terms()->delete(); }); } protected $table = 'fct_atts_groups'; protected $fillable = [ 'title', 'slug', 'description', 'settings', 'serial', // is_system intentionally NOT fillable — it's a trust flag that only the // seeder sets (via bulk insert, which bypasses fillable). Keeping it out // of mass-assignment means user-created groups stay is_system=0 even if // a client sneaks the field into a request body. ]; protected $casts = [ 'is_system' => 'boolean', ]; public function setSettingsAttribute($value) { if (is_array($value)) { $value = json_encode($value, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); } $this->attributes['settings'] = $value; } public function getSettingsAttribute($value) { if (is_string($value)) { $decoded = json_decode($value, true); return $decoded ?: $value; } return $value; } /** * hasMany: Group has many Terms * * @return \FluentCart\Framework\Database\Orm\Relations\HasMany */ public function terms() { return $this->hasMany(AttributeTerm::class, 'group_id', 'id'); } public function usedTerms() { return $this->hasMany(AttributeRelation::class, 'group_id', 'id'); } public function scopeApplyCustomFilters( $query, $filters ) { if ( ! $filters ) { return $query; } $acceptedKeys = $this->fillable; foreach ( $filters as $filterKey => $filter ) { if ( ! in_array( $filterKey, $acceptedKeys ) && $filterKey !== 'terms_count') { continue; } $value = Arr::get( $filter, 'value', '' ); $operator = Arr::get( $filter, 'operator', '' ); if ( ! $value || ! $operator || is_array( $value ) ) { continue; } switch (strtolower($operator)) { case 'includes': $operator = "like_all"; break; case 'not_includes': $operator = "not_like"; break; case 'gt': $operator = ">"; break; case 'lt': $operator = "<"; break; default: } if ($filterKey === 'terms_count') { // Validate operator is in whitelist $allowedOperators = ['=', '>', '<', '>=', '<=', '!=']; if (in_array($operator, $allowedOperators)) { return $query->havingRaw($filterKey.' '.$operator.' ?', [(int)$value]); }else{ return $query; } // Use parameterized query } $param = [ $filterKey => [ "column" => $filterKey, "operator" => $operator, "value" => trim( $value ) ] ]; $query->when($param, function ($query) use ($param) { return $query->search($param); }); } return $query; } }