Skip to content

Commit d51025f

Browse files
committed
Add base abstract operation class
1 parent d65cf4c commit d51025f

File tree

1 file changed

+96
-0
lines changed

1 file changed

+96
-0
lines changed

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+
}

0 commit comments

Comments
 (0)