Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 26 additions & 11 deletions config/model-preferences.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,50 @@

declare(strict_types=1);

use HosmelQ\ModelPreferences\Models\Preference;

return [

/*
|--------------------------------------------------------------------------
| Preferences Table Name
| Default Preference Driver
|--------------------------------------------------------------------------
|
| This is the name of the table that will be used to store preferences.
| You can change this to any table name you prefer.
| This option controls the default preference store that will be used.
| This connection is utilized if no other store is explicitly specified
| when running a preference operation within the application.
|
| Supported: "column", "separate", "shared"
|
*/

'table' => env('MODEL_PREFERENCES_TABLE', 'preferences'),
'default' => env('MODEL_PREFERENCES_DRIVER', 'shared'),

/*
|--------------------------------------------------------------------------
| Model Configuration
| Preference Stores
|--------------------------------------------------------------------------
|
| Specify the model classes to use for preferences. You can extend
| the default models to add custom functionality if needed.
| Here, you can define all the preference stores for your application
| along with their respective drivers.
|
*/

'models' => [
'stores' => [

'column' => [
'driver' => 'column',
'name' => env('MODEL_PREFERENCES_COLUMN_NAME', 'preferences'),
],

'separate' => [
'connection' => env('MODEL_PREFERENCES_DB_CONNECTION'),
'driver' => 'separate',
],

'preference' => Preference::class,
'shared' => [
'connection' => env('MODEL_PREFERENCES_DB_CONNECTION'),
'driver' => 'shared',
'table' => env('MODEL_PREFERENCES_TABLE', 'preferences'),
],

],

Expand Down
4 changes: 2 additions & 2 deletions database/migrations/create_preferences_table.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@
*/
public function down(): void
{
Schema::dropIfExists(Config::string('model-preferences.table'));
Schema::dropIfExists(Config::string('model-preferences.stores.shared.table'));
}

/**
* Run the migrations.
*/
public function up(): void
{
Schema::create(Config::string('model-preferences.table'), function (Blueprint $table) {
Schema::create(Config::string('model-preferences.stores.shared.table'), function (Blueprint $table) {
$table->id();

$table->morphs('preferable');
Expand Down
3 changes: 3 additions & 0 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@ includes:
- vendor/spaze/phpstan-disallowed-calls/disallowed-loose-calls.neon

parameters:
checkAuthCallsWhenInRequestScope: true
checkBenevolentUnionTypes: true
checkConfigTypes: true
checkModelProperties: true
checkOctaneCompatibility: true
editorUrl: 'phpstorm://open?file=%%file%%&line=%%line%%'
noUnnecessaryEnumerableToArrayCalls: true
errorFormat: ticketswap
level: max
noEnvCallsOutsideOfConfig: true
Expand Down
5 changes: 4 additions & 1 deletion pint.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@
"no_useless_else": true,
"no_whitespace_before_comma_in_array": true,
"not_operator_with_successor_space": true,
"nullable_type_declaration": {
"syntax": "union"
},
"object_operator_without_whitespace": true,
"ordered_class_elements": {
"order": [
Expand Down Expand Up @@ -85,6 +88,7 @@
},
"ordered_interfaces": true,
"ordered_traits": true,
"ordered_types": true,
"phpdoc_add_missing_param_annotation": true,
"phpdoc_align": {
"align": "left",
Expand All @@ -93,7 +97,6 @@
"phpdoc_indent": true,
"phpdoc_inline_tag_normalizer": true,
"phpdoc_line_span": true,
"phpdoc_list_type": false,
"phpdoc_no_useless_inheritdoc": true,
"phpdoc_order": {
"order": ["param", "return", "throws"]
Expand Down
22 changes: 0 additions & 22 deletions src/Contracts/HasPreferences.php

This file was deleted.

37 changes: 37 additions & 0 deletions src/Contracts/PreferenceDriver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

declare(strict_types=1);

namespace HosmelQ\ModelPreferences\Contracts;

use Illuminate\Database\Eloquent\Model;

interface PreferenceDriver
{
/**
* Get all preferences for a model.
*
* @return array<string, mixed>
*/
public function all(Model $model): array;

/**
* Delete a preference for a model.
*/
public function delete(Model $model, string $key): void;

/**
* Get a preference value for a model.
*/
public function get(Model $model, string $key): mixed;

/**
* Check if a preference exists for a model.
*/
public function has(Model $model, string $key): bool;

/**
* Set a preference value for a model.
*/
public function set(Model $model, string $key, mixed $value): void;
}
66 changes: 0 additions & 66 deletions src/Contracts/PreferenceRepository.php

This file was deleted.

125 changes: 125 additions & 0 deletions src/Drivers/ColumnDriver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
<?php

declare(strict_types=1);

namespace HosmelQ\ModelPreferences\Drivers;

use HosmelQ\ModelPreferences\Contracts\PreferenceDriver;
use Illuminate\Contracts\Config\Repository;
use Illuminate\Database\Eloquent\Model;

class ColumnDriver implements PreferenceDriver
{
/**
* Create a new column driver instance.
*/
public function __construct(
protected Repository $config,
protected string $name
) {
}

/**
* Get all preferences for a model.
*
* @return array<string, mixed>
*/
public function all(Model $model): array
{
return $this->getPreferences($model);
}

/**
* Delete a preference for a model.
*/
public function delete(Model $model, string $key): void
{
$preferences = $this->getPreferences($model);

unset($preferences[$key]);

$this->savePreferences($model, $preferences);
}

/**
* Get a preference value for a model.
*/
public function get(Model $model, string $key): mixed
{
$preferences = $this->getPreferences($model);

return $preferences[$key] ?? null;
}

/**
* Check if a preference exists for a model.
*/
public function has(Model $model, string $key): bool
{
$preferences = $this->getPreferences($model);

return array_key_exists($key, $preferences);
}

/**
* Set a preference value for a model.
*/
public function set(Model $model, string $key, mixed $value): void
{
$preferences = $this->getPreferences($model);

$preferences[$key] = $value;

$this->savePreferences($model, $preferences);
}

/**
* Get the default column name from config.
*/
protected function getDefaultColumnName(): string
{
$columnName = $this->config->get(sprintf('model-preferences.stores.%s.name', $this->name));

return is_string($columnName) ? $columnName : 'preferences';
}

/**
* Get all preferences from the model's JSON column.
*
* @return array<string, mixed>
*/
protected function getPreferences(Model $model): array
{
$columnName = method_exists($model, 'getPreferencesColumn')
? $model->getPreferencesColumn()
: $this->getDefaultColumnName();

if (! is_string($columnName)) {
$columnName = $this->getDefaultColumnName();
}

$value = $model->getAttribute($columnName);

return is_array($value) ? $value : [];
}

/**
* Save preferences to the model's JSON column.
*
* @param array<string, mixed> $preferences
*/
protected function savePreferences(Model $model, array $preferences): void
{
$columnName = method_exists($model, 'getPreferencesColumn')
? $model->getPreferencesColumn()
: $this->getDefaultColumnName();

if (! is_string($columnName)) {
$columnName = $this->getDefaultColumnName();
}

$model->update([
$columnName => $preferences,
]);
}
}
Loading
Loading