Skip to content

Commit 339dc21

Browse files
committed
Merge branch 'release/1.0.0-beta'
2 parents e8cd7bb + d65b6fd commit 339dc21

File tree

8 files changed

+260
-5
lines changed

8 files changed

+260
-5
lines changed

CHANGELOG.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [1.0.0-beta] - 2020-03-03
11+
### Updated
12+
- Upgraded Laravel support to include 7.x
13+
14+
### Added
15+
- Add a user password validation rule
16+
- Base abstract operation class
17+
- Added castable for CarbonInterval and UUID
18+
19+
### Changed
20+
- Moved the operations contract to a more sensible namespace
21+
1022
## [1.0.2-alpha] - 2020-01-19
1123
### Changed
1224
- Disabled the query grammar override for now
@@ -18,7 +30,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1830
## [1.0.0-alpha] - 2020-01-17
1931
- Initial release
2032

21-
[Unreleased]: https://github.com/sprocketbox/laravel-toolkit/compare/v1.0.2-alpha...develop
33+
[Unreleased]: https://github.com/sprocketbox/laravel-toolkit/compare/v1.0.0-beta...develop
34+
[1.0.0-beta]: https://github.com/sprocketbox/laravel-toolkit/compare/v1.0.1-alpha...v1.0.0-beta
2235
[1.0.2-alpha]: https://github.com/sprocketbox/laravel-toolkit/compare/v1.0.1-alpha...v1.0.2-alpha
2336
[1.0.1-alpha]: https://github.com/sprocketbox/laravel-toolkit/compare/v1.0.0-alpha...v1.0.1-alpha
2437
[1.0.0-alpha]: https://github.com/sprocketbox/laravel-toolkit/releases/tag/v1.0.0-alpha

composer.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@
2626
},
2727
"require": {
2828
"php": "^7.4",
29-
"illuminate/routing": "^6.0",
30-
"illuminate/database": "^6.0",
31-
"illuminate/validation": "^6.0"
29+
"illuminate/routing": "^6.0 || ^7.0",
30+
"illuminate/database": "^6.0 || ^7.0",
31+
"illuminate/validation": "^6.0 || ^7.0"
3232
},
3333
"extra": {
3434
"laravel": {
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
namespace Sprocketbox\Toolkit\Database\Casts;
4+
5+
use Carbon\CarbonInterval;
6+
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
7+
8+
class IntervalCast implements CastsAttributes
9+
{
10+
/**
11+
* @param \Illuminate\Database\Eloquent\Model $model
12+
* @param string $key
13+
* @param mixed $value
14+
* @param array $attributes
15+
*
16+
* @return mixed|void
17+
* @throws \Exception
18+
*/
19+
public function get($model, string $key, $value, array $attributes): CarbonInterval
20+
{
21+
return new CarbonInterval($value);
22+
}
23+
24+
/**
25+
* @param \Illuminate\Database\Eloquent\Model $model
26+
* @param string $key
27+
* @param CarbonInterval $value
28+
* @param array $attributes
29+
*
30+
* @return string
31+
*/
32+
public function set($model, string $key, $value, array $attributes): string
33+
{
34+
return $value->spec();
35+
}
36+
}

src/Database/Casts/UUIDCast.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
namespace Sprocketbox\Toolkit\Database\Casts;
4+
5+
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
6+
use Ramsey\Uuid\Uuid;
7+
use Ramsey\Uuid\UuidInterface;
8+
9+
class UUIDCast implements CastsAttributes
10+
{
11+
/**
12+
* @param \Illuminate\Database\Eloquent\Model $model
13+
* @param string $key
14+
* @param string $value
15+
* @param array $attributes
16+
*
17+
* @return \Ramsey\Uuid\UuidInterface
18+
*/
19+
public function get($model, string $key, $value, array $attributes): UuidInterface
20+
{
21+
return Uuid::fromString($value);
22+
}
23+
24+
/**
25+
* @param \Illuminate\Database\Eloquent\Model $model
26+
* @param string $key
27+
* @param \Ramsey\Uuid\UuidInterface $value
28+
* @param array $attributes
29+
*
30+
* @return string
31+
*/
32+
public function set($model, string $key, $value, array $attributes): string
33+
{
34+
return $value->toString();
35+
}
36+
}

src/Http/Contracts/Operation.php renamed to src/Operations/Contracts/Operation.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22

3-
namespace Sprocketbox\Toolkit\Http\Contracts;
3+
namespace Sprocketbox\Toolkit\Operations\Contracts;
44

55
/**
66
* Interface Operation

src/Operations/Operation.php

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
<?php
2+
3+
namespace Sprocketbox\Toolkit\Operations;
4+
5+
use Illuminate\Container\Container;
6+
use Illuminate\Contracts\Container\BindingResolutionException;
7+
use Illuminate\Support\Str;
8+
use InvalidArgumentException;
9+
10+
abstract class Operation implements Contracts\Operation
11+
{
12+
/**
13+
* @return static
14+
*/
15+
public static function start(): self
16+
{
17+
try {
18+
return Container::getInstance()->make(__CLASS__, func_get_args());
19+
} catch (BindingResolutionException $e) {
20+
report($e);
21+
}
22+
}
23+
24+
/**
25+
* Handle any calls to setters.
26+
*
27+
* Match the called setter name to a property name.
28+
*
29+
* @param $name
30+
* @param $arguments
31+
*
32+
* @return self
33+
*/
34+
public function __call($name, $arguments): self
35+
{
36+
// Error if there are no arguments provided
37+
if (count($arguments) === 0) {
38+
throw new InvalidArgumentException('Must provide a property value');
39+
}
40+
41+
// If the property doesn't exist we're going to want to error
42+
// There's no nice way to check if a property is actually accessible without using reflection
43+
// which is overkill here, so we're going to let it error naturally
44+
if (! property_exists($this, $name)) {
45+
throw new InvalidArgumentException('Invalid operation property');
46+
}
47+
48+
$this->$name = count($arguments) === 1 ? $arguments[0] : $arguments;
49+
50+
return $this;
51+
}
52+
53+
/**
54+
* Get an array of attributes using class properties, optionally skipping null entries.
55+
*
56+
* @param array<string> $properties An array of properties to snake case and use as array keys
57+
* @param bool|array<string> $skipIfNull True to skip null, false to not, or an array of properties to skip if null
58+
*
59+
* @return array
60+
*/
61+
protected function getAttributes(array $properties, $skipIfNull = false): array
62+
{
63+
$attributes = [];
64+
65+
foreach ($properties as $property) {
66+
$property = Str::camel($property);
67+
68+
if (! property_exists($this, $property)) {
69+
throw new InvalidArgumentException(sprintf('Property %s on %s does not exist', self::class, $property));
70+
}
71+
72+
if ($this->shouldSkip($property, $skipIfNull)) {
73+
continue;
74+
}
75+
76+
/** @noinspection NullCoalescingOperatorCanBeUsedInspection */
77+
$attributes[Str::snake($property)] = isset($this->{$property}) ? $this->{$property} : null;
78+
}
79+
80+
return $attributes;
81+
}
82+
83+
/**
84+
* Check if the property should be skipped.
85+
*
86+
* @param string $property
87+
* @param bool|array<string> $skipIfNull
88+
*
89+
* @return bool
90+
*/
91+
private function shouldSkip(string $property, $skipIfNull = false): bool
92+
{
93+
return (! isset($this->{$property}) && $this->{$property} === null)
94+
&& ($skipIfNull === true || (is_array($skipIfNull) && in_array($property, $skipIfNull, true)));
95+
}
96+
}

src/Validators/Rules/Rules.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
namespace Sprocketbox\Toolkit\Validators\Rules;
4+
5+
use Illuminate\Database\Eloquent\Model;
6+
use Illuminate\Validation\Rules\Unique;
7+
8+
class Rules
9+
{
10+
/**
11+
* @param \Illuminate\Database\Eloquent\Model|string $model
12+
* @param string|null $column
13+
*
14+
* @return \Illuminate\Validation\Rules\Unique
15+
*/
16+
public static function unique($model, ?string $column = null): Unique
17+
{
18+
$instance = $model instanceof Model ? $model : new $model;
19+
$rule = new Unique($instance->getTable(), $column ?? 'NULL');
20+
21+
if ($model instanceof Model) {
22+
$rule->ignoreModel($model);
23+
}
24+
25+
return $rule;
26+
}
27+
28+
public static function password(?string $guard = null): UserPassword
29+
{
30+
return new UserPassword($guard);
31+
}
32+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
namespace Sprocketbox\Toolkit\Validators\Rules;
4+
5+
use Illuminate\Contracts\Validation\Rule;
6+
use Illuminate\Support\Facades\Auth;
7+
use Illuminate\Support\Facades\Hash;
8+
9+
class UserPassword implements Rule
10+
{
11+
/**
12+
* @var string|null
13+
*/
14+
protected ?string $guard;
15+
16+
public function __construct(?string $guard = null)
17+
{
18+
$this->guard = $guard;
19+
}
20+
21+
/**
22+
* @inheritDoc
23+
*/
24+
public function passes($attribute, $value)
25+
{
26+
$user = Auth::guard($this->guard)->user();
27+
28+
if ($user !== null) {
29+
return Hash::check($value, $user->getAuthPassword());
30+
}
31+
32+
return false;
33+
}
34+
35+
/**
36+
* @inheritDoc
37+
*/
38+
public function message()
39+
{
40+
return 'validation.user_password';
41+
}
42+
}

0 commit comments

Comments
 (0)