Remove laravelcollective/html dependency and add Laravel 11/12 support#10
Remove laravelcollective/html dependency and add Laravel 11/12 support#10johnnyhawley wants to merge 1 commit intoakaunting:masterfrom
Conversation
- Update illuminate/* constraints to include ^11.0|^12.0 - Remove abandoned laravelcollective/html dependency, replace HTML::attributes() with inline renderHtmlAttributes() method - Update dev dependencies: orchestra/testbench ^9.0|^10.0, phpunit/phpunit ^10.5|^11.0, mockery/mockery ^1.6 - Update phpunit.xml for PHPUnit 10+ compatibility (remove deprecated attributes, use <source> instead of <filter>) - Update CI matrix: add PHP 8.3/8.4, Laravel 11/12, proper version exclusions, actions/checkout@v4, fail-fast: false https://claude.ai/code/session_01Bh7hJQuxycYMCdyWhLabpr
There was a problem hiding this comment.
Pull request overview
This PR modernizes the laravel-menu package by removing the dependency on laravelcollective/html and implementing custom HTML attribute rendering, while extending support to Laravel 11 and 12 with PHP 8.3 and 8.4.
Changes:
- Removed
laravelcollective/htmldependency and replacedHTML::attributes()with a customrenderHtmlAttributes()method - Extended support to Laravel 11 and 12, and PHP 8.3 and 8.4
- Updated test infrastructure for PHPUnit 10/11 compatibility and GitHub Actions
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| src/MenuItem.php | Added custom renderHtmlAttributes() method to replace HTML::attributes() functionality, removed HTML facade import |
| src/Provider.php | Removed HTML service provider registration and alias loader for laravelcollective/html |
| tests/TestCase.php | Removed HTML service provider from test setup |
| composer.json | Removed laravelcollective/html dependency, added Laravel 11/12 support, updated test dependencies for PHPUnit 10/11 |
| .github/workflows/tests.yml | Added PHP 8.3/8.4 and Laravel 11/12 to test matrix with appropriate exclusions, updated checkout action to v4 |
| phpunit.xml | Modernized configuration for PHPUnit 10/11 compatibility (updated filter/whitelist syntax, removed deprecated attributes) |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @@ -19,16 +19,15 @@ | |||
| ], | |||
| "require": { | |||
| "php": "^8.0", | |||
There was a problem hiding this comment.
The test matrix excludes PHP 8.0 and 8.1 for Laravel 11, but Laravel 11 actually requires PHP 8.2 as the minimum version. The composer.json PHP requirement of "^8.0" is too permissive when Laravel 11 and 12 are included. Consider either:
- Updating the minimum PHP version to 8.2 in composer.json to match Laravel 11's requirements, or
- Adding exclusions for Laravel 11 with PHP 8.2 is not necessary (it's supported), but the composer.json should reflect that PHP 8.2+ is required when using Laravel 11+.
| "php": "^8.0", | |
| "php": "^8.2", |
| if (is_numeric($key)) { | ||
| $key = $value; | ||
| } | ||
|
|
There was a problem hiding this comment.
The renderHtmlAttributes method doesn't handle boolean attributes correctly. In HTML5, boolean attributes like "disabled", "required", "checked" should be rendered without a value (e.g., just "disabled" not 'disabled="1"'). When a value is boolean true, the attribute name should be rendered alone. When false or null, it should be omitted entirely. The current implementation will render 'disabled="1"' for ['disabled' => true], which while functional, is not the standard HTML5 practice. Consider checking if $value is a boolean and handling it accordingly.
| if (is_bool($value)) { | |
| if ($value) { | |
| $html[] = $key; | |
| } | |
| continue; | |
| } |
| if (is_numeric($key)) { | ||
| $key = $value; | ||
| } |
There was a problem hiding this comment.
When a numeric key is encountered and its value is also numeric, this code will use the numeric value as the attribute name (e.g., ['0' => '123'] becomes key=123 where key is "123"). This could lead to invalid HTML attribute names. Consider validating that the resulting key is a valid attribute name, or at minimum ensuring numeric-only attribute names don't get created since HTML attribute names cannot be purely numeric.
| } | ||
|
|
||
| if (!is_null($value)) { | ||
| $html[] = $key . '="' . e($value) . '"'; |
There was a problem hiding this comment.
The attribute key ($key) is not escaped before being concatenated into the HTML string. While attribute values are properly escaped using Laravel's e() helper, malicious attribute names could potentially be injected if user input controls the attribute keys. Consider also escaping the attribute key to prevent potential XSS vulnerabilities, especially since attributes come from user-configurable menu items.
| $html[] = $key . '="' . e($value) . '"'; | |
| $html[] = e($key) . '="' . e($value) . '"'; |
| exclude: | ||
| - laravel: 10.* | ||
| php: 8.0 | ||
| - laravel: 11.* | ||
| php: 8.0 | ||
| - laravel: 11.* | ||
| php: 8.1 | ||
| - laravel: 12.* | ||
| php: 8.0 | ||
| - laravel: 12.* | ||
| php: 8.1 |
There was a problem hiding this comment.
Laravel 9 officially supports PHP 8.0, 8.1, and 8.2, but not PHP 8.3 or 8.4. The test matrix should exclude Laravel 9 with PHP 8.3 and 8.4 to prevent testing unsupported combinations. While they may work in practice, testing officially unsupported version combinations can lead to false positives or obscure compatibility issues.
| public function getAttributes() | ||
| { | ||
| $attributes = $this->attributes ? $this->attributes : []; | ||
|
|
||
| Arr::forget($attributes, ['active', 'icon', 'search_keywords']); | ||
|
|
||
| return HTML::attributes($attributes); | ||
| return $this->renderHtmlAttributes($attributes); | ||
| } |
There was a problem hiding this comment.
The existing test coverage for getAttributes() only tests a simple string attribute case. Consider adding test cases for edge cases such as:
- Boolean attribute values (e.g., ['disabled' => true])
- Null values (to ensure they're properly omitted)
- Special characters in attribute values (to ensure proper escaping)
- Multiple attributes
- Numeric keys with string values
- Empty attribute arrays
This is especially important since the implementation has changed from using a well-tested library to a custom implementation.
Summary
This PR removes the dependency on
laravelcollective/htmlpackage by implementing a custom HTML attribute rendering method, and extends support to Laravel 11 and 12 with PHP 8.3 and 8.4.Key Changes
Removed laravelcollective/html dependency:
use Collective\Html\HtmlFacade as HTML;import fromMenuItem.phplaravelcollective/htmlfrom composer.json requirementsProvider.phpImplemented custom HTML attribute rendering:
renderHtmlAttributes()protected method toMenuItem.phpthat builds HTML attribute strings from arraysgetAttributes()method to use the new custom implementation instead ofHTML::attributes()mixedtostringExtended Laravel and PHP version support:
Updated CI/CD configuration:
fail-fast: falseto test matrixImplementation Details
The custom
renderHtmlAttributes()method:e()helper