Update charcoal to support PHP 8.3 - 8.5#96
Conversation
Introduced a utility script to streamline monorepo package management. Supports listing packages in default, JSON, or pretty formats.
… package handling
…proved localization Replaced the deprecated `strftime` with `IntlDateFormatter` for date formatting. Introduced locale support to the `DateHelper` class for better internationalization.
…s` and removing redundant parsing
…monorepo-builder` configuration
…ma and cleanup deprecated settings
…ed cache and log files
…or for modern PHP syntax (rector utility) Applied strict typing declarations across packages. Updated composer dependencies to require PHP 8.3 and PHPUnit ^12.5. Refactored codebase with type hints, `static` return type, and improved null checks.
Introduced `$tableExistsCache` for caching table existence checks. Replaced `property_exists` logic with an internal cache and added `#[\AllowDynamicProperties]` for PHP 8.2 compatibility.
…, PHPUnit, and other libraries
…^7.2, Slim ^3.13, Stash ^1.1, and PSR/Cache ^2.0
… add type hints, and refactor for modern PHP syntax - Eliminated `MessageSelector` as it is no longer required with `MessageFormatter`. - Added type hints and return types across various components, improving strict typing consistency. - Simplified logic and migrated to modern PHP syntax for better code maintainability.
…ethods, and modernize for strict typing compliance
…ecated docblocks to modern syntax
…ts, and fix syntax issues for immutability compliance
…nce across CollectionContainerTrait and TableWidget
…ePassByReference`
…pdating parentheses usage, and adding return type hints where applicable
…ernize schema versions
…in GitHub Actions
… for package testing
…clean up unused GitHub Actions step
…nit configurations across all packages
…ions with explicit loops for better compatibility
…clean up #[Override] attributes from class properties
… and update associated configuration
…property namespace
mcaskill
left a comment
There was a problem hiding this comment.
This is a preliminary review wherein I've looked at top-level files, Composer manifests, and PHPUnit configuration files.
I'll submit further reviews as I dive into the packages.
There was a problem hiding this comment.
Add a .gitattributes file and exclude .ddev with export-ignore.
| @@ -1,4 +1,6 @@ | |||
| .phpunit.result.cache | |||
There was a problem hiding this comment.
With .phpunit.cache, I think we can remove .phpunit.result.cache.
| @@ -1,4 +1,6 @@ | |||
| .phpunit.result.cache | |||
| phpunit.xml.dist.bak | |||
There was a problem hiding this comment.
I recommend removing this rule. .bak is a generic extension used by various tools. It should be ignored globally rather than ignored at this specific level and file name.
| # Function to list all monorepo packages in pretty format | ||
| packages_pretty() { | ||
| echo "Monorepo packages:" | ||
| find packages -maxdepth 2 -name "composer.json" -type f | while read -r composer_file; do | ||
| package_dir=$(dirname "$composer_file") | ||
| package_name=$(basename "$package_dir") | ||
| echo " - $package_name" | ||
| done | ||
| } | ||
|
|
||
| # Function to list packages as JSON array | ||
| packages_json() { | ||
| packages=$(find packages -maxdepth 2 -name "composer.json" -type f | while read -r composer_file; do | ||
| package_dir=$(dirname "$composer_file") | ||
| basename "$package_dir" | ||
| done | awk 'BEGIN{printf "["} {printf "%s\"%s\"", (NR>1?",":""), $0} END{printf "]\n"}') | ||
| echo "$packages" | ||
| } | ||
|
|
||
| # Function to list package names only (space-separated) - default | ||
| packages_default() { | ||
| find packages -maxdepth 2 -name "composer.json" -type f | while read -r composer_file; do | ||
| package_dir=$(dirname "$composer_file") | ||
| basename "$package_dir" | ||
| done | tr '\n' ' ' | sed 's/ $/\n/' | ||
| } |
There was a problem hiding this comment.
I would recommend having one function execute the find and extract package names.
I think this command I wrote to be more versatile (the list is also sorted for convenience):
find ./packages -type f -name 'composer.json' \
-maxdepth 2 -exec dirname {} + \
| sort -u \
| xargs basenameFrom that, JSON output becomes:
packages_json() {
packages=$(find_packages | awk 'BEGIN{printf "["} {printf "%s\"%s\"", (NR>1?",":""), $0} END{printf "]\n"}')
echo "$packages"
}Also, I don't think you need to store the result in a variable to echo afterwards?
| echo "Usage: $0 packages [--type=TYPE|-t TYPE]" | ||
| echo "Commands:" | ||
| echo " packages List package names (space-separated, default)" | ||
| echo " packages -t json List packages as JSON array" | ||
| echo " packages -t pretty List all monorepo packages in pretty format" |
There was a problem hiding this comment.
--type (-t) feels like an odd choice for this kind of option. I would recommend --format (-f).
Examples using f:
There was a problem hiding this comment.
According to Rector, couldn't one skip AddOverrideAttributeToOverriddenPropertiesRector?
RectorConfig::configure()
->withSkip([
AddOverrideAttributeToOverriddenPropertiesRector::class,
]);| "charcoal/ui": "^5.1", | ||
| "charcoal/user": "^5.1", | ||
| "guzzlehttp/guzzle": "^6.0 || ^7.0", | ||
| "kriswallsmith/assetic": "^1.4", |
There was a problem hiding this comment.
kriswallsmith/assetic will need to be replaced with assetic/framework.
| "require": { | ||
| "php": "^7.4 || ^8.0", | ||
| "php": "^8.3", | ||
| "ext-json": "*", | ||
| "psr/http-message": "^1.0", | ||
| "charcoal/config": "^5.1", | ||
| "erusev/parsedown": "^1.7" |
There was a problem hiding this comment.
erusev/parsedown should be upgraded to v1.8.0 to resolve PHP 8 deprecations.
mcaskill
left a comment
There was a problem hiding this comment.
This review covers UI, User, and View packages.
There was a problem hiding this comment.
Would it be complicated to import class names instead of using fully qualified names?
The only issue I can think of is it would impact (for humans) the manually curated grouping of imports (which are per package).
| */ | ||
| public function __invoke(string $text, LambdaHelper $helper = null): string | ||
| public function __invoke(string $text = '', ?LambdaHelper $helper = null): mixed |
There was a problem hiding this comment.
Replace mixed with static|string.
| */ | ||
| public function __get(string $macro) | ||
| public function __get(string $macro): mixed |
There was a problem hiding this comment.
Replace mixed with static.
| // Mustache v3 calls callable objects with no arguments when traversing dotted | ||
| // names (e.g. `_t.en`). Return $this so the traversal can continue to __get(). |
There was a problem hiding this comment.
Use block comment for PHPDoc parsers to intercept this comment.
| // Mustache v3 calls callable objects with no arguments when traversing dotted | |
| // names (e.g. `_t.en`). Return $this so the traversal can continue to __get(). | |
| /** | |
| * Mustache v3 calls callable objects with no arguments when traversing dotted | |
| * names (e.g. `_t.en`). Return $this so the traversal can continue to __get(). | |
| */ |
| @@ -14,21 +14,23 @@ | |||
| class DebugHelpers extends AbstractExtension implements | |||
| HelpersInterface | |||
| { | |||
| public $debug; | |||
There was a problem hiding this comment.
The property needs a type, either:
public ?bool $debug = null;
public bool $debug = false;
public mixed $debug = false;
If bool, the null coalescing operator should be removed from the isDebug() method.
If mixed, the property should be cast to bool in isDebug().
| @@ -339,13 +339,9 @@ protected function parseFormGroup($groupIdent, $group) | |||
| * @param array|null $data Optional. The form group data to set. | |||
| * @return FormGroupInterface | |||
| */ | |||
| protected function createFormGroup(array $data = null) | |||
| protected function createFormGroup(?array $data = null) | |||
There was a problem hiding this comment.
Add return type:
| protected function createFormGroup(?array $data = null) | |
| protected function createFormGroup(?array $data = null): FormGroupInterface |
There was a problem hiding this comment.
Missing property types which influence other methods throughout the trait.
private int $position = 0;
private array $structure = [];There was a problem hiding this comment.
Some methods are returning float|int|null where they should be ?int.
Example of a refactored method to enforce int.
public function rowNumColumns(?int $position = null): ?int
{
$position ??= $this->position();
$row = $this->rowData($position);
if ($row === null) {
return null;
}
return (int) array_sum($row['columns']);
}| @@ -260,7 +253,7 @@ public function cellSpan($position = null) | |||
| * @param integer $position Optional. Forced position. | |||
| * @return integer | |||
| */ | |||
| public function cellSpanBy12($position = null) | |||
| public function cellSpanBy12($position = null): null|float|int | |||
There was a problem hiding this comment.
This method should round and clamp its result.
|
|
||
| /** | ||
| * Return a new menu. | ||
| * | ||
| * @param array|\ArrayAccess $data Class dependencies. | ||
| */ | ||
| public function __construct($data) | ||
| public function __construct(?array $data) |
There was a problem hiding this comment.
Is there a way for this method to not support null?
Same concern applies to similar classes that such as AbstractMenuItem.
mcaskill
left a comment
There was a problem hiding this comment.
This review covers Translator package.
| @@ -215,11 +189,11 @@ private function getLanguage(RequestInterface $request) | |||
| * @param RequestInterface $request The PSR-7 HTTP request. | |||
| * @return string | |||
| */ | |||
| private function getLanguageFromHost(RequestInterface $request) | |||
| private function getLanguageFromHost(RequestInterface $request): int|string | |||
There was a problem hiding this comment.
Return type should be string.
return $lang; should maybe be return (string) $lang;.
Maybe also add an annotation to the $hostMap property:
/** @var array<string, string> */
private array $hostMap;There was a problem hiding this comment.
Missing parameter type on $domain throughout a few methods.
There was a problem hiding this comment.
The trait's $translator property should be:
private ?Translator $translator = null;I think we can also remove the exception thrown in translator() in favour of delegating error handling to PHP which will expect the return type.
| */ | ||
| private $container; | ||
| private \Pimple\Container|array|null $container = null; |
There was a problem hiding this comment.
This property is only ever ?Container, I see no occurrence of it as an array.
mcaskill
left a comment
There was a problem hiding this comment.
This review covers Property package.
In regards to all packages: The Override attribute should not applied to methods that call their parent such as dataUpload(), fileUpload(), setDependencies().
There was a problem hiding this comment.
valshould bemixedand default tonull.label,description, andnotesshould be?Translationand default tonull.multipleOptionsandviewOptionsshould be?arrayand default tonull.displayTypeshould be?stringand default tonull.
| */ | ||
| public function __toString() | ||
| #[\Deprecated] | ||
| public function __toString(): string |
There was a problem hiding this comment.
Might as well simplify this method with early returns instead of using else:
public function __toString(): string
{
$val = $this->val();
if (is_string($val)) {
return $val;
}
if (is_object($val)) {
return (string)$val;
}
return '';
}| */ | ||
| public function inputVal($val, array $options = []) | ||
| public function inputVal($val, array $options = []): string |
There was a problem hiding this comment.
Like parseVal and parseOne, inputVal and displayVal should also type $val as mixed.
| * @return Translation | ||
| */ | ||
| public function getLabel() | ||
| public function getLabel(): mixed |
There was a problem hiding this comment.
Should be Translation|string
| */ | ||
| public function setMultiple($multiple) | ||
| public function setMultiple(bool $multiple): static |
There was a problem hiding this comment.
If the parameter is to be bool, the method should be simplified.
| @@ -287,26 +269,24 @@ public function defaultVal() | |||
| * @param boolean $allowNull The field allow null flag. | |||
| * @return PropertyField Chainable | |||
| */ | |||
| public function setAllowNull($allowNull) | |||
| public function setAllowNull($allowNull): static | |||
There was a problem hiding this comment.
Parameter should be typed bool instead of casting.
| * @var boolean | ||
| */ | ||
| private $allowNull; | ||
| private ?bool $allowNull = null; |
There was a problem hiding this comment.
Should be bool and default to true.
| */ | ||
| public function setIdent($ident) | ||
| public function setIdent($ident): static |
There was a problem hiding this comment.
Parameter should be typed string and the is_string() guard should be removed.
| */ | ||
| private $sprite; | ||
| private ?string $sprite = null; | ||
|
|
||
| /** | ||
| * @var ViewInterface | ||
| */ | ||
| private $view; |
There was a problem hiding this comment.
Should be typed ?ViewInterface and default to null.
| */ | ||
| public function setAllowHtml($allowHtml) | ||
| public function setAllowHtml($allowHtml): static |
There was a problem hiding this comment.
Parameter should be typed bool instead of casting.
mcaskill
left a comment
There was a problem hiding this comment.
This review covers Object package.
| int|float &$count, | ||
| int|float $level, |
There was a problem hiding this comment.
Parameters should be typed int. A float would be very problematic.
| @@ -293,7 +287,7 @@ private function sortDescendantObjects( | |||
| * @throws InvalidArgumentException If the parameter is not numeric or < 0. | |||
| * @return Pagination (Chainable) | |||
| */ | |||
| public function setPage($page) | |||
| public function setPage($page): static | |||
There was a problem hiding this comment.
Parameter should be typed int and is_numeric() guard below should be removed.
- if (!is_numeric($page)) {
- throw new InvalidArgumentException(
- 'Page number needs to be numeric.'
- );
- }
-
- $page = (int)$page;
if ($page < 0) {
throw new InvalidArgumentException(
- 'Page number needs to be greater than or equal 0.'
+ 'Page number must be at least 0'
);
}
$this->page = $page;| @@ -326,7 +320,7 @@ public function getPage() | |||
| * @throws InvalidArgumentException If the parameter is not numeric or < 0. | |||
| * @return Pagination (Chainable) | |||
| */ | |||
| public function setNumPerPage($num) | |||
| public function setNumPerPage($num): static | |||
There was a problem hiding this comment.
Parameter should be typed int and is_numeric() guard below should be removed.
- if (!is_numeric($num)) {
- throw new InvalidArgumentException(
- 'Num-per-page needs to be numeric.'
- );
- }
-
- $num = (int)$num;
if ($num < 0) {
throw new InvalidArgumentException(
- 'Num-per-page needs to be >= 0.'
+ 'Num-per-page must be at least 0'
);
}
$this->numPerPage = $num;There was a problem hiding this comment.
$mastershould be typedint|string|null.$hierarchy,$children, and$siblingsshould be typed?array.$masterObjectshould be typed?HierarchicalInterface.$objectCacheshould be typedarrayand annotation should be@var array<class-string, array<int|string, ModelInterface>.
There was a problem hiding this comment.
Methods hierarchy(), children(), and siblings() can be simplified using null coalescing assignment operator. For example:
return $this->hierarchy ??= $this->loadHierarchy();And their return types should be array.
There was a problem hiding this comment.
Methods objFromIdent(), loadObjectFromCache(), and loadObjectFromSource() should return either:
(HierarchicalInterface&ModelInterface)|null?HierarchicalInterface?ModelInterface
| @@ -694,9 +676,7 @@ public function createRouteObject() | |||
| */ | |||
| public function getRouteObjectPrototype() | |||
There was a problem hiding this comment.
Method getRouteObjectPrototype() should have return type ObjectRouteInterface.
| @@ -799,7 +779,7 @@ public function routeOptionsIdent() | |||
| public function isActiveRoute() | |||
There was a problem hiding this comment.
Method isActiveRoute() should have return type bool.
There was a problem hiding this comment.
- Class property
$ipshould be typedint|string|nullandsetIp()simplified to delegate IP address parsing toIpProperty. - Class properties
$langand$originshould be typed?stringand default tonull.
Equivalent accessor and mutator methods should be updated correspondingly.
| */ | ||
| public function setLang($lang) | ||
| public function setLang($lang): static |
There was a problem hiding this comment.
Method parameter $lang should be typed ?string and guards below removed.
| */ | ||
| public function setOrigin($origin) | ||
| public function setOrigin($origin): static |
There was a problem hiding this comment.
Method parameter $origin should be typed ?string and guards below removed.
mcaskill
left a comment
There was a problem hiding this comment.
This review covers Image package.
I don't think the build directory shout not be indexed in the Image package based on the last release.
There was a problem hiding this comment.
Class property $channel should be typed string.
Equivalent accessor and mutator methods should be updated accordingly including removing any pre-PHP 7.4 guards.
There was a problem hiding this comment.
Class property $gravity should be typed string.
Equivalent accessor and mutator methods should be updated accordingly including removing any pre-PHP 7.4 guards and casts.
Method parameters of doCrop() should be typed int and have return type void.
There was a problem hiding this comment.
With class property $quality typed, equivalent accessor and mutator methods should be updated accordingly including removing any pre-PHP 7.4 guards and casts.
There was a problem hiding this comment.
With class properties $colors and $mode typed, equivalent accessor and mutator methods should be updated accordingly including removing any pre-PHP 7.4 guards and casts.
There was a problem hiding this comment.
This // Quantize comment should be indented to match array items.
There was a problem hiding this comment.
Class properties $*Cmd for Imagemagick binaries should be typed ?string and default to null.
Equivalent accessor methods should be simplified. For example:
public function mogrifyCmd()
{
return $this->mogrifyCmd ??= $this->findCmd('mogrify');
}Equivalent accessor and mutator methods should be updated accordingly including removing any pre-PHP 7.4 guards and casts.
| @@ -383,7 +365,7 @@ public function resetTmp() | |||
| * @throws Exception If the command fails. | |||
| * @return string | |||
| */ | |||
| public function exec($cmd) | |||
| public function exec(string $cmd): string|false|null | |||
There was a problem hiding this comment.
Given the return within the proc_open condition, the else that executes shell_exec is unnecessary.
There was a problem hiding this comment.
- Class properties
$sourceand$targetshould be typed?stringand default tonull. - Class property
$effectsshould be typedarray.
Equivalent accessor and mutator methods should be updated accordingly including removing any pre-PHP 7.4 guards and casts.
| @@ -61,7 +58,7 @@ public function __call($fxType, array $data) | |||
| */ | |||
| protected function effectFactory() | |||
There was a problem hiding this comment.
Method effectFactory() should be simplified:
protected function effectFactory(): EffectFactory
{
return $this->effectFactory ??= new EffectFactory();
}There was a problem hiding this comment.
Mutator methods should have return type static.
Methods' parameters and return should be typed.
mcaskill
left a comment
There was a problem hiding this comment.
This review covers Factory package.
There was a problem hiding this comment.
- Class property
$resolvedshould be typedarrayand be annotatedarray<class-string<static>, array<string, class-string>>. - Class properties
$baseClassand$defaultClassshould be typedstringand be annotatedclass-string. - Class property
$callbackshould be typed?callableand default tonull. - Class property
$resolvershould be typedcallable. - Class property
$instancesshould be annotatedarray<string, object>. - Class property
$mapshould be annotatedarray<string, class-string>.
| @@ -89,7 +85,7 @@ public function __construct(array $data = null) | |||
| } | |||
|
|
|||
| if (!isset($data['resolver'])) { | |||
| $opts = isset($data['resolver_options']) ? $data['resolver_options'] : null; | |||
| $opts = ($data['resolver_options'] ?? null); | |||
There was a problem hiding this comment.
This should be simplified:
- if (!isset($data['resolver'])) {
- $opts = ($data['resolver_options'] ?? null);
- $data['resolver'] = new GenericResolver($opts);
- }
-
- $this->setResolver($data['resolver']);
+ $this->setResolver($data['resolver'] ?? new GenericResolver($data['resolver_options'] ?? null));| @@ -118,13 +114,13 @@ public function __construct(array $data = null) | |||
| * @throws InvalidArgumentException If type argument is not a string or is not an available type. | |||
| * @return mixed The instance / object | |||
| */ | |||
| final public function create($type, array $args = null, callable $cb = null) | |||
| final public function create($type, ?array $args = null, ?callable $cb = null) | |||
There was a problem hiding this comment.
Fallback for $args should be simplified to:
- if (!isset($args)) {
- $args = $this->arguments();
- }
+ $args ??= $this->arguments();There was a problem hiding this comment.
Methods with parameter $type should be typed string and is_string() guards removed.
mcaskill
left a comment
There was a problem hiding this comment.
This review covers Email package.
| /** | ||
| * @param string $linkId Link ID. | ||
| * @param Tracker $tracker Tracker service. | ||
| * @param FactoryInterface $modelFactory Model factory, to create Link objects. | ||
| */ | ||
| public function __construct(string $linkId, Tracker $tracker, FactoryInterface $modelFactory) | ||
| public function __construct(private readonly string $linkId, private readonly Tracker $tracker, private readonly FactoryInterface $modelFactory) |
There was a problem hiding this comment.
For readability, promoted parameters should be spread over multiple lines.
| public function __construct(private readonly string $linkId, private readonly Tracker $tracker, private readonly FactoryInterface $modelFactory) | |
| public function __construct( | |
| private readonly string $linkId, | |
| private readonly Tracker $tracker, | |
| private readonly FactoryInterface $modelFactory | |
| ) |
| /** | ||
| * @param string $emailId Email log ID. | ||
| * @param Tracker $tracker Tracker service. | ||
| */ | ||
| public function __construct(string $emailId, Tracker $tracker) | ||
| public function __construct(private readonly string $emailId, private readonly Tracker $tracker) |
There was a problem hiding this comment.
For readability, promoted parameters should be spread over multiple lines.
| public function __construct(private readonly string $emailId, private readonly Tracker $tracker) | |
| public function __construct( | |
| private readonly string $emailId, | |
| private readonly Tracker $tracker | |
| ) |
There was a problem hiding this comment.
- Class property
$queueIdshould be typedint|string|nulland default tonull. - Class properties
$errorCodeand$campaignshould be typed?stringand default tonull.
There was a problem hiding this comment.
Class properties $email and $url should be typed ?string and default to null.
| /** | ||
| * @param string $baseUrl Base URL. | ||
| * @param FactoryInterface $modelFactory Model factory to create link and log objects. | ||
| */ | ||
| public function __construct(string $baseUrl, FactoryInterface $modelFactory) | ||
| public function __construct(private readonly string $baseUrl, private readonly FactoryInterface $modelFactory) |
There was a problem hiding this comment.
For readability, promoted parameters should be spread over multiple lines.
| public function __construct(private readonly string $baseUrl, private readonly FactoryInterface $modelFactory) | |
| public function __construct( | |
| private readonly string $baseUrl, | |
| private readonly FactoryInterface $modelFactory | |
| ) |
There was a problem hiding this comment.
- Class property
$replyToshould be typed?stringand default tonull. - Class property
$attachmentsshould be typedarray. - Class properties
$logEnabled,$trackOpenEnabledand$trackLinksEnabledshould be typed?booland default tonull. Mutator methods should accept?booland not cast toboolto allow one to reset the value to the config's defaults in their equivalent accessors.
There was a problem hiding this comment.
Class property $parser should be typed ?Parser and default to null.
| */ | ||
| private $smtpSecurity = ''; | ||
| private string $smtpSecurity = ''; |
There was a problem hiding this comment.
Class property $smtpSecurity appears to be unused across Charcoal. I would recommend changing its type to ?string and default to null.
Its mutator (and accessor) method should be changed to support null:
public function setSmtpSecurity(?string $security): static
{
if (is_string($security)) {
$security = strtoupper($security);
$validSecurity = [ 'TLS', 'SSL' ];
if (!in_array($security, $validSecurity)) {
throw new InvalidArgumentException(
'SMTP Security is not valid. Must be null, "TLS", or "SSL".'
);
}
}
$this->smtpSecurity = $security;
return $this;
}There was a problem hiding this comment.
Class properties $subject, $msgHtml, $msgTxt, and $campaign should be typed ?string and default to null.
mcaskill
left a comment
There was a problem hiding this comment.
This review covers Core package.
There was a problem hiding this comment.
- Class property
$sourceshould be typed?SourceInterfaceand default tonull. - Class property
$modelshould be typed?ModelInterfaceand default tonull. - Class property
$factoryshould be typed?FactoryInterfaceand default tonull. - Class property
$callbackshould be typed?callableand default tonull. - Class property
$dynamicTypeFieldshould be typed?stringand default tonull. - Class property
$collectionClassshould be typed?string, annotated as'array'|class-string|null, and default tonull.
There was a problem hiding this comment.
Methods that return \ArrayAccess|array (or array|\ArrayAccess) should \ArrayAccess|iterable because the collection could be a class (same applies to LazyCollectionLoader).
I would personally suggest remove ArrayAccess as a choice.
| @@ -773,7 +744,7 @@ protected function processCollection($results, callable $before = null, callable | |||
| * @param callable|null $after Process each entity after applying raw data. | |||
| * @return ModelInterface|ArrayAccess|null | |||
| */ | |||
| protected function processModel($objData, callable $before = null, callable $after = null) | |||
| protected function processModel(array $objData, ?callable $before = null, ?callable $after = null) | |||
There was a problem hiding this comment.
This method should be typed ModelInterface.
There's no scenario where ArrayAccess or null would be returned.
There was a problem hiding this comment.
Class property $collectionLoader should be typed ?CollectionLoader and default to null.
The isset() guard in collectionLoader() method should be removed.
There was a problem hiding this comment.
Class property $collectionLoaderFactory should be typed ?FactoryInterface and default to null.
Method collectionLoaderFactory() should return FactoryInterface and the isset() guard removed.
There was a problem hiding this comment.
- Method parameter of
setCondition()should be typed?string. - Method return of
hasCondition()should be typedbool. - Method return of
condition()should be typed?string.
| */ | ||
| public function defaults() | ||
| #[\Override] | ||
| public function defaults(): array | ||
| { | ||
| return [ | ||
| 'type' => '' |
There was a problem hiding this comment.
Default value of type should be null instead of empty string.
| */ | ||
| public function setType($type) | ||
| public function setType($type): static |
There was a problem hiding this comment.
Method parameter should be typed and guard removed.
There was a problem hiding this comment.
setKey()parameter andkey()return should be typedstring.source()return should beSourceInterface.save(),update(), anddelete()return should bebool.
There was a problem hiding this comment.
- Class property
$idshould default tonull. - Class property
$keyshould be typedstring. - Class property
$sourceFactoryshould be typed?FactoryInterfaceand default tonull. - Class property
$sourceshould be typed?SourceInterfaceand default tonull. - Corresponding guards in mutator methods should be removed.
pre*()andpost*()methods should returnbool.
mcaskill
left a comment
There was a problem hiding this comment.
This review covers Config package.
There was a problem hiding this comment.
- Class properties
$keyCache,$mutatorCache, and$camelCacheshould be typedarray.
There was a problem hiding this comment.
- Method
defaults()should returnarray. - Method
addFile()parameter should be typedstring.
There was a problem hiding this comment.
Method parameter of config() should be typed ?string.
There was a problem hiding this comment.
- Class property
$configshould be typed?ConfigInterfaceand default tonull. - Method parameter
$keyofconfig()should be typed?string.
There was a problem hiding this comment.
Class property $delegates should be typed array.
There was a problem hiding this comment.
- Method return of
keys()should bearray. - Method return of
data()should bearray. - Method return of
has()should bebooland parameter$keyshould bestring. - Method parameter
$keyofget()should bestring. - Method parameter
$keyofset()should bestring.
There was a problem hiding this comment.
Method parameter $path of loadFile() should be string.
There was a problem hiding this comment.
Method parameter $separator of setSeparator() should be string.
There was a problem hiding this comment.
- Class property
$separatorshould be typedstringand not have a default value. - Method parameter of
setSeparator()should be typedstringand type guard removed. - Method return of
separator()should be typedstring. - Method parameter of
*WithSeparator()should be typedstring.
mcaskill
left a comment
There was a problem hiding this comment.
This review covers the CMS package.
There was a problem hiding this comment.
- Class property
$sectionFactoryshould be typed?FactoryInterfaceand default tonull. - Method
sectionFactory()should returnFactoryInterfaceand guard removed. - Methods
abridgeUri()andabridgeStr()should be typed.
There was a problem hiding this comment.
Method active() should return bool.
There was a problem hiding this comment.
- Class property
$isAttachmentMetadataFinalizedshould be typedbooland default tofalse. - Class property
$controllerIdentshould be typed?stringand default tonull(equivalent methods should be updated).
There was a problem hiding this comment.
- Class properties
$controllerIdent,$isMergingDataand$extraFormGroupsappear unused and should be removed. - Class properties
$formGroupsand$widgetMetadatashould be typedarrayand default to[]. - Class property
$storagePropertyshould be typed?ModelStructurePropertyand default tonull. - Class property
$widgetFactoryshould be typed?FactoryInterfaceand default tonull. Corresponding accessor method return should be typed and guard removed.
There was a problem hiding this comment.
- Class properties
$defaultFromEmail,$contactCategoryObj
,$defaultContactCategory, and$contactObjshould be typed?stringand default tonull. - Class properties
$dateFormatsand$timeFormatsshould be typedarray. - Class properties
$homeNewsand$homeEventsshould be typedarrayand default to[]. - Class properties
$newsConfig,$eventConfig, and$sectionConfigshould be typed to their corresponding config class and default tonull.
There was a problem hiding this comment.
Class properties whose mutator methods are using Translator should be typed ?Translation.
There was a problem hiding this comment.
Class property $name should be typed ?Translation.
There was a problem hiding this comment.
Class property $name should be typed ?Translation.
There was a problem hiding this comment.
- Class properties
$templateIdentand$controllerIdentshould be typed?stringand default tostring. - Class property
$templateOptionsshould be typedarray. - Class property
$templateOptionsMetadatashould be typed?StructureMetadataand default tonull. - Class property
$areTemplateOptionsFinalizedshould be typedbool.
PHP 8.3 / 8.4 Compatibility
Branch:
joel/php8→mainSummary
Updates all 17 Charcoal packages for PHP 8.3 and 8.4 compatibility, addressing breaking changes and deprecations introduced in recent PHP versions.
Breaking Changes Fixed
strftime()removed in PHP 8.4 (charcoal/cms)strftime()calls inDateHelper.phpwithIntlDateFormatterequivalents (6 occurrences)strftime()was deprecated in PHP 8.1 and removed in PHP 8.4Implicit nullable parameters (all packages)
function foo(Type $param = null)→function foo(?Type $param = null)across all packagesDynamic properties (affected model classes)
#[AllowDynamicProperties]attribute to classes relying on dynamic property assignmentDependency Updates
PHP constraint — updated in all 17
composer.jsonfiles:Dev dependencies (all packages):
phpunit/phpunit^9.5^11.0vimeo/psalm^4.23^5.0phpstan/phpstan^1.7^2.0squizlabs/php_codesniffer^3.6^3.10Testing
phpstan,psalm)Notes
charcoal/app) is EOL but functions on PHP 8.4; a Slim 4 migration is tracked separatelycharcoal/cmsDateHelper.phplocale handling preserves existing output format across all supported locales — thestrftime→IntlDateFormatterreplacement was validated againstfr_CAanden_CAlocale strings