Laravel 9.29 Released

Laravel 9.29 Released

Laravel 9.29 released with RequiredIfAccepted validation rule, generating Vite assetPath() method, Eloquent Model changes discard ability, Mail attachments existence ability (with direct, from storage disk having data attached), add assertions around cancelled batched jobs, and more including the fixes. Let’s check these updates in detail here:

1. RequiredIfAccepted validation rule:

Pascal Baljet contributed by adding a required_if_accepted validation rule. This validation rule depends upon another field. So, this validations works if the dependent filed is accepted as “yes”, “on”, 1, or true.

Validator::make([
    'is_company'   => 'on',
    'company_name' => 'Apple',
], [
    'is_company'   => 'required|boolean',
    'company_name' => 'required_if_accepted:is_company',
]);

Source File Edits: src/Illuminate/Validation/Concerns/ValidatesAttributes.php

/**
 * Validate that an attribute exists when another attribute was "accepted".
 *
 * @param  string  $attribute
 * @param  mixed  $value
 * @param  mixed  $parameters
 * @return bool
 */
public function validateRequiredIfAccepted($attribute, $value, $parameters)
{
    $this->requireParameterCount(1, $parameters, 'required_if_accepted');

    if ( $this->validateAccepted($parameters[0], $this->getValue($parameters[0]))) {
        return $this->validateRequired($attribute, $value);            
    }

    return true;
}

2. Generating Vite assetPath() method:

Wilsen Hernández contributed adding a method to the Vite class to generate the asset URLs separated from the main class. The assetPath() method has the same signature as the global asset() helper.

Vite::assetPath('resources/images/logo.jpeg');

Source File Edits: src/Illuminate/Foundation/Vite.php

/**
 * Generate an asset path for the application.
 *
 * @param  string  $path
 * @param  bool|null  $secure
 * @return string
 */
protected function assetPath($path, $secure = null)
{
    return asset($path, $secure);
}

3. Eloquent Model changes discard ability:

Mior Muhammad Zaki contributed by adding a discardChanges() method to the Eloquent that provides the ability that can determine if any of the attribute(s) were changed when the model was last saved and discard those changes if required as per the condition.

Project::updating(function (Project $model) {
    /*
     * The project update should be a change request
     */
    $changeRequest = new ProjectChangeRequest([
        'original' => array_intersect_key($model->getRawOriginal(), $model->getDirty()), // compare the change between original records and proposed records.
        'changes' => $model->getDirty(), // get the modified proposed changes.
    ]);

    $changeRequest->source_model()->associate($model); // assign the changes to the Eloquent to save
    $changeRequest->save(); // saving the modified data.

    // Now we can simply ignore all attribute changes and only save `status="change_request"`
    $model->discardChanges();

    $model->status = 'change_request';
    $model->save();
});

Source File Edits: src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php

/**
 * Discard attribute(s) changes.
 *
 * @return $this
 */
public function discardChanges()
{
    $this->attributes = $this->original;
    $this->changes = [];

    return $this;
}

4. Mail attachments existence ability:

Andrew Minion contributed by adding the hasAttachment(), hasAttachmentFromStorageDisk(), and hasAttachedData() methods that give the ability to indicate the attachment(s) are included in the mailable while there is a direct attachment posted, attachment from storage disk, or have attached data. It works similar to the $mail->hasTo(), $mail->hasSubject(), etc. mailable methods. Let’s check them in detail here:

  • $mail->hasAttachment()
Mail::assertSent(OrderShipped::class, function ($mail) {
    return $mail->hasAttachment('/path/to/file');
});
 
Mail::assertSent(OrderShipped::class, function ($mail) {
    return $mail->hasAttachment('/path/to/file', [
        'as' => 'name.pdf',
        'mime' => 'application/pdf',
    ]);
});
  • $mail->hasAttachmentFromStorageDisk()
Mail::assertSent(OrderShipped::class, function ($mail) {
    return $mail->hasAttachmentFromStorageDisk('s3', '/path/to/file');
});
  • $mail->hasAttachedData()
Mail::assertSent(OrderShipped::class, function ($mail) use ($pdfData) {
    return $mail->hasAttachedData($pdfData, 'name.pdf', [
        'mime' => 'application/pdf'
    ]);
});

Source File Edits: src/Illuminate/Mail/Mailable.php

/**
 * Determine if the mailable has the given attachment.
 *
 * @param  string|\Illuminate\Contracts\Mail\Attachable|\Illuminate\Mail\Attachment  $file
 * @param  array $options
 * @return bool
 */
public function hasAttachment($file, ?array $options = null)
{
    return collect($this->attachments)->filter(function ($attachment) use ($file, $options) {
        if (is_null($options)) {
            $optionsMatch = true;
        } else {
            $optionsMatch = $attachment['options'] === $options;
        }

        return $attachment['file'] === $file
            && $optionsMatch;
    })->isNotEmpty();
}


/**
 * Determine if the mailable has the given attachment from a specific storage disk.
 *
 * @param  string  $disk
 * @param  string  $path
 * @param  string|null  $name
 * @param  array  $options
 * @return bool
 */
public function hasAttachmentFromStorageDisk($disk, $path, $name = null, array $options = [])
{
    return collect($this->diskAttachments)->contains(
        fn ($attachment) => $attachment['disk'] === $disk
            && $attachment['path'] === $path
            && $attachment['name'] === ($name ?? basename($path))
            && $attachment['options'] === $options
    );
}


/**
 * Determine if the mailable has the given data as an attachment.
 *
 * @param  string  $data
 * @param  string  $name
 * @param  array  $options
 * @return bool
 */
public function hasAttachedData($data, $name, array $options = [])
{
    return collect($this->rawAttachments)->contains(
        fn ($attachment) => $attachment['data'] === $data
            && $attachment['name'] === $name
            && array_filter($attachment['options']) === array_filter($options)
    );
}

Now the list of the Laravel 9.28 Released updates:

Added

  • Added RequiredIfAccepted validation rule (#44035)
  • Added Illuminate/Foundation/Vite::assetPath() (#44037)
  • Added ability to discard Eloquent Model changes (#43772)
  • Added ability to determine if attachments exist to Illuminate/Mail/Mailable (#43967)
  • Added Illuminate/Support/Testing/Fakes/BusFake::assertNothingBatched() (#44056)

Reverted

Fixed

  • Avoid Passing null to parameter exception on PHP 8.1 (#43951)
  • Align Remember Me Cookie Duration with CookieJar expiration (#44026)
  • Fix Stringable typehints with Enumerable (#44030)
  • Fixed middleware “SetCacheHeaders” with file responses (#44063)

Changed

  • Don’t use locks for queue job popping for PlanetScale’s MySQL-compatible Vitess engine (#44027)
  • Avoid matching ‘use’ in custom Stub templates in Illuminate/Console/GeneratorCommand.php (#44049)

To get to know more about Laravel, you can check these articles too.

You can check the latest release tech articles like Laravel 9.29 Released here.

Please follow and like us:

Related Posts

Leave a Reply

Share