Skip to content

Commit

Permalink
Merge pull request #11 from matteoc99/feature/readme
Browse files Browse the repository at this point in the history
Feature/readme
  • Loading branch information
matteoc99 authored May 5, 2024
2 parents b7c0814 + 0c20863 commit 6300993
Show file tree
Hide file tree
Showing 17 changed files with 515 additions and 57 deletions.
117 changes: 74 additions & 43 deletions README.md

Large diffs are not rendered by default.

13 changes: 12 additions & 1 deletion src/Contracts/PreferenceableModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,17 @@ public function getPreferences(string $group = null): Collection;
*/
public function removePreference(PreferenceGroup $name): int;


/**
* Reset the model to its original state
* Remove all user's preferences.
*
*
* @return int Number of deleted records.
* @throws AuthorizationException
*/
public function removeAllPreferences(): int;

/**
* Set a preference value, handling validation and persistence.
*
Expand All @@ -54,7 +65,7 @@ public function setPreference(PreferenceGroup $name, mixed $value): void;
public function getPreference(PreferenceGroup $name, mixed $default = null): mixed;

/**
* Get a user's preference value or default if not set with no casting
* Get a user's preference value or default if not set, transformed for data transfer
*
* @param PreferenceGroup|Preference $preference
* @param string|null $default Default value if preference not set.
Expand Down
1 change: 1 addition & 0 deletions src/Enums/PolicyAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

enum PolicyAction
{
case DELETE_ALL;
case INDEX;
case GET;
case UPDATE;
Expand Down
26 changes: 26 additions & 0 deletions src/Exceptions/InvalidStateException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace Matteoc99\LaravelPreference\Exceptions;

use Exception;
use Throwable;

class InvalidStateException extends Exception
{

private int $state;

public function __construct($state, string $message, ?Throwable $previous = null)
{
$this->state = $state;
parent::__construct($message, 0, $previous);
}

/**
* @return int
*/
public function getState(): int
{
return $this->state;
}
}
46 changes: 40 additions & 6 deletions src/Factory/PreferenceBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
use Matteoc99\LaravelPreference\Contracts\CastableEnum;
use Matteoc99\LaravelPreference\Contracts\PreferenceGroup;
use Matteoc99\LaravelPreference\Enums\Cast;
use Matteoc99\LaravelPreference\Exceptions\InvalidStateException;
use Matteoc99\LaravelPreference\Factory\builders\BaseBuilder;
use Matteoc99\LaravelPreference\Factory\builders\ObjectPreferenceBuilder;
use Matteoc99\LaravelPreference\Factory\builders\PrimitivePreferenceBuilder;
use Matteoc99\LaravelPreference\Models\Preference;
Expand All @@ -28,6 +30,7 @@ class PreferenceBuilder
*
* @return void Creates the preference and commits it to the database.
*
* @throws InvalidStateException
* @example
* ```
* PreferenceBuilder::buildString(UserPreference::TEST, "default");
Expand All @@ -36,7 +39,7 @@ class PreferenceBuilder
*/
public static function buildString(PreferenceGroup $name, string $default = null): void
{
self::init($name)->nullable()->withDefaultValue(null)->create();
self::init($name)->nullable()->withDefaultValue($default)->create();
}

/**
Expand All @@ -49,6 +52,7 @@ public static function buildString(PreferenceGroup $name, string $default = null
*
* @return void Creates the preference and commits it to the database.
*
* @throws InvalidStateException
* @example
* ```
* PreferenceBuilder::buildArray(new SettingsPreferenceGroup(), ["item1", "item2"]);
Expand All @@ -58,7 +62,7 @@ public static function buildString(PreferenceGroup $name, string $default = null
*/
public static function buildArray(PreferenceGroup $name, array $default = null): void
{
self::init($name, Cast::ARRAY)->nullable()->withDefaultValue(null)->create();
self::init($name, Cast::ARRAY)->nullable()->withDefaultValue($default)->create();
}


Expand Down Expand Up @@ -99,7 +103,7 @@ public static function init(PreferenceGroup $name, CastableEnum $cast = Cast::ST
*
* @param PreferenceGroup $name
*
* @return int,
* @return int
*/
public static function delete(PreferenceGroup $name): int
{
Expand Down Expand Up @@ -148,7 +152,23 @@ public static function initBulk(array $preferences, bool $nullable = false): voi
throw new InvalidArgumentException("no preferences provided");
}

foreach ($preferences as $index => &$preferenceData) {
$cleanPreferences = [];

foreach ($preferences as $index => $preferenceData) {

if ($preferenceData instanceof BaseBuilder) {
if ($preferenceData->isStateSet(BaseBuilder::STATE_CREATED)) {
throw new InvalidStateException($preferenceData->getState()
, "The State should not be Created at this point, as its initBulk responsibility");
}
if (!$preferenceData->isStateSet(BaseBuilder::STATE_NULLABLE_SET)) {
$preferenceData->nullable($nullable);
}

$preferenceData->updateOrCreate();
continue;
}

if (empty($preferenceData['cast'])) {
$preferenceData['cast'] = Cast::STRING;
}
Expand Down Expand Up @@ -177,7 +197,7 @@ public static function initBulk(array $preferences, bool $nullable = false): voi
$preferenceData['cast'] = serialize($preferenceData['cast']);

// Ensure Defaults
$preferenceData = array_merge([
$preferenceData = array_merge([
'group' => 'general',
'default_value' => null,
'allowed_values' => null,
Expand All @@ -186,9 +206,10 @@ public static function initBulk(array $preferences, bool $nullable = false): voi
'rule' => null,
'nullable' => false,
], $preferenceData);
$cleanPreferences[] = $preferenceData;
}

Preference::upsert($preferences, ['name', 'group']);
Preference::upsert($cleanPreferences, ['name', 'group']);
}

/**
Expand All @@ -203,6 +224,7 @@ public static function initBulk(array $preferences, bool $nullable = false): voi
* @return int Returns the number of deleted preferences.
*
* @throws InvalidArgumentException if the preferences array is empty or if any preference lacks a required
* @throws InvalidStateException
* 'name' field, or if the 'name' field does not implement PreferenceGroup.
*/
public static function deleteBulk(array $preferences): int
Expand All @@ -213,6 +235,18 @@ public static function deleteBulk(array $preferences): int
$query = Preference::query();

foreach ($preferences as $index => $preferenceData) {


if ($preferenceData instanceof BaseBuilder) {
if ($preferenceData->isStateSet(BaseBuilder::STATE_DELETED)) {
throw new InvalidStateException($preferenceData->getState()
, "The State should not be Deleted at this point, as its deleteBulk's responsibility");
}

$preferenceData->delete();
continue;
}

if (empty($preferenceData['name']) || !($preferenceData['name'] instanceof PreferenceGroup)) {
throw new InvalidArgumentException(
sprintf("index: #%s name is required and must implement PreferenceGroup", $index)
Expand Down
89 changes: 88 additions & 1 deletion src/Factory/builders/BaseBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,63 @@
namespace Matteoc99\LaravelPreference\Factory\builders;

use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Validation\ValidationException;
use Matteoc99\LaravelPreference\Contracts\CastableEnum;
use Matteoc99\LaravelPreference\Contracts\PreferenceGroup;
use Matteoc99\LaravelPreference\Contracts\PreferencePolicy;
use Matteoc99\LaravelPreference\Exceptions\InvalidStateException;
use Matteoc99\LaravelPreference\Models\Preference;
use Matteoc99\LaravelPreference\Traits\HasState;
use Matteoc99\LaravelPreference\Utils\SerializeHelper;
use Matteoc99\LaravelPreference\Utils\ValidationHelper;

abstract class BaseBuilder
{
use HasState;

protected Preference $preference;

const STATE_INITIALIZED = 1;
const STATE_CREATED = 2;
const STATE_DELETED = 4;
const STATE_NAME_SET = 8;
const STATE_CAST_SET = 16;
const STATE_POLICY_SET = 32;
const STATE_RULE_SET = 64;
const STATE_DEFAULT_SET = 128;
const STATE_DESCRIPTION_SET = 256;
const STATE_NULLABLE_SET = 512;
const STATE_ALLOWED_VALUES_SET = 1024;

/**
* @throws InvalidStateException
*/
public function __construct(PreferenceGroup $name, CastableEnum $cast)
{
$this->preference = new Preference();

$this->withName($name)->withCast($cast)->nullable(false);
$this->addState(self::STATE_INITIALIZED);

$this->withName($name)->withCast($cast);
}

/**
* @throws InvalidStateException
*/
private function withCast(CastableEnum $cast): static
{
$this->addState(self::STATE_CAST_SET);
$this->preference->cast = $cast;
return $this;
}

/**
* @throws InvalidStateException
*/
private function withName(PreferenceGroup $name): static
{
$this->addState(self::STATE_NAME_SET);

SerializeHelper::conformNameAndGroup($name, $group);

$this->preference->name = $name;
Expand All @@ -37,44 +68,100 @@ private function withName(PreferenceGroup $name): static
}


/**
* @throws InvalidStateException
*/
public function withPolicy(PreferencePolicy $policy): static
{
$this->addState(self::STATE_POLICY_SET);
$this->preference->policy = $policy;
return $this;
}

/**
* @throws InvalidStateException
*/
public function withDefaultValue(mixed $value): static
{
$this->addState(self::STATE_DEFAULT_SET);

$this->preference->default_value = $value;
return $this;
}

/**
* @throws InvalidStateException
*/
public function withDescription(string $description): static
{
$this->addState(self::STATE_DESCRIPTION_SET);

$this->preference->description = $description;
return $this;
}

/**
* @throws InvalidStateException
*/
public function withRule(ValidationRule $rule): static
{
$this->addState(self::STATE_RULE_SET);

$this->preference->rule = $rule;
return $this;
}

/**
* @throws InvalidStateException
*/
public function nullable(bool $nullable = true)
{
$this->addState(self::STATE_NULLABLE_SET);

$this->preference->nullable = $nullable;
return $this;
}


/**
* @deprecated no reason to use this over updateOrCreate, will be removed in v3.x
*/
public function create(): Preference
{
return $this->updateOrCreate();

}

/**
* @throws InvalidStateException
*/
public function delete(): int
{

if (!$this->isStateSet(self::STATE_INITIALIZED)
|| !$this->isStateSet(self::STATE_NAME_SET)) {
throw new InvalidStateException($this->getState(), "Initialize the builder before deleting the preference");
}

$this->addState(self::STATE_DELETED);



return Preference::query()
->where('group', $this->preference->group)
->where('name', $this->preference->name)
->delete();

}

/**
* @throws InvalidStateException
* @throws ValidationException
*/
public function updateOrCreate(): Preference
{
$this->addState(self::STATE_CREATED);

ValidationHelper::validatePreference($this->preference);


Expand Down
6 changes: 6 additions & 0 deletions src/Factory/builders/ObjectPreferenceBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,20 @@

namespace Matteoc99\LaravelPreference\Factory\builders;

use Matteoc99\LaravelPreference\Exceptions\InvalidStateException;
use Matteoc99\LaravelPreference\Utils\ValidationHelper;

class ObjectPreferenceBuilder extends BaseBuilder
{


/**
* @throws InvalidStateException
*/
public function setAllowedClasses(...$classes): static
{
$this->addState(self::STATE_ALLOWED_VALUES_SET);


ValidationHelper::validateAllowedClasses($this->preference->cast, $classes);

Expand Down
4 changes: 4 additions & 0 deletions src/Models/Preference.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ class Preference extends BaseModel
'allowed_values',
];

protected $attributes = [
'nullable' => false,
];

protected $casts = [
'created_at' => 'datetime',
'updated_at' => 'datetime',
Expand Down
Loading

0 comments on commit 6300993

Please sign in to comment.