Skip to content

Commit 6300993

Browse files
authored
Merge pull request #11 from matteoc99/feature/readme
Feature/readme
2 parents b7c0814 + 0c20863 commit 6300993

17 files changed

+515
-57
lines changed

README.md

+74-43
Large diffs are not rendered by default.

src/Contracts/PreferenceableModel.php

+12-1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,17 @@ public function getPreferences(string $group = null): Collection;
3131
*/
3232
public function removePreference(PreferenceGroup $name): int;
3333

34+
35+
/**
36+
* Reset the model to its original state
37+
* Remove all user's preferences.
38+
*
39+
*
40+
* @return int Number of deleted records.
41+
* @throws AuthorizationException
42+
*/
43+
public function removeAllPreferences(): int;
44+
3445
/**
3546
* Set a preference value, handling validation and persistence.
3647
*
@@ -54,7 +65,7 @@ public function setPreference(PreferenceGroup $name, mixed $value): void;
5465
public function getPreference(PreferenceGroup $name, mixed $default = null): mixed;
5566

5667
/**
57-
* Get a user's preference value or default if not set with no casting
68+
* Get a user's preference value or default if not set, transformed for data transfer
5869
*
5970
* @param PreferenceGroup|Preference $preference
6071
* @param string|null $default Default value if preference not set.

src/Enums/PolicyAction.php

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
enum PolicyAction
66
{
7+
case DELETE_ALL;
78
case INDEX;
89
case GET;
910
case UPDATE;
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
namespace Matteoc99\LaravelPreference\Exceptions;
4+
5+
use Exception;
6+
use Throwable;
7+
8+
class InvalidStateException extends Exception
9+
{
10+
11+
private int $state;
12+
13+
public function __construct($state, string $message, ?Throwable $previous = null)
14+
{
15+
$this->state = $state;
16+
parent::__construct($message, 0, $previous);
17+
}
18+
19+
/**
20+
* @return int
21+
*/
22+
public function getState(): int
23+
{
24+
return $this->state;
25+
}
26+
}

src/Factory/PreferenceBuilder.php

+40-6
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
use Matteoc99\LaravelPreference\Contracts\CastableEnum;
1010
use Matteoc99\LaravelPreference\Contracts\PreferenceGroup;
1111
use Matteoc99\LaravelPreference\Enums\Cast;
12+
use Matteoc99\LaravelPreference\Exceptions\InvalidStateException;
13+
use Matteoc99\LaravelPreference\Factory\builders\BaseBuilder;
1214
use Matteoc99\LaravelPreference\Factory\builders\ObjectPreferenceBuilder;
1315
use Matteoc99\LaravelPreference\Factory\builders\PrimitivePreferenceBuilder;
1416
use Matteoc99\LaravelPreference\Models\Preference;
@@ -28,6 +30,7 @@ class PreferenceBuilder
2830
*
2931
* @return void Creates the preference and commits it to the database.
3032
*
33+
* @throws InvalidStateException
3134
* @example
3235
* ```
3336
* PreferenceBuilder::buildString(UserPreference::TEST, "default");
@@ -36,7 +39,7 @@ class PreferenceBuilder
3639
*/
3740
public static function buildString(PreferenceGroup $name, string $default = null): void
3841
{
39-
self::init($name)->nullable()->withDefaultValue(null)->create();
42+
self::init($name)->nullable()->withDefaultValue($default)->create();
4043
}
4144

4245
/**
@@ -49,6 +52,7 @@ public static function buildString(PreferenceGroup $name, string $default = null
4952
*
5053
* @return void Creates the preference and commits it to the database.
5154
*
55+
* @throws InvalidStateException
5256
* @example
5357
* ```
5458
* PreferenceBuilder::buildArray(new SettingsPreferenceGroup(), ["item1", "item2"]);
@@ -58,7 +62,7 @@ public static function buildString(PreferenceGroup $name, string $default = null
5862
*/
5963
public static function buildArray(PreferenceGroup $name, array $default = null): void
6064
{
61-
self::init($name, Cast::ARRAY)->nullable()->withDefaultValue(null)->create();
65+
self::init($name, Cast::ARRAY)->nullable()->withDefaultValue($default)->create();
6266
}
6367

6468

@@ -99,7 +103,7 @@ public static function init(PreferenceGroup $name, CastableEnum $cast = Cast::ST
99103
*
100104
* @param PreferenceGroup $name
101105
*
102-
* @return int,
106+
* @return int
103107
*/
104108
public static function delete(PreferenceGroup $name): int
105109
{
@@ -148,7 +152,23 @@ public static function initBulk(array $preferences, bool $nullable = false): voi
148152
throw new InvalidArgumentException("no preferences provided");
149153
}
150154

151-
foreach ($preferences as $index => &$preferenceData) {
155+
$cleanPreferences = [];
156+
157+
foreach ($preferences as $index => $preferenceData) {
158+
159+
if ($preferenceData instanceof BaseBuilder) {
160+
if ($preferenceData->isStateSet(BaseBuilder::STATE_CREATED)) {
161+
throw new InvalidStateException($preferenceData->getState()
162+
, "The State should not be Created at this point, as its initBulk responsibility");
163+
}
164+
if (!$preferenceData->isStateSet(BaseBuilder::STATE_NULLABLE_SET)) {
165+
$preferenceData->nullable($nullable);
166+
}
167+
168+
$preferenceData->updateOrCreate();
169+
continue;
170+
}
171+
152172
if (empty($preferenceData['cast'])) {
153173
$preferenceData['cast'] = Cast::STRING;
154174
}
@@ -177,7 +197,7 @@ public static function initBulk(array $preferences, bool $nullable = false): voi
177197
$preferenceData['cast'] = serialize($preferenceData['cast']);
178198

179199
// Ensure Defaults
180-
$preferenceData = array_merge([
200+
$preferenceData = array_merge([
181201
'group' => 'general',
182202
'default_value' => null,
183203
'allowed_values' => null,
@@ -186,9 +206,10 @@ public static function initBulk(array $preferences, bool $nullable = false): voi
186206
'rule' => null,
187207
'nullable' => false,
188208
], $preferenceData);
209+
$cleanPreferences[] = $preferenceData;
189210
}
190211

191-
Preference::upsert($preferences, ['name', 'group']);
212+
Preference::upsert($cleanPreferences, ['name', 'group']);
192213
}
193214

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

215237
foreach ($preferences as $index => $preferenceData) {
238+
239+
240+
if ($preferenceData instanceof BaseBuilder) {
241+
if ($preferenceData->isStateSet(BaseBuilder::STATE_DELETED)) {
242+
throw new InvalidStateException($preferenceData->getState()
243+
, "The State should not be Deleted at this point, as its deleteBulk's responsibility");
244+
}
245+
246+
$preferenceData->delete();
247+
continue;
248+
}
249+
216250
if (empty($preferenceData['name']) || !($preferenceData['name'] instanceof PreferenceGroup)) {
217251
throw new InvalidArgumentException(
218252
sprintf("index: #%s name is required and must implement PreferenceGroup", $index)

src/Factory/builders/BaseBuilder.php

+88-1
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,63 @@
33
namespace Matteoc99\LaravelPreference\Factory\builders;
44

55
use Illuminate\Contracts\Validation\ValidationRule;
6+
use Illuminate\Validation\ValidationException;
67
use Matteoc99\LaravelPreference\Contracts\CastableEnum;
78
use Matteoc99\LaravelPreference\Contracts\PreferenceGroup;
89
use Matteoc99\LaravelPreference\Contracts\PreferencePolicy;
10+
use Matteoc99\LaravelPreference\Exceptions\InvalidStateException;
911
use Matteoc99\LaravelPreference\Models\Preference;
12+
use Matteoc99\LaravelPreference\Traits\HasState;
1013
use Matteoc99\LaravelPreference\Utils\SerializeHelper;
1114
use Matteoc99\LaravelPreference\Utils\ValidationHelper;
1215

1316
abstract class BaseBuilder
1417
{
18+
use HasState;
19+
1520
protected Preference $preference;
1621

22+
const STATE_INITIALIZED = 1;
23+
const STATE_CREATED = 2;
24+
const STATE_DELETED = 4;
25+
const STATE_NAME_SET = 8;
26+
const STATE_CAST_SET = 16;
27+
const STATE_POLICY_SET = 32;
28+
const STATE_RULE_SET = 64;
29+
const STATE_DEFAULT_SET = 128;
30+
const STATE_DESCRIPTION_SET = 256;
31+
const STATE_NULLABLE_SET = 512;
32+
const STATE_ALLOWED_VALUES_SET = 1024;
33+
34+
/**
35+
* @throws InvalidStateException
36+
*/
1737
public function __construct(PreferenceGroup $name, CastableEnum $cast)
1838
{
1939
$this->preference = new Preference();
2040

21-
$this->withName($name)->withCast($cast)->nullable(false);
41+
$this->addState(self::STATE_INITIALIZED);
42+
43+
$this->withName($name)->withCast($cast);
2244
}
2345

46+
/**
47+
* @throws InvalidStateException
48+
*/
2449
private function withCast(CastableEnum $cast): static
2550
{
51+
$this->addState(self::STATE_CAST_SET);
2652
$this->preference->cast = $cast;
2753
return $this;
2854
}
2955

56+
/**
57+
* @throws InvalidStateException
58+
*/
3059
private function withName(PreferenceGroup $name): static
3160
{
61+
$this->addState(self::STATE_NAME_SET);
62+
3263
SerializeHelper::conformNameAndGroup($name, $group);
3364

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

3970

71+
/**
72+
* @throws InvalidStateException
73+
*/
4074
public function withPolicy(PreferencePolicy $policy): static
4175
{
76+
$this->addState(self::STATE_POLICY_SET);
4277
$this->preference->policy = $policy;
4378
return $this;
4479
}
4580

81+
/**
82+
* @throws InvalidStateException
83+
*/
4684
public function withDefaultValue(mixed $value): static
4785
{
86+
$this->addState(self::STATE_DEFAULT_SET);
87+
4888
$this->preference->default_value = $value;
4989
return $this;
5090
}
5191

92+
/**
93+
* @throws InvalidStateException
94+
*/
5295
public function withDescription(string $description): static
5396
{
97+
$this->addState(self::STATE_DESCRIPTION_SET);
98+
5499
$this->preference->description = $description;
55100
return $this;
56101
}
57102

103+
/**
104+
* @throws InvalidStateException
105+
*/
58106
public function withRule(ValidationRule $rule): static
59107
{
108+
$this->addState(self::STATE_RULE_SET);
109+
60110
$this->preference->rule = $rule;
61111
return $this;
62112
}
63113

114+
/**
115+
* @throws InvalidStateException
116+
*/
64117
public function nullable(bool $nullable = true)
65118
{
119+
$this->addState(self::STATE_NULLABLE_SET);
120+
66121
$this->preference->nullable = $nullable;
67122
return $this;
68123
}
69124

70125

126+
/**
127+
* @deprecated no reason to use this over updateOrCreate, will be removed in v3.x
128+
*/
71129
public function create(): Preference
72130
{
73131
return $this->updateOrCreate();
132+
133+
}
134+
135+
/**
136+
* @throws InvalidStateException
137+
*/
138+
public function delete(): int
139+
{
140+
141+
if (!$this->isStateSet(self::STATE_INITIALIZED)
142+
|| !$this->isStateSet(self::STATE_NAME_SET)) {
143+
throw new InvalidStateException($this->getState(), "Initialize the builder before deleting the preference");
144+
}
145+
146+
$this->addState(self::STATE_DELETED);
147+
148+
149+
150+
return Preference::query()
151+
->where('group', $this->preference->group)
152+
->where('name', $this->preference->name)
153+
->delete();
154+
74155
}
75156

157+
/**
158+
* @throws InvalidStateException
159+
* @throws ValidationException
160+
*/
76161
public function updateOrCreate(): Preference
77162
{
163+
$this->addState(self::STATE_CREATED);
164+
78165
ValidationHelper::validatePreference($this->preference);
79166

80167

src/Factory/builders/ObjectPreferenceBuilder.php

+6
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,20 @@
22

33
namespace Matteoc99\LaravelPreference\Factory\builders;
44

5+
use Matteoc99\LaravelPreference\Exceptions\InvalidStateException;
56
use Matteoc99\LaravelPreference\Utils\ValidationHelper;
67

78
class ObjectPreferenceBuilder extends BaseBuilder
89
{
910

1011

12+
/**
13+
* @throws InvalidStateException
14+
*/
1115
public function setAllowedClasses(...$classes): static
1216
{
17+
$this->addState(self::STATE_ALLOWED_VALUES_SET);
18+
1319

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

src/Models/Preference.php

+4
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ class Preference extends BaseModel
4444
'allowed_values',
4545
];
4646

47+
protected $attributes = [
48+
'nullable' => false,
49+
];
50+
4751
protected $casts = [
4852
'created_at' => 'datetime',
4953
'updated_at' => 'datetime',

0 commit comments

Comments
 (0)