From 35d4d6567b1ec06980105e2b43c39eb9f09cba42 Mon Sep 17 00:00:00 2001 From: Touhidur Rahman Date: Mon, 21 Oct 2024 17:36:04 +0600 Subject: [PATCH] pkp/pkp-lib#10292 fixed issue when guarded attribute defined --- .../controlledVocab/ControlledVocabEntry.php | 16 +------ classes/core/traits/ModelWithSettings.php | 46 +++++++++++++++++-- 2 files changed, 45 insertions(+), 17 deletions(-) diff --git a/classes/controlledVocab/ControlledVocabEntry.php b/classes/controlledVocab/ControlledVocabEntry.php index 19f4825b242..707de4232d7 100644 --- a/classes/controlledVocab/ControlledVocabEntry.php +++ b/classes/controlledVocab/ControlledVocabEntry.php @@ -38,12 +38,11 @@ class ControlledVocabEntry extends Model */ protected $primaryKey = 'controlled_vocab_entry_id'; - // TODO: Investigate why defining any guarded props causing no data to store in settings table /** * @copydoc \Illuminate\Database\Eloquent\Concerns\GuardsAttributes::$guarded */ protected $guarded = [ - // 'id', + 'controlledVocabEntryId', ]; /** @@ -66,7 +65,7 @@ protected function casts(): array { return [ 'controlled_vocab_entry_id' => 'string', - 'controlled_vocab_id' => 'int', + 'controlled_vocab_id' => 'integer', 'seq' => 'float', ]; } @@ -103,17 +102,6 @@ public function getSettings(): array ); } - /** - * Accessor and Mutator for primary key => id - */ - protected function id(): Attribute - { - return Attribute::make( - get: fn($value, $attributes) => $attributes[$this->primaryKey] ?? null, - set: fn($value) => [$this->primaryKey => $value], - )->shouldCache(); - } - /** * The controlled vocab associated with this controlled vocab entry */ diff --git a/classes/core/traits/ModelWithSettings.php b/classes/core/traits/ModelWithSettings.php index a63c1096447..295d61a131c 100644 --- a/classes/core/traits/ModelWithSettings.php +++ b/classes/core/traits/ModelWithSettings.php @@ -17,8 +17,9 @@ namespace PKP\core\traits; -use Eloquence\Behaviours\HasCamelCasing; use Exception; +use Eloquence\Behaviours\HasCamelCasing; +use Illuminate\Support\Str; use Illuminate\Database\Eloquent\Casts\Attribute; use PKP\core\maps\Schema; use PKP\core\SettingsBuilder; @@ -30,6 +31,11 @@ trait ModelWithSettings { use HasCamelCasing; + /** + * @see \Illuminate\Database\Eloquent\Concerns\GuardsAttributes::$guardableColumns + */ + protected static $guardableColumns = []; + // The list of attributes associated with the model settings protected array $settings = []; @@ -46,7 +52,7 @@ abstract public function getTable(); /** * Get settings table name */ - abstract public function getSettingsTable(); + abstract public function getSettingsTable(): string; /** * The name of the schema for the Model if exists, null otherwise @@ -54,7 +60,7 @@ abstract public function getSettingsTable(); abstract public static function getSchemaName(): ?string; /** - * See Illuminate\Database\Eloquent\Concerns\HasAttributes::mergeCasts() + * @see Illuminate\Database\Eloquent\Concerns\HasAttributes::mergeCasts() * * @param array $casts * @@ -62,6 +68,9 @@ abstract public static function getSchemaName(): ?string; */ abstract protected function ensureCastsAreStringValues($casts); + /** + * @see \Illuminate\Database\Eloquent\Model::__construct() + */ public function __construct(array $attributes = []) { parent::__construct($attributes); @@ -188,4 +197,35 @@ protected function id(): Attribute set: fn ($value) => [$this->primaryKey => $value], ); } + + /** + * @see \Illuminate\Database\Eloquent\Concerns\GuardsAttributes::isGuardableColumn() + */ + protected function isGuardableColumn($key) + { + // Need the snake like to key to check for main table to compare with column listing + $key = Str::snake($key); + + if (! isset(static::$guardableColumns[get_class($this)])) { + $columns = $this->getConnection() + ->getSchemaBuilder() + ->getColumnListing($this->getTable()); + + if (empty($columns)) { + return true; + } + static::$guardableColumns[get_class($this)] = $columns; + } + + + $settingsWithMultilingual = array_merge($this->getSettings(), $this->getMultilingualProps()); + $camelKey = Str::camel($key); + + // Check if this column included in setting and multilingula props and not set to guarded + if (in_array($camelKey, $settingsWithMultilingual) && !in_array($camelKey, $this->getGuarded())) { + return true; + } + + return in_array($key, (array)static::$guardableColumns[get_class($this)]); + } }