diff --git a/system/BaseModel.php b/system/BaseModel.php index d3b3cd56bbdd..5218154ce98f 100644 --- a/system/BaseModel.php +++ b/system/BaseModel.php @@ -35,7 +35,7 @@ /** * The BaseModel class provides a number of convenient features that * makes working with a databases less painful. Extending this class - * provide means of implementing various database systems + * provide means of implementing various database systems. * * It will: * - simplifies pagination @@ -60,21 +60,22 @@ abstract class BaseModel { /** * Pager instance. - * Populated after calling $this->paginate() + * + * Populated after calling `$this->paginate()`. * * @var Pager */ public $pager; /** - * Database Connection + * Database Connection. * * @var BaseConnection */ protected $db; /** - * Last insert ID + * Last insert ID. * * @var int|string */ @@ -90,14 +91,17 @@ abstract class BaseModel /** * The format that the results should be returned as. - * Will be overridden if the as* methods are used. * - * @var string + * Will be overridden if the `$this->asArray()`, `$this->asObject()` methods are used. + * + * @var 'array'|'object'|class-string */ protected $returnType = 'array'; /** - * Used by asArray() and asObject() to provide + * The temporary format of the result. + * + * Used by `$this->asArray()` and `$this->asObject()` to provide * temporary overrides of model default. * * @var 'array'|'object'|class-string @@ -107,14 +111,14 @@ abstract class BaseModel /** * Array of column names and the type of value to cast. * - * @var array [column => type] + * @var array Array order `['column' => 'type']`. */ protected array $casts = []; /** * Custom convert handlers. * - * @var array [type => classname] + * @var array Array order `['type' => 'classname']`. */ protected array $castHandlers = []; @@ -122,9 +126,9 @@ abstract class BaseModel /** * Determines whether the model should protect field names during - * mass assignment operations such as insert() and update(). + * mass assignment operations such as $this->insert(), $this->update(). * - * When set to true, only the fields explicitly defined in the $allowedFields + * When set to `true`, only the fields explicitly defined in the `$allowedFields` * property will be allowed for mass assignment. This helps prevent * unintended modification of database fields and improves security * by avoiding mass assignment vulnerabilities. @@ -153,21 +157,19 @@ abstract class BaseModel * The type of column that created_at and updated_at * are expected to. * - * Allowed: 'datetime', 'date', 'int' - * - * @var string + * @var 'date'|'datetime'|'int' */ protected $dateFormat = 'datetime'; /** - * The column used for insert timestamps + * The column used for insert timestamps. * * @var string */ protected $createdField = 'created_at'; /** - * The column used for update timestamps + * The column used for update timestamps. * * @var string */ @@ -183,15 +185,15 @@ abstract class BaseModel protected $useSoftDeletes = false; /** - * Used by withDeleted to override the - * model's softDelete setting. + * Used by $this->withDeleted() to override the + * model's "softDelete" setting. * * @var bool */ protected $tempUseSoftDeletes; /** - * The column used to save soft delete state + * The column used to save soft delete state. * * @var string */ @@ -208,10 +210,10 @@ abstract class BaseModel protected bool $updateOnlyChanged = true; /** - * Rules used to validate data in insert(), update(), save(), - * insertBatch(), and updateBatch() methods. + * Rules used to validate data + * in $this->insert(), $this->update(), $this->save() methods. * - * The array must match the format of data passed to the Validation + * The array must match the format of data passed to the `Validation` * library. * * @see https://codeigniter4.github.io/userguide/models/model.html#setting-validation-rules @@ -224,12 +226,14 @@ abstract class BaseModel * Contains any custom error messages to be * used during data validation. * - * @var array> + * @var array> The column is used as the keys. */ protected $validationMessages = []; /** - * Skip the model's validation. Used in conjunction with skipValidation() + * Skip the model's validation. + * + * Used in conjunction with `$this->skipValidation()` * to skip data validation for any future calls. * * @var bool @@ -265,99 +269,99 @@ abstract class BaseModel */ /** - * Whether to trigger the defined callbacks + * Whether to trigger the defined callbacks. * * @var bool */ protected $allowCallbacks = true; /** - * Used by allowCallbacks() to override the - * model's allowCallbacks setting. + * Used by $this->allowCallbacks() to override the + * model's $allowCallbacks setting. * * @var bool */ protected $tempAllowCallbacks; /** - * Callbacks for beforeInsert + * Callbacks for "beforeInsert" event. * * @var list */ protected $beforeInsert = []; /** - * Callbacks for afterInsert + * Callbacks for "afterInsert" event. * * @var list */ protected $afterInsert = []; /** - * Callbacks for beforeUpdate + * Callbacks for "beforeUpdate" event. * * @var list */ protected $beforeUpdate = []; /** - * Callbacks for afterUpdate + * Callbacks for "afterUpdate" event. * * @var list */ protected $afterUpdate = []; /** - * Callbacks for beforeInsertBatch + * Callbacks for "beforeInsertBatch" event. * * @var list */ protected $beforeInsertBatch = []; /** - * Callbacks for afterInsertBatch + * Callbacks for "afterInsertBatch" event. * * @var list */ protected $afterInsertBatch = []; /** - * Callbacks for beforeUpdateBatch + * Callbacks for "beforeUpdateBatch" event. * * @var list */ protected $beforeUpdateBatch = []; /** - * Callbacks for afterUpdateBatch + * Callbacks for "afterUpdateBatch" event. * * @var list */ protected $afterUpdateBatch = []; /** - * Callbacks for beforeFind + * Callbacks for "beforeFind" event. * * @var list */ protected $beforeFind = []; /** - * Callbacks for afterFind + * Callbacks for "afterFind" event. * * @var list */ protected $afterFind = []; /** - * Callbacks for beforeDelete + * Callbacks for "beforeDelete" event. * * @var list */ protected $beforeDelete = []; /** - * Callbacks for afterDelete + * Callbacks for "afterDelete" event. * * @var list */ @@ -408,13 +412,15 @@ protected function initialize() } /** - * Fetches the row of database. + * Fetches the row(s) of database with a primary key + * matching $id. * This method works only with dbCalls. * - * @param bool $singleton Single or multiple results - * @param array|int|string|null $id One primary key or an array of primary keys + * @param bool $singleton Single or multiple results. + * @param int|list|string|null $id One primary key or an array of primary keys. * - * @return array|object|null The resulting row of data, or null. + * @return list|object|row_array|null The resulting row of data or null. + * @phpstan-return ($singleton is true ? object|row_array|null : list) */ abstract protected function doFind(bool $singleton, $id = null); @@ -422,9 +428,7 @@ abstract protected function doFind(bool $singleton, $id = null); * Fetches the column of database. * This method works only with dbCalls. * - * @param string $columnName Column Name - * - * @return array|null The resulting row of data, or null if no data found. + * @return list|null The resulting row of data or null if no data found. * * @throws DataException */ @@ -434,10 +438,7 @@ abstract protected function doFindColumn(string $columnName); * Fetches all results, while optionally limiting them. * This method works only with dbCalls. * - * @param int|null $limit Limit - * @param int $offset Offset - * - * @return array + * @return list */ abstract protected function doFindAll(?int $limit = null, int $offset = 0); @@ -445,7 +446,7 @@ abstract protected function doFindAll(?int $limit = null, int $offset = 0); * Returns the first row of the result set. * This method works only with dbCalls. * - * @return array|object|null + * @return object|row_array|null */ abstract protected function doFirst(); @@ -453,8 +454,7 @@ abstract protected function doFirst(); * Inserts data into the current database. * This method works only with dbCalls. * - * @param array $row Row data - * @phpstan-param row_array $row + * @param row_array $row * * @return bool */ @@ -464,12 +464,12 @@ abstract protected function doInsert(array $row); * Compiles batch insert and runs the queries, validating each row prior. * This method works only with dbCalls. * - * @param array|null $set An associative array of insert values - * @param bool|null $escape Whether to escape values - * @param int $batchSize The size of the batch to run - * @param bool $testing True means only number of records is returned, false will execute the query + * @param list|null $set An associative array of insert values + * @param bool|null $escape Whether to escape values + * @param int $batchSize The size of the batch to run + * @param bool $testing `true` means only number of records is returned, `false` will execute the query * - * @return bool|int Number of rows inserted or FALSE on failure + * @return false|int|list Number of rows affected or `false` on failure, SQL array when test mode */ abstract protected function doInsertBatch(?array $set = null, ?bool $escape = null, int $batchSize = 100, bool $testing = false); @@ -477,9 +477,8 @@ abstract protected function doInsertBatch(?array $set = null, ?bool $escape = nu * Updates a single record in the database. * This method works only with dbCalls. * - * @param array|int|string|null $id ID - * @param array|null $row Row data - * @phpstan-param row_array|null $row + * @param array|int|string|null $id + * @param row_array|null $row */ abstract protected function doUpdate($id = null, $row = null): bool; @@ -487,42 +486,43 @@ abstract protected function doUpdate($id = null, $row = null): bool; * Compiles an update and runs the query. * This method works only with dbCalls. * - * @param array|null $set An associative array of update values - * @param string|null $index The where key - * @param int $batchSize The size of the batch to run - * @param bool $returnSQL True means SQL is returned, false will execute the query + * @param list|null $set An associative array of update values + * @param string|null $index The where key + * @param int $batchSize The size of the batch to run + * @param bool $returnSQL `true` means SQL is returned, `false` will execute the query * - * @return false|int|list Number of rows affected or FALSE on failure, SQL array when testMode + * @return false|int|list Number of rows affected or `false` on failure, SQL array when test mode * * @throws DatabaseException */ abstract protected function doUpdateBatch(?array $set = null, ?string $index = null, int $batchSize = 100, bool $returnSQL = false); /** - * Deletes a single record from the database where $id matches. + * Deletes a single record from the database where $id matches + * the table's primary key. * This method works only with dbCalls. * - * @param array|int|string|null $id The rows primary key(s) - * @param bool $purge Allows overriding the soft deletes setting. + * @param array|int|string|null $id The rows primary key(s) + * @param bool $purge Allows overriding the soft deletes setting * - * @return bool|string + * @return bool|string Returns a SQL string if in test mode * * @throws DatabaseException */ abstract protected function doDelete($id = null, bool $purge = false); /** - * Permanently deletes all rows that have been marked as deleted. - * through soft deletes (deleted = 1). + * Permanently deletes all rows that have been marked as deleted + * through soft deletes (value of column $deletedField is not null). * This method works only with dbCalls. * - * @return bool|string Returns a string if in test mode. + * @return bool|string Returns a SQL string if in test mode */ abstract protected function doPurgeDeleted(); /** - * Works with the find* methods to return only the rows that - * have been deleted. + * Works with the $this->find* methods to return only the rows that + * have been deleted (value of column $deletedField is not null). * This method works only with dbCalls. * * @return void @@ -533,8 +533,8 @@ abstract protected function doOnlyDeleted(); * Compiles a replace and runs the query. * This method works only with dbCalls. * - * @param row_array|null $row Row data - * @param bool $returnSQL Set to true to return Query String + * @param row_array|null $row + * @param bool $returnSQL `true` means SQL is returned, `false` will execute the query * * @return BaseResult|false|Query|string */ @@ -549,12 +549,12 @@ abstract protected function doReplace(?array $row = null, bool $returnSQL = fals abstract protected function doErrors(); /** - * Public getter to return the id value using the idValue() method. - * For example with SQL this will return $data->$this->primaryKey. + * Public getter to return the id value for the data array or object. + * For example with SQL this will return `$data->{$this->primaryKey}`. * - * @param object|row_array $row Row data + * @param object|row_array $row * - * @return array|int|string|null + * @return int|string|null */ abstract public function getIdValue($row); @@ -562,10 +562,12 @@ abstract public function getIdValue($row); * Override countAllResults to account for soft deleted accounts. * This method works only with dbCalls. * - * @param bool $reset Reset - * @param bool $test Test + * @param bool $reset When `false`, the `$tempUseSoftDeletes` will be + * dependent on `$useSoftDeletes` value because we don't + * want to add the same "where" condition for the second time + * @param bool $test `true` returns the number of all records, `false` will execute the query * - * @return int|string + * @return int|string Returns a SQL string if in test mode */ abstract public function countAllResults(bool $reset = true, bool $test = false); @@ -573,8 +575,7 @@ abstract public function countAllResults(bool $reset = true, bool $test = false) * Loops over records in batches, allowing you to operate on them. * This method works only with dbCalls. * - * @param int $size Size - * @param Closure(array|object): mixed $userFunc Callback Function + * @param Closure(array|object): mixed $userFunc * * @return void * @@ -585,10 +586,10 @@ abstract public function chunk(int $size, Closure $userFunc); /** * Fetches the row of database. * - * @param array|int|string|null $id One primary key or an array of primary keys + * @param int|list|string|null $id One primary key or an array of primary keys * - * @return array|object|null The resulting row of data, or null. - * @phpstan-return ($id is int|string ? row_array|object|null : list) + * @return list|object|row_array|null + * @phpstan-return ($id is int|string ? object|row_array|null : list) */ public function find($id = null) { @@ -628,9 +629,7 @@ public function find($id = null) /** * Fetches the column of database. * - * @param string $columnName Column Name - * - * @return array|null The resulting row of data, or null if no data found. + * @return list|object|string|null>|null The resulting row of data, or null if no data found * * @throws DataException */ @@ -648,10 +647,7 @@ public function findColumn(string $columnName) /** * Fetches all results, while optionally limiting them. * - * @param int $limit Limit - * @param int $offset Offset - * - * @return array + * @return list */ public function findAll(?int $limit = null, int $offset = 0) { @@ -696,7 +692,7 @@ public function findAll(?int $limit = null, int $offset = 0) /** * Returns the first row of the result set. * - * @return array|object|null + * @return object|row_array|null */ public function first() { @@ -731,12 +727,14 @@ public function first() /** * A convenience method that will attempt to determine whether the - * data should be inserted or updated. Will work with either - * an array or object. When using with custom class objects, + * data should be inserted or updated. + * + * Will work with either an array or object. + * When using with custom class objects, * you must ensure that the class will provide access to the class * variables, even if through a magic method. * - * @param object|row_array $row Row data + * @param object|row_array $row * * @throws ReflectionException */ @@ -761,16 +759,15 @@ public function save($row): bool /** * This method is called on save to determine if entry have to be updated. - * If this method returns false insert operation will be executed + * If this method returns `false` insert operation will be executed. * - * @param array|object $row Row data - * @phpstan-param row_array|object $row + * @param object|row_array $row */ protected function shouldUpdate($row): bool { $id = $this->getIdValue($row); - return ! ($id === null || $id === [] || $id === ''); + return $id !== null && $id !== ''; } /** @@ -787,10 +784,11 @@ public function getInsertID() * Inserts data into the database. If an object is provided, * it will attempt to convert it to an array. * - * @param object|row_array|null $row Row data - * @param bool $returnID Whether insert ID should be returned or not. + * @param object|row_array|null $row + * @param bool $returnID Whether insert ID should be returned or not * - * @return ($returnID is true ? false|int|string : bool) + * @return bool|int|string + * @phpstan-return ($returnID is true ? false|int|string : bool) * * @throws ReflectionException */ @@ -864,7 +862,7 @@ public function insert($row = null, bool $returnID = true) * Set datetime to created field. * * @param row_array $row - * @param int|string $date timestamp or datetime string + * @param int|string $date Timestamp or datetime string */ protected function setCreatedField(array $row, $date): array { @@ -879,7 +877,7 @@ protected function setCreatedField(array $row, $date): array * Set datetime to updated field. * * @param row_array $row - * @param int|string $date timestamp or datetime string + * @param int|string $date Timestamp or datetime string */ protected function setUpdatedField(array $row, $date): array { @@ -893,12 +891,12 @@ protected function setUpdatedField(array $row, $date): array /** * Compiles batch insert runs the queries, validating each row prior. * - * @param list|null $set an associative array of insert values + * @param list|null $set An associative array of insert values * @param bool|null $escape Whether to escape values * @param int $batchSize The size of the batch to run - * @param bool $testing True means only number of records is returned, false will execute the query + * @param bool $testing `true` means only number of records is returned, `false` will execute the query * - * @return bool|int Number of rows inserted or FALSE on failure + * @return false|int|list Number of rows inserted or `false` on failure * * @throws ReflectionException */ @@ -961,19 +959,14 @@ public function insertBatch(?array $set = null, ?bool $escape = null, int $batch * Updates a single record in the database. If an object is provided, * it will attempt to convert it into an array. * - * @param array|int|string|null $id - * @param array|object|null $row Row data - * @phpstan-param row_array|object|null $row + * @param array|int|string|null $id + * @param object|row_array|null $row * * @throws ReflectionException */ public function update($id = null, $row = null): bool { - if (is_bool($id)) { - throw new InvalidArgumentException('update(): argument #1 ($id) should not be boolean.'); - } - - if (is_numeric($id) || is_string($id)) { + if ($this->hasAllowedValueId($id)) { $id = [$id]; } @@ -1023,12 +1016,12 @@ public function update($id = null, $row = null): bool /** * Compiles an update and runs the query. * - * @param list|null $set an associative array of insert values + * @param list|null $set An associative array of insert values * @param string|null $index The where key * @param int $batchSize The size of the batch to run - * @param bool $returnSQL True means SQL is returned, false will execute the query + * @param bool $returnSQL `true` means SQL is returned, `false` will execute the query * - * @return false|int|list Number of rows affected or FALSE on failure, SQL array when testMode + * @return false|int|list Number of rows affected or `false` on failure, SQL array when test mode * * @throws DatabaseException * @throws ReflectionException @@ -1092,19 +1085,15 @@ public function updateBatch(?array $set = null, ?string $index = null, int $batc * Deletes a single record from the database where $id matches. * * @param int|list|string|null $id The rows primary key(s) - * @param bool $purge Allows overriding the soft deletes setting. + * @param bool $purge Allows overriding the soft deletes setting * - * @return BaseResult|bool + * @return bool|string Returns a SQL string if in test mode * * @throws DatabaseException */ public function delete($id = null, bool $purge = false) { - if (is_bool($id)) { - throw new InvalidArgumentException('delete(): argument #1 ($id) should not be boolean.'); - } - - if (! in_array($id, [null, 0, '0'], true) && (is_numeric($id) || is_string($id))) { + if ($this->hasAllowedValueId($id)) { $id = [$id]; } @@ -1135,9 +1124,9 @@ public function delete($id = null, bool $purge = false) /** * Permanently deletes all rows that have been marked as deleted - * through soft deletes (deleted = 1). + * through soft deletes (value of column $deletedField is not null). * - * @return bool|string Returns a string if in test mode. + * @return bool|string Returns a SQL string if in test mode */ public function purgeDeleted() { @@ -1152,8 +1141,6 @@ public function purgeDeleted() * Sets $useSoftDeletes value so that we can temporarily override * the soft deletes settings. Can be used for all find* methods. * - * @param bool $val Value - * * @return $this */ public function withDeleted(bool $val = true) @@ -1164,7 +1151,7 @@ public function withDeleted(bool $val = true) } /** - * Works with the find* methods to return only the rows that + * Works with the $this->find* methods to return only the rows that * have been deleted. * * @return $this @@ -1180,8 +1167,8 @@ public function onlyDeleted() /** * Compiles a replace and runs the query. * - * @param row_array|null $row Row data - * @param bool $returnSQL Set to true to return Query String + * @param row_array|null $row + * @param bool $returnSQL `true` means SQL is returned, `false` will execute the query * * @return BaseResult|false|Query|string */ @@ -1200,12 +1187,13 @@ public function replace(?array $row = null, bool $returnSQL = false) } /** - * Grabs the last error(s) that occurred. If data was validated, - * it will first check for errors there, otherwise will try to - * grab the last error from the Database connection. + * Grabs the last error(s) that occurred. + * + * If data was validated, it will first check for errors there, + * otherwise will try to grab the last error from the Database connection. * * The return array should be in the following format: - * ['source' => 'message'] + * `['source' => 'message']`. * * @param bool $forceDB Always grab the db error, not validation * @@ -1231,11 +1219,11 @@ public function errors(bool $forceDB = false) * to display. * * @param int|null $perPage Items per page - * @param string $group Will be used by the pagination library to identify a unique pagination set. + * @param string $group Will be used by the pagination library to identify a unique pagination set * @param int|null $page Optional page number (useful when the page number is provided in different way) * @param int $segment Optional URI segment number (if page number is provided by URI segment) * - * @return array|null + * @return list */ public function paginate(?int $perPage = null, string $group = 'default', ?int $page = null, int $segment = 0) { @@ -1258,7 +1246,7 @@ public function paginate(?int $perPage = null, string $group = 'default', ?int $ /** * It could be used when you have to change default or override current allowed fields. * - * @param array $allowedFields Array with names of fields + * @param list $allowedFields Array with names of fields * * @return $this */ @@ -1273,8 +1261,6 @@ public function setAllowedFields(array $allowedFields) * Sets whether or not we should whitelist data set during * updates or inserts against $this->availableFields. * - * @param bool $protect Value - * * @return $this */ public function protect(bool $protect = true) @@ -1291,8 +1277,7 @@ public function protect(bool $protect = true) * @used-by update() to protect against mass assignment vulnerabilities. * @used-by updateBatch() to protect against mass assignment vulnerabilities. * - * @param array $row Row data - * @phpstan-param row_array $row + * @param row_array $row * * @throws DataException */ @@ -1322,8 +1307,7 @@ protected function doProtectFields(array $row): array * @used-by insert() to protect against mass assignment vulnerabilities. * @used-by insertBatch() to protect against mass assignment vulnerabilities. * - * @param array $row Row data - * @phpstan-param row_array $row + * @param row_array $row * * @throws DataException */ @@ -1333,17 +1317,17 @@ protected function doProtectFieldsForInsert(array $row): array } /** - * Sets the date or current date if null value is passed. + * Sets the timestamp or current timestamp if null value is passed. * - * @param int|null $userData An optional PHP timestamp to be converted. + * @param int|null $userDate An optional PHP timestamp to be converted * * @return int|string * * @throws ModelException */ - protected function setDate(?int $userData = null) + protected function setDate(?int $userDate = null) { - $currentDate = $userData ?? Time::now()->getTimestamp(); + $currentDate = $userDate ?? Time::now()->getTimestamp(); return $this->intToDate($currentDate); } @@ -1359,8 +1343,6 @@ protected function setDate(?int $userData = null) * - 'datetime' - Stores the data in the SQL datetime format * - 'date' - Stores the date (only) in the SQL date format. * - * @param int $value value - * * @return int|string * * @throws ModelException @@ -1383,8 +1365,6 @@ protected function intToDate(int $value) * - 'datetime' - Stores the data in the SQL datetime format * - 'date' - Stores the date (only) in the SQL date format. * - * @param Time $value value - * * @return int|string */ protected function timeToDate(Time $value) @@ -1398,9 +1378,7 @@ protected function timeToDate(Time $value) } /** - * Set the value of the skipValidation flag. - * - * @param bool $skip Value + * Set the value of the $skipValidation flag. * * @return $this */ @@ -1415,7 +1393,7 @@ public function skipValidation(bool $skip = true) * Allows to set (and reset) validation messages. * It could be used when you have to change default or override current validate messages. * - * @param array $validationMessages Value + * @param array> $validationMessages * * @return $this */ @@ -1430,8 +1408,7 @@ public function setValidationMessages(array $validationMessages) * Allows to set field wise validation message. * It could be used when you have to change default or override current validate messages. * - * @param string $field Field Name - * @param array $fieldMessages Validation messages + * @param array $fieldMessages * * @return $this */ @@ -1446,7 +1423,7 @@ public function setValidationMessage(string $field, array $fieldMessages) * Allows to set (and reset) validation rules. * It could be used when you have to change default or override current validate rules. * - * @param array|string>|string> $validationRules Value + * @param array|string>|string> $validationRules * * @return $this */ @@ -1461,8 +1438,7 @@ public function setValidationRules(array $validationRules) * Allows to set field wise validation rules. * It could be used when you have to change default or override current validate rules. * - * @param string $field Field Name - * @param array|string $fieldRules Validation rules + * @param array|string>|string $fieldRules * * @return $this */ @@ -1490,8 +1466,6 @@ public function setValidationRule(string $field, $fieldRules) * Should validation rules be removed before saving? * Most handy when doing updates. * - * @param bool $choice Value - * * @return $this */ public function cleanRules(bool $choice = false) @@ -1505,8 +1479,7 @@ public function cleanRules(bool $choice = false) * Validate the row data against the validation rules (or the validation group) * specified in the class property, $validationRules. * - * @param array|object $row Row data - * @phpstan-param row_array|object $row + * @param object|row_array $row */ public function validate($row): bool { @@ -1548,7 +1521,9 @@ public function validate($row): bool * Returns the model's defined validation rules so that they * can be used elsewhere, if needed. * - * @param array $options Options + * @param array{only?: list, except?: list} $options Filter the list of rules + * + * @return array|string>|string> */ public function getValidationRules(array $options = []): array { @@ -1583,6 +1558,8 @@ protected function ensureValidation(): void /** * Returns the model's validation messages, so they * can be used elsewhere, if needed. + * + * @return array> */ public function getValidationMessages(): array { @@ -1594,13 +1571,14 @@ public function getValidationMessages(): array * currently so that rules don't block updating when only updating * a partial row. * - * @param array $rules Array containing field name and rule - * @param array $row Row data (@TODO Remove null in param type) - * @phpstan-param row_array $row + * @param array|string>|string> $rules + * @param row_array $row + * + * @return array|string>|string> */ - protected function cleanValidationRules(array $rules, ?array $row = null): array + protected function cleanValidationRules(array $rules, array $row): array { - if ($row === null || $row === []) { + if ($row === []) { return []; } @@ -1617,8 +1595,6 @@ protected function cleanValidationRules(array $rules, ?array $row = null): array * Sets $tempAllowCallbacks value so that we can temporarily override * the setting. Resets after the next method that uses triggers. * - * @param bool $val value - * * @return $this */ public function allowCallbacks(bool $val = true) @@ -1643,10 +1619,12 @@ public function allowCallbacks(bool $val = true) * * If callbacks are not allowed then returns $eventData immediately. * - * @param string $event Event - * @param array $eventData Event Data + * @template TEventData of array + * + * @param string $event Valid property of the model event: $this->before*, $this->after*, etc + * @param TEventData $eventData * - * @return array + * @return TEventData * * @throws DataException */ @@ -1686,7 +1664,7 @@ public function asArray() * class vars with the same name as the collection columns, * or at least allows them to be created. * - * @param 'object'|class-string $class Class Name + * @param 'object'|class-string $class * * @return $this */ @@ -1700,12 +1678,12 @@ public function asObject(string $class = 'object') /** * Takes a class and returns an array of its public and protected * properties as an array suitable for use in creates and updates. - * This method uses objectToRawArray() internally and does conversion - * to string on all Time instances + * This method uses `$this->objectToRawArray()` internally and does conversion + * to string on all Time instances. * - * @param object $object Object - * @param bool $onlyChanged Only Changed Property - * @param bool $recursive If true, inner entities will be cast as array as well + * @param object $object + * @param bool $onlyChanged Returns only the changed properties + * @param bool $recursive If `true`, inner entities will be cast as array as well * * @return array * @@ -1745,17 +1723,17 @@ protected function timeToString(array $properties): array * Takes a class and returns an array of its public and protected * properties as an array with raw values. * - * @param object $object Object - * @param bool $onlyChanged Only Changed Property - * @param bool $recursive If true, inner entities will be casted as array as well + * @param object $object + * @param bool $onlyChanged Returns only the changed properties + * @param bool $recursive If `true`, inner entities will be cast as array as well * - * @return array Array with raw values. + * @return array Array with raw values * * @throws ReflectionException */ protected function objectToRawArray($object, bool $onlyChanged = true, bool $recursive = false): array { - // Entity::toRawArray() returns array. + // Entity::toRawArray() returns array if (method_exists($object, 'toRawArray')) { $properties = $object->toRawArray($onlyChanged, $recursive); } else { @@ -1765,7 +1743,7 @@ protected function objectToRawArray($object, bool $onlyChanged = true, bool $rec $properties = []; // Loop over each property, - // saving the name/value in a new array we can return. + // saving the name/value in a new array we can return foreach ($props as $prop) { $properties[$prop->getName()] = $prop->getValue($object); } @@ -1777,8 +1755,7 @@ protected function objectToRawArray($object, bool $onlyChanged = true, bool $rec /** * Transform data to array. * - * @param object|row_array|null $row Row data - * @param string $type Type of data (insert|update) + * @param object|row_array|null $row * * @throws DataException * @throws InvalidArgumentException @@ -1844,9 +1821,7 @@ protected function transformDataToArray($row, string $type): array /** * Provides the db connection and model's properties. * - * @param string $name Name - * - * @return array|bool|float|int|object|string|null + * @return array|bool|float|int|object|string|null */ public function __get(string $name) { @@ -1859,8 +1834,6 @@ public function __get(string $name) /** * Checks for the existence of properties across this model, and db connection. - * - * @param string $name Name */ public function __isset(string $name): bool { @@ -1874,10 +1847,9 @@ public function __isset(string $name): bool /** * Provides direct access to method in the database connection. * - * @param string $name Name - * @param array $params Params + * @param array $params * - * @return $this|null + * @return $this|array|bool|float|int|object|string|null */ public function __call(string $name, array $params) { @@ -1916,4 +1888,24 @@ protected function convertToReturnType(array $row, string $returnType): array|ob return $this->converter->reconstruct($returnType, $row); } + + /** + * Checking that the ID has a rational value. + * + * Standard type checks in PHP do not fully verify the validity of ID as a primary key. + * Especially the values 0, '0', '' are rarely used or are invalid. + * Example, if you add an entry with ID=0, it will be an error for `$this->insertID`. + * + * @param array|float|int|string|null $id + * + * @throws InvalidArgumentException + */ + protected function hasAllowedValueId($id): bool + { + if (is_bool($id)) { + throw new InvalidArgumentException('The ID value should not be boolean.'); + } + + return ! in_array($id, [0, '0', '', 0.0], true) && (is_numeric($id) || is_string($id)); + } } diff --git a/system/Database/BaseBuilder.php b/system/Database/BaseBuilder.php index eb2dc6f73bd2..f773bae30e4b 100644 --- a/system/Database/BaseBuilder.php +++ b/system/Database/BaseBuilder.php @@ -947,8 +947,8 @@ public function orHavingNotIn(?string $key = null, $values = null, ?bool $escape * @used-by whereNotIn() * @used-by orWhereNotIn() * - * @param non-empty-string|null $key - * @param array|BaseBuilder|(Closure(BaseBuilder): BaseBuilder)|null $values The values searched on, or anonymous function with subquery + * @param non-empty-string|null $key + * @param array|BaseBuilder|(Closure(BaseBuilder): BaseBuilder)|null $values The values searched on, or anonymous function with subquery * * @return $this * diff --git a/system/Model.php b/system/Model.php index 44ed52a0edd0..47e79000159a 100644 --- a/system/Model.php +++ b/system/Model.php @@ -16,18 +16,15 @@ use Closure; use CodeIgniter\Database\BaseBuilder; use CodeIgniter\Database\BaseConnection; -use CodeIgniter\Database\BaseResult; use CodeIgniter\Database\ConnectionInterface; use CodeIgniter\Database\Exceptions\DatabaseException; use CodeIgniter\Database\Exceptions\DataException; -use CodeIgniter\Database\Query; use CodeIgniter\Entity\Entity; use CodeIgniter\Exceptions\BadMethodCallException; use CodeIgniter\Exceptions\ModelException; use CodeIgniter\Validation\ValidationInterface; use Config\Database; use Config\Feature; -use ReflectionException; use stdClass; /** @@ -91,7 +88,7 @@ class Model extends BaseModel { /** - * Name of database table + * Name of database table. * * @var string */ @@ -112,7 +109,7 @@ class Model extends BaseModel protected $useAutoIncrement = true; /** - * Query Builder object + * Query Builder object. * * @var BaseBuilder|null */ @@ -123,8 +120,7 @@ class Model extends BaseModel * so that we can capture it (not the builder) * and ensure it gets validated first. * - * @var array{escape: array, data: array}|array{} - * @phpstan-var array{escape: array, data: row_array}|array{} + * @var array{escape: array, data: row_array}|array{} */ protected $tempData = []; @@ -139,7 +135,7 @@ class Model extends BaseModel /** * Builder method names that should not be used in the Model. * - * @var list method name + * @var list */ private array $builderMethodsNotAvailable = [ 'getCompiledInsert', @@ -160,9 +156,7 @@ public function __construct(?ConnectionInterface $db = null, ?ValidationInterfac } /** - * Specify the table associated with a model - * - * @param string $table Table + * Specify the table associated with a model. * * @return $this */ @@ -173,22 +167,11 @@ public function setTable(string $table) return $this; } - /** - * Fetches the row(s) of database from $this->table with a primary key - * matching $id. - * This method works only with dbCalls. - * - * @param bool $singleton Single or multiple results - * @param array|int|string|null $id One primary key or an array of primary keys - * - * @return array|object|null The resulting row of data, or null. - * @phpstan-return ($singleton is true ? row_array|null|object : list) - */ protected function doFind(bool $singleton, $id = null) { $builder = $this->builder(); - $useCast = $this->useCasts(); + if ($useCast) { $returnType = $this->tempReturnType; $this->asArray(); @@ -238,30 +221,15 @@ protected function doFind(bool $singleton, $id = null) return $rows; } - /** - * Fetches the column of database from $this->table. - * This method works only with dbCalls. - * - * @param string $columnName Column Name - * - * @return array|null The resulting row of data, or null if no data found. - * @phpstan-return list|null - */ protected function doFindColumn(string $columnName) { return $this->select($columnName)->asArray()->find(); } /** - * Works with the current Query Builder instance to return - * all results, while optionally limiting them. - * This method works only with dbCalls. - * - * @param int|null $limit Limit - * @param int $offset Offset + * {@inheritDoc} * - * @return array - * @phpstan-return list + * Works with the current Query Builder instance. */ protected function doFindAll(?int $limit = null, int $offset = 0) { @@ -298,12 +266,10 @@ protected function doFindAll(?int $limit = null, int $offset = 0) } /** - * Returns the first row of the result set. Will take any previous - * Query Builder calls into account when determining the result set. - * This method works only with dbCalls. + * {@inheritDoc} * - * @return array|object|null - * @phpstan-return row_array|object|null + * Will take any previous Query Builder calls into account + * when determining the result set. */ protected function doFirst() { @@ -338,15 +304,6 @@ protected function doFirst() return $row; } - /** - * Inserts data into the current table. - * This method works only with dbCalls. - * - * @param array $row Row data - * @phpstan-param row_array $row - * - * @return bool - */ protected function doInsert(array $row) { $escape = $this->escape; @@ -402,24 +359,13 @@ protected function doInsert(array $row) return $result; } - /** - * Compiles batch insert strings and runs the queries, validating each row prior. - * This method works only with dbCalls. - * - * @param array|null $set An associative array of insert values - * @param bool|null $escape Whether to escape values - * @param int $batchSize The size of the batch to run - * @param bool $testing True means only number of records is returned, false will execute the query - * - * @return bool|int Number of rows inserted or FALSE on failure - */ protected function doInsertBatch(?array $set = null, ?bool $escape = null, int $batchSize = 100, bool $testing = false) { - if (is_array($set)) { + if (is_array($set) && ! $this->useAutoIncrement) { foreach ($set as $row) { - // Require non-empty primaryKey when + // Require non-empty $primaryKey when // not using auto-increment feature - if (! $this->useAutoIncrement && ! isset($row[$this->primaryKey])) { + if (! isset($row[$this->primaryKey])) { throw DataException::forEmptyPrimaryKey('insertBatch'); } } @@ -428,14 +374,6 @@ protected function doInsertBatch(?array $set = null, ?bool $escape = null, int $ return $this->builder()->testMode($testing)->insertBatch($set, $escape, $batchSize); } - /** - * Updates a single record in $this->table. - * This method works only with dbCalls. - * - * @param array|int|string|null $id - * @param array|null $row Row data - * @phpstan-param row_array|null $row - */ protected function doUpdate($id = null, $row = null): bool { $escape = $this->escape; @@ -443,7 +381,7 @@ protected function doUpdate($id = null, $row = null): bool $builder = $this->builder(); - if (! in_array($id, [null, '', 0, '0', []], true)) { + if ((is_array($id) && $id !== []) || $this->hasAllowedValueId($id)) { $builder = $builder->whereIn($this->table . '.' . $this->primaryKey, $id); } @@ -461,42 +399,17 @@ protected function doUpdate($id = null, $row = null): bool return $builder->update(); } - /** - * Compiles an update string and runs the query - * This method works only with dbCalls. - * - * @param array|null $set An associative array of update values - * @param string|null $index The where key - * @param int $batchSize The size of the batch to run - * @param bool $returnSQL True means SQL is returned, false will execute the query - * - * @return false|int|list Number of rows affected or FALSE on failure, SQL array when testMode - * - * @throws DatabaseException - */ protected function doUpdateBatch(?array $set = null, ?string $index = null, int $batchSize = 100, bool $returnSQL = false) { return $this->builder()->testMode($returnSQL)->updateBatch($set, $index, $batchSize); } - /** - * Deletes a single record from $this->table where $id matches - * the table's primaryKey - * This method works only with dbCalls. - * - * @param array|int|string|null $id The rows primary key(s) - * @param bool $purge Allows overriding the soft deletes setting. - * - * @return bool|string SQL string when testMode - * - * @throws DatabaseException - */ protected function doDelete($id = null, bool $purge = false) { $set = []; $builder = $this->builder(); - if (! in_array($id, [null, '', 0, '0', []], true)) { + if ((is_array($id) && $id !== []) || $this->hasAllowedValueId($id)) { $builder = $builder->whereIn($this->primaryKey, $id); } @@ -521,13 +434,6 @@ protected function doDelete($id = null, bool $purge = false) return $builder->delete(); } - /** - * Permanently deletes all rows that have been marked as deleted - * through soft deletes (deleted = 1) - * This method works only with dbCalls. - * - * @return bool|string Returns a SQL string if in test mode. - */ protected function doPurgeDeleted() { return $this->builder() @@ -535,39 +441,22 @@ protected function doPurgeDeleted() ->delete(); } - /** - * Works with the find* methods to return only the rows that - * have been deleted. - * This method works only with dbCalls. - * - * @return void - */ protected function doOnlyDeleted() { $this->builder()->where($this->table . '.' . $this->deletedField . ' IS NOT NULL'); } - /** - * Compiles a replace into string and runs the query - * This method works only with dbCalls. - * - * @param row_array|null $row Data - * @param bool $returnSQL Set to true to return Query String - * - * @return BaseResult|false|Query|string - */ protected function doReplace(?array $row = null, bool $returnSQL = false) { return $this->builder()->testMode($returnSQL)->replace($row); } /** - * Grabs the last error(s) that occurred from the Database connection. + * {@inheritDoc} + * * The return array should be in the following format: - * ['source' => 'message'] + * `['source' => 'message']`. * This method works only with dbCalls. - * - * @return array */ protected function doErrors() { @@ -581,14 +470,6 @@ protected function doErrors() return [$this->db::class => $error['message']]; } - /** - * Returns the id value for the data array or object - * - * @param array|object $row Row data - * @phpstan-param row_array|object $row - * - * @return array|int|string|null - */ public function getIdValue($row) { if (is_object($row)) { @@ -619,9 +500,23 @@ public function getIdValue($row) return null; } + public function countAllResults(bool $reset = true, bool $test = false) + { + if ($this->tempUseSoftDeletes) { + $this->builder()->where($this->table . '.' . $this->deletedField, null); + } + + $this->tempUseSoftDeletes = $reset + ? $this->useSoftDeletes + : ($this->useSoftDeletes ? false : $this->useSoftDeletes); + + return $this->builder()->testMode($test)->countAllResults($reset); + } + /** - * Loops over records in batches, allowing you to operate on them. - * Works with $this->builder to get the Compiled select to + * {@inheritDoc} + * + * Works with `$this->builder` to get the Compiled select to * determine the rows to operate on. * This method works only with dbCalls. */ @@ -654,27 +549,6 @@ public function chunk(int $size, Closure $userFunc) } } - /** - * Override countAllResults to account for soft deleted accounts. - * - * @return int|string - */ - public function countAllResults(bool $reset = true, bool $test = false) - { - if ($this->tempUseSoftDeletes) { - $this->builder()->where($this->table . '.' . $this->deletedField, null); - } - - // When $reset === false, the $tempUseSoftDeletes will be - // dependent on $useSoftDeletes value because we don't - // want to add the same "where" condition for the second time - $this->tempUseSoftDeletes = $reset - ? $this->useSoftDeletes - : ($this->useSoftDeletes ? false : $this->useSoftDeletes); - - return $this->builder()->testMode($test)->countAllResults($reset); - } - /** * Provides a shared instance of the Query Builder. * @@ -725,7 +599,7 @@ public function builder(?string $table = null) * data here. This allows it to be used with any of the other * builder methods and still get validated data, like replace. * - * @param array|object|string $key Field name, or an array of field/value pairs, or an object + * @param object|row_array|string $key Field name, or an array of field/value pairs, or an object * @param bool|float|int|object|string|null $value Field value, if $key is a single field * @param bool|null $escape Whether to escape values * @@ -748,12 +622,6 @@ public function set($key, $value = '', ?bool $escape = null) return $this; } - /** - * This method is called on save to determine if entry have to be updated - * If this method return false insert operation will be executed - * - * @param array|object $row Data - */ protected function shouldUpdate($row): bool { if (parent::shouldUpdate($row) === false) { @@ -769,17 +637,6 @@ protected function shouldUpdate($row): bool return $this->where($this->primaryKey, $this->getIdValue($row))->countAllResults() === 1; } - /** - * Inserts data into the database. If an object is provided, - * it will attempt to convert it to an array. - * - * @param object|row_array|null $row - * @param bool $returnID Whether insert ID should be returned or not. - * - * @return ($returnID is true ? false|int|string : bool) - * - * @throws ReflectionException - */ public function insert($row = null, bool $returnID = true) { if (isset($this->tempData['data'])) { @@ -797,18 +654,6 @@ public function insert($row = null, bool $returnID = true) return parent::insert($row, $returnID); } - /** - * Ensures that only the fields that are allowed to be inserted are in - * the data array. - * - * @used-by insert() to protect against mass assignment vulnerabilities. - * @used-by insertBatch() to protect against mass assignment vulnerabilities. - * - * @param array $row Row data - * @phpstan-param row_array $row - * - * @throws DataException - */ protected function doProtectFieldsForInsert(array $row): array { if (! $this->protectFields) { @@ -833,16 +678,6 @@ protected function doProtectFieldsForInsert(array $row): array return $row; } - /** - * Updates a single record in the database. If an object is provided, - * it will attempt to convert it into an array. - * - * @param array|int|string|null $id - * @param array|object|null $row - * @phpstan-param row_array|object|null $row - * - * @throws ReflectionException - */ public function update($id = null, $row = null): bool { if (isset($this->tempData['data'])) { @@ -860,17 +695,6 @@ public function update($id = null, $row = null): bool return parent::update($id, $row); } - /** - * Takes a class and returns an array of its public and protected - * properties as an array with raw values. - * - * @param object $object Object - * @param bool $recursive If true, inner entities will be cast as array as well - * - * @return array Array with raw values. - * - * @throws ReflectionException - */ protected function objectToRawArray($object, bool $onlyChanged = true, bool $recursive = false): array { return parent::objectToRawArray($object, $onlyChanged); @@ -879,9 +703,7 @@ protected function objectToRawArray($object, bool $onlyChanged = true, bool $rec /** * Provides/instantiates the builder/db connection and model's table/primary key names and return type. * - * @param string $name Name - * - * @return array|BaseBuilder|bool|float|int|object|string|null + * @return array|BaseBuilder|bool|float|int|object|string|null */ public function __get(string $name) { @@ -894,8 +716,6 @@ public function __get(string $name) /** * Checks for the existence of properties across this model, builder, and db connection. - * - * @param string $name Name */ public function __isset(string $name): bool { @@ -910,7 +730,7 @@ public function __isset(string $name): bool * Provides direct access to method in the builder (if available) * and the database connection. * - * @return $this|array|BaseBuilder|bool|float|int|object|string|null + * @return $this|array|BaseBuilder|bool|float|int|object|string|null */ public function __call(string $name, array $params) { diff --git a/tests/system/Models/MiscellaneousModelTest.php b/tests/system/Models/MiscellaneousModelTest.php index 556c1b441c18..ecc09f7851c0 100644 --- a/tests/system/Models/MiscellaneousModelTest.php +++ b/tests/system/Models/MiscellaneousModelTest.php @@ -14,7 +14,9 @@ namespace CodeIgniter\Models; use CodeIgniter\Database\Exceptions\DataException; +use CodeIgniter\Exceptions\InvalidArgumentException; use CodeIgniter\I18n\Time; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Group; use Tests\Support\Models\EntityModel; use Tests\Support\Models\JobModel; @@ -122,4 +124,46 @@ public function testEmptyDataInTransformDataToArray(): void $method = self::getPrivateMethodInvoker($this->model, 'transformDataToArray'); $method([], 'insert'); } + + public function testHasAllowedValueIdWithBoolean(): void + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('The ID value should not be boolean.'); + + $this->createModel(JobModel::class); + $method = self::getPrivateMethodInvoker($this->model, 'hasAllowedValueId'); + $method(true); // @phpstan-ignore argument.type + } + + /** + * @param float|int|string|null $value + */ + #[DataProvider('provideHasAllowedValueId')] + public function testHasAllowedValueId($value, bool $expected): void + { + $this->createModel(JobModel::class); + $method = self::getPrivateMethodInvoker($this->model, 'hasAllowedValueId'); + $this->assertSame($method($value), $expected); + } + + /** + * @return list> + */ + public static function provideHasAllowedValueId(): iterable + { + return [ + [0, false], + ['0', false], + [0.0, false], + ['', false], + [null, false], + ['001', true], + [' ', true], + [' 0 ', true], + [1, true], + ['1', true], + ['00000000-0000-0000-0000-000000000000', true], + ['codeigniter', true], + ]; + } } diff --git a/tests/system/Models/UpdateModelTest.php b/tests/system/Models/UpdateModelTest.php index 802896369aa5..ae3c487e1e7c 100644 --- a/tests/system/Models/UpdateModelTest.php +++ b/tests/system/Models/UpdateModelTest.php @@ -567,7 +567,7 @@ public function testUpdateThrowDatabaseExceptionWithoutWhereClause($id, string $ // $useSoftDeletes = false $this->createModel(JobModel::class); - $this->model->update($id, ['name' => 'Foo Bar']); + $this->model->update($id, ['name' => 'Foo Bar']); // @phpstan-ignore argument.type } public static function provideUpdateThrowDatabaseExceptionWithoutWhereClause(): iterable @@ -581,7 +581,7 @@ public static function provideUpdateThrowDatabaseExceptionWithoutWhereClause(): [ false, InvalidArgumentException::class, - 'update(): argument #1 ($id) should not be boolean.', + 'The ID value should not be boolean.', ], ]; } diff --git a/tests/system/Models/ValidationModelRuleGroupTest.php b/tests/system/Models/ValidationModelRuleGroupTest.php index eb50406ab62b..37e0ae4e3e6e 100644 --- a/tests/system/Models/ValidationModelRuleGroupTest.php +++ b/tests/system/Models/ValidationModelRuleGroupTest.php @@ -201,7 +201,7 @@ public function testCleanValidationRemovesAllWhenNoDataProvided(): void 'foo' => 'bar', ]; - $rules = $cleaner($rules, null); + $rules = $cleaner($rules, []); $this->assertEmpty($rules); } diff --git a/tests/system/Models/ValidationModelTest.php b/tests/system/Models/ValidationModelTest.php index 4a99d8fae5bb..7ec08c9e36ac 100644 --- a/tests/system/Models/ValidationModelTest.php +++ b/tests/system/Models/ValidationModelTest.php @@ -189,7 +189,7 @@ public function testCleanValidationRemovesAllWhenNoDataProvided(): void 'foo' => 'bar', ]; - $rules = $cleaner($rules, null); + $rules = $cleaner($rules, []); $this->assertEmpty($rules); } diff --git a/user_guide_src/source/changelogs/v4.7.0.rst b/user_guide_src/source/changelogs/v4.7.0.rst index 9399095c1d44..0077ed9e35f6 100644 --- a/user_guide_src/source/changelogs/v4.7.0.rst +++ b/user_guide_src/source/changelogs/v4.7.0.rst @@ -48,6 +48,8 @@ Interface Changes Method Signature Changes ======================== +- **BaseModel:** The type of the ``$row`` parameter for the ``cleanValidationRules()`` method has been changed from ``?array $row = null`` to ``array $row``. + - Added the ``SensitiveParameter`` attribute to various methods to conceal sensitive information from stack traces. Affected methods are: - ``CodeIgniter\Encryption\EncrypterInterface::encrypt()`` - ``CodeIgniter\Encryption\EncrypterInterface::decrypt()`` diff --git a/user_guide_src/source/models/model.rst b/user_guide_src/source/models/model.rst index 57fb52a024c3..5e42a39ca438 100644 --- a/user_guide_src/source/models/model.rst +++ b/user_guide_src/source/models/model.rst @@ -750,9 +750,9 @@ The other way to set the validation message to fields by functions, .. literalinclude:: model/030.php -.. php:method:: setValidationMessages($fieldMessages) +.. php:method:: setValidationMessages($validationMessages) - :param array $fieldMessages: + :param array $validationMessages: This function will set the field messages. diff --git a/utils/phpstan-baseline/argument.type.neon b/utils/phpstan-baseline/argument.type.neon index 0c99d09b54e3..ee64c6f1290e 100644 --- a/utils/phpstan-baseline/argument.type.neon +++ b/utils/phpstan-baseline/argument.type.neon @@ -1,4 +1,4 @@ -# total 85 errors +# total 84 errors parameters: ignoreErrors: @@ -197,11 +197,6 @@ parameters: count: 1 path: ../../tests/system/Models/DataConverterModelTest.php - - - message: '#^Parameter \#1 \$id of method CodeIgniter\\Model\:\:update\(\) expects array\|int\|string\|null, false\|null given\.$#' - count: 1 - path: ../../tests/system/Models/UpdateModelTest.php - - message: '#^Parameter \#1 \$format of method CodeIgniter\\RESTful\\ResourceController\:\:setFormat\(\) expects ''json''\|''xml'', ''Nonsense'' given\.$#' count: 1 diff --git a/utils/phpstan-baseline/loader.neon b/utils/phpstan-baseline/loader.neon index 4a3fe00ddf57..d9ba475e01d4 100644 --- a/utils/phpstan-baseline/loader.neon +++ b/utils/phpstan-baseline/loader.neon @@ -1,4 +1,4 @@ -# total 2795 errors +# total 2751 errors includes: - argument.type.neon diff --git a/utils/phpstan-baseline/method.childReturnType.neon b/utils/phpstan-baseline/method.childReturnType.neon index adf2f2999aaf..0e82a903c408 100644 --- a/utils/phpstan-baseline/method.childReturnType.neon +++ b/utils/phpstan-baseline/method.childReturnType.neon @@ -1,4 +1,4 @@ -# total 29 errors +# total 28 errors parameters: ignoreErrors: @@ -141,8 +141,3 @@ parameters: message: '#^Return type \(CodeIgniter\\Images\\Handlers\\ImageMagickHandler\) of method CodeIgniter\\Images\\Handlers\\ImageMagickHandler\:\:_resize\(\) should be covariant with return type \(\$this\(CodeIgniter\\Images\\Handlers\\BaseHandler\)\) of method CodeIgniter\\Images\\Handlers\\BaseHandler\:\:_resize\(\)$#' count: 1 path: ../../system/Images/Handlers/ImageMagickHandler.php - - - - message: '#^Return type \(array\|bool\|float\|int\|object\|string\|null\) of method CodeIgniter\\Model\:\:__call\(\) should be covariant with return type \(\$this\(CodeIgniter\\BaseModel\)\|null\) of method CodeIgniter\\BaseModel\:\:__call\(\)$#' - count: 1 - path: ../../system/Model.php diff --git a/utils/phpstan-baseline/missingType.iterableValue.neon b/utils/phpstan-baseline/missingType.iterableValue.neon index 9bb3a84ef6c0..3cf937172e50 100644 --- a/utils/phpstan-baseline/missingType.iterableValue.neon +++ b/utils/phpstan-baseline/missingType.iterableValue.neon @@ -1,67 +1,12 @@ -# total 1386 errors +# total 1344 errors parameters: ignoreErrors: - - - message: '#^Method CodeIgniter\\BaseModel\:\:__call\(\) has parameter \$params with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/BaseModel.php - - - - message: '#^Method CodeIgniter\\BaseModel\:\:__get\(\) return type has no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/BaseModel.php - - - - message: '#^Method CodeIgniter\\BaseModel\:\:cleanValidationRules\(\) has parameter \$rules with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/BaseModel.php - - - - message: '#^Method CodeIgniter\\BaseModel\:\:cleanValidationRules\(\) return type has no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/BaseModel.php - - message: '#^Method CodeIgniter\\BaseModel\:\:convertToReturnType\(\) return type has no value type specified in iterable type array\.$#' count: 1 path: ../../system/BaseModel.php - - - message: '#^Method CodeIgniter\\BaseModel\:\:doDelete\(\) has parameter \$id with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/BaseModel.php - - - - message: '#^Method CodeIgniter\\BaseModel\:\:doFind\(\) has parameter \$id with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/BaseModel.php - - - - message: '#^Method CodeIgniter\\BaseModel\:\:doFind\(\) return type has no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/BaseModel.php - - - - message: '#^Method CodeIgniter\\BaseModel\:\:doFindAll\(\) return type has no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/BaseModel.php - - - - message: '#^Method CodeIgniter\\BaseModel\:\:doFindColumn\(\) return type has no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/BaseModel.php - - - - message: '#^Method CodeIgniter\\BaseModel\:\:doFirst\(\) return type has no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/BaseModel.php - - - - message: '#^Method CodeIgniter\\BaseModel\:\:doInsertBatch\(\) has parameter \$set with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/BaseModel.php - - message: '#^Method CodeIgniter\\BaseModel\:\:doProtectFields\(\) return type has no value type specified in iterable type array\.$#' count: 1 @@ -72,66 +17,6 @@ parameters: count: 1 path: ../../system/BaseModel.php - - - message: '#^Method CodeIgniter\\BaseModel\:\:doUpdate\(\) has parameter \$id with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/BaseModel.php - - - - message: '#^Method CodeIgniter\\BaseModel\:\:doUpdateBatch\(\) has parameter \$set with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/BaseModel.php - - - - message: '#^Method CodeIgniter\\BaseModel\:\:find\(\) has parameter \$id with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/BaseModel.php - - - - message: '#^Method CodeIgniter\\BaseModel\:\:findAll\(\) return type has no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/BaseModel.php - - - - message: '#^Method CodeIgniter\\BaseModel\:\:findColumn\(\) return type has no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/BaseModel.php - - - - message: '#^Method CodeIgniter\\BaseModel\:\:first\(\) return type has no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/BaseModel.php - - - - message: '#^Method CodeIgniter\\BaseModel\:\:getIdValue\(\) return type has no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/BaseModel.php - - - - message: '#^Method CodeIgniter\\BaseModel\:\:getValidationMessages\(\) return type has no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/BaseModel.php - - - - message: '#^Method CodeIgniter\\BaseModel\:\:getValidationRules\(\) has parameter \$options with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/BaseModel.php - - - - message: '#^Method CodeIgniter\\BaseModel\:\:getValidationRules\(\) return type has no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/BaseModel.php - - - - message: '#^Method CodeIgniter\\BaseModel\:\:paginate\(\) return type has no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/BaseModel.php - - - - message: '#^Method CodeIgniter\\BaseModel\:\:setAllowedFields\(\) has parameter \$allowedFields with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/BaseModel.php - - message: '#^Method CodeIgniter\\BaseModel\:\:setCreatedField\(\) return type has no value type specified in iterable type array\.$#' count: 1 @@ -142,41 +27,11 @@ parameters: count: 1 path: ../../system/BaseModel.php - - - message: '#^Method CodeIgniter\\BaseModel\:\:setValidationMessage\(\) has parameter \$fieldMessages with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/BaseModel.php - - - - message: '#^Method CodeIgniter\\BaseModel\:\:setValidationMessages\(\) has parameter \$validationMessages with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/BaseModel.php - - - - message: '#^Method CodeIgniter\\BaseModel\:\:setValidationRule\(\) has parameter \$fieldRules with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/BaseModel.php - - message: '#^Method CodeIgniter\\BaseModel\:\:transformDataToArray\(\) return type has no value type specified in iterable type array\.$#' count: 1 path: ../../system/BaseModel.php - - - message: '#^Method CodeIgniter\\BaseModel\:\:trigger\(\) has parameter \$eventData with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/BaseModel.php - - - - message: '#^Method CodeIgniter\\BaseModel\:\:trigger\(\) return type has no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/BaseModel.php - - - - message: '#^Method CodeIgniter\\BaseModel\:\:update\(\) has parameter \$id with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/BaseModel.php - - message: '#^Method CodeIgniter\\CLI\\CLI\:\:isZeroOptions\(\) has parameter \$options with no value type specified in iterable type array\.$#' count: 1 @@ -582,11 +437,6 @@ parameters: count: 1 path: ../../system/Database/BaseBuilder.php - - - message: '#^Method CodeIgniter\\Database\\BaseBuilder\:\:_whereIn\(\) has parameter \$values with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/Database/BaseBuilder.php - - message: '#^Method CodeIgniter\\Database\\BaseBuilder\:\:batchObjectToArray\(\) has parameter \$object with no value type specified in iterable type array\.$#' count: 1 @@ -4097,71 +3947,11 @@ parameters: count: 1 path: ../../system/Images/Image.php - - - message: '#^Method CodeIgniter\\Model\:\:__call\(\) has parameter \$params with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/Model.php - - - - message: '#^Method CodeIgniter\\Model\:\:__call\(\) return type has no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/Model.php - - - - message: '#^Method CodeIgniter\\Model\:\:__get\(\) return type has no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/Model.php - - - - message: '#^Method CodeIgniter\\Model\:\:doDelete\(\) has parameter \$id with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/Model.php - - - - message: '#^Method CodeIgniter\\Model\:\:doFind\(\) has parameter \$id with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/Model.php - - - - message: '#^Method CodeIgniter\\Model\:\:doInsertBatch\(\) has parameter \$set with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/Model.php - - message: '#^Method CodeIgniter\\Model\:\:doProtectFieldsForInsert\(\) return type has no value type specified in iterable type array\.$#' count: 1 path: ../../system/Model.php - - - message: '#^Method CodeIgniter\\Model\:\:doUpdate\(\) has parameter \$id with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/Model.php - - - - message: '#^Method CodeIgniter\\Model\:\:doUpdateBatch\(\) has parameter \$set with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/Model.php - - - - message: '#^Method CodeIgniter\\Model\:\:getIdValue\(\) return type has no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/Model.php - - - - message: '#^Method CodeIgniter\\Model\:\:set\(\) has parameter \$key with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/Model.php - - - - message: '#^Method CodeIgniter\\Model\:\:shouldUpdate\(\) has parameter \$row with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/Model.php - - - - message: '#^Method CodeIgniter\\Model\:\:update\(\) has parameter \$id with no value type specified in iterable type array\.$#' - count: 1 - path: ../../system/Model.php - - message: '#^Property CodeIgniter\\Model\:\:\$escape type has no value type specified in iterable type array\.$#' count: 1