Cake 4.x
Showing 5 of 32 files from the diff.
Other files ignored by Codecov
phpstan.neon
is new.
.semver
was deleted.
.editorconfig
has changed.
phpunit.xml.dist
has changed.
tests/bootstrap.php
has changed.
tests/Fixture/ArticlesTagsFixture.php
has changed.
src/Model/Behavior/Strategy/StrategyInterface.php
has changed.
.gitignore
has changed.
phpcs.xml
is new.
tests/Fixture/ArticlesFixture.php
has changed.
tests/Fixture/AuthorsFixture.php
has changed.
.sticker.yml
is new.
src/Plugin.php
is new.
VERSION
was deleted.
.github/workflows/ci.yml
is new.
tests/Fixture/CommentsFixture.php
has changed.
.travis.yml
was deleted.
README.md
has changed.
psalm.xml
is new.
tests/Fixture/TagsFixture.php
has changed.
phpstan-baseline.neon
is new.
composer.json
has changed.
.gitattributes
has changed.
@@ -1,10 +1,18 @@
Loading
1 | 1 | <?php |
|
2 | + | declare(strict_types=1); |
|
3 | + | ||
2 | 4 | namespace Muffin\Obfuscate\Model\Behavior\Strategy; |
|
3 | 5 | ||
6 | + | use InvalidArgumentException; |
|
4 | 7 | use Jenssegers\Optimus\Optimus; |
|
5 | 8 | ||
6 | 9 | class OptimusStrategy implements StrategyInterface |
|
7 | 10 | { |
|
11 | + | /** |
|
12 | + | * Obfuscator. |
|
13 | + | * |
|
14 | + | * @var \Jenssegers\Optimus\Optimus |
|
15 | + | */ |
|
8 | 16 | protected $_optimus; |
|
9 | 17 | ||
10 | 18 | /** |
@@ -14,30 +22,32 @@
Loading
14 | 22 | * @param int $inverse Inverse number. |
|
15 | 23 | * @param int $random Random number. |
|
16 | 24 | */ |
|
17 | - | public function __construct($prime, $inverse, $random) |
|
25 | + | public function __construct(int $prime, int $inverse, int $random) |
|
18 | 26 | { |
|
19 | 27 | $this->_optimus = new Optimus($prime, $inverse, $random); |
|
20 | 28 | } |
|
21 | 29 | ||
22 | 30 | /** |
|
23 | - | * {@inheritdoc} |
|
24 | - | * |
|
25 | - | * @param string $str String to obfuscate. |
|
26 | - | * @return int |
|
31 | + | * @inheritDoc |
|
27 | 32 | */ |
|
28 | - | public function obfuscate($str) |
|
33 | + | public function obfuscate($str): string |
|
29 | 34 | { |
|
30 | - | return $this->_optimus->encode($str); |
|
35 | + | if (!is_numeric($str)) { |
|
36 | + | throw new InvalidArgumentException('Argument should be an integer'); |
|
37 | + | } |
|
38 | + | ||
39 | + | return (string)$this->_optimus->encode((int)$str); |
|
31 | 40 | } |
|
32 | 41 | ||
33 | 42 | /** |
|
34 | - | * {@inheritdoc} |
|
35 | - | * |
|
36 | - | * @param string $str String to elucidate. |
|
37 | - | * @return int |
|
43 | + | * @inheritDoc |
|
38 | 44 | */ |
|
39 | - | public function elucidate($str) |
|
45 | + | public function elucidate($str): int |
|
40 | 46 | { |
|
41 | - | return $this->_optimus->decode($str); |
|
47 | + | if (!is_numeric($str)) { |
|
48 | + | throw new InvalidArgumentException('Argument should be an integer'); |
|
49 | + | } |
|
50 | + | ||
51 | + | return $this->_optimus->decode((int)$str); |
|
42 | 52 | } |
|
43 | 53 | } |
@@ -1,15 +1,15 @@
Loading
1 | 1 | <?php |
|
2 | + | declare(strict_types=1); |
|
3 | + | ||
2 | 4 | namespace Muffin\Obfuscate\Model\Behavior\Strategy; |
|
3 | 5 | ||
4 | 6 | use Cake\ORM\Table; |
|
5 | 7 | ||
6 | 8 | /** |
|
7 | 9 | * Class UuidStrategy |
|
8 | - | * |
|
9 | 10 | */ |
|
10 | 11 | class UuidStrategy implements StrategyInterface |
|
11 | 12 | { |
|
12 | - | ||
13 | 13 | /** |
|
14 | 14 | * UUID field to use. |
|
15 | 15 | * |
@@ -20,30 +20,28 @@
Loading
20 | 20 | /** |
|
21 | 21 | * Table using this strategy. |
|
22 | 22 | * |
|
23 | - | * @var Table |
|
23 | + | * @var \Cake\ORM\Table |
|
24 | 24 | */ |
|
25 | 25 | protected $_table; |
|
26 | 26 | ||
27 | 27 | /** |
|
28 | 28 | * Constructor. |
|
29 | 29 | * |
|
30 | - | * @param Table $table Instance of the table using the strategy. |
|
30 | + | * @param \Cake\ORM\Table $table Instance of the table using the strategy. |
|
31 | 31 | * @param string $field Name of the UUID field on the table. |
|
32 | 32 | */ |
|
33 | - | public function __construct($table, $field = 'uuid') |
|
33 | + | public function __construct(Table $table, string $field = 'uuid') |
|
34 | 34 | { |
|
35 | 35 | $this->_table = $table; |
|
36 | 36 | $this->_field = $field; |
|
37 | 37 | } |
|
38 | 38 | ||
39 | 39 | /** |
|
40 | - | * {@inheritdoc} |
|
41 | - | * |
|
42 | - | * @param string $str String to obfuscate. |
|
43 | - | * @return string |
|
40 | + | * @inheritDoc |
|
44 | 41 | */ |
|
45 | - | public function obfuscate($str) |
|
42 | + | public function obfuscate($str): string |
|
46 | 43 | { |
|
44 | + | /** @psalm-suppress InvalidArrayOffset */ |
|
47 | 45 | $record = $this->_table |
|
48 | 46 | ->find() |
|
49 | 47 | ->where([$this->_table->getPrimaryKey() => $str]) |
@@ -54,12 +52,9 @@
Loading
54 | 52 | } |
|
55 | 53 | ||
56 | 54 | /** |
|
57 | - | * {@inheritdoc} |
|
58 | - | * |
|
59 | - | * @param string $str String to elucidate. |
|
60 | - | * @return string |
|
55 | + | * @inheritDoc |
|
61 | 56 | */ |
|
62 | - | public function elucidate($str) |
|
57 | + | public function elucidate($str): int |
|
63 | 58 | { |
|
64 | 59 | $pk = $this->_table->getPrimaryKey(); |
|
65 | 60 |
@@ -1,15 +1,15 @@
Loading
1 | 1 | <?php |
|
2 | + | declare(strict_types=1); |
|
3 | + | ||
2 | 4 | namespace Muffin\Obfuscate\Model\Behavior\Strategy; |
|
3 | 5 | ||
4 | 6 | use ZackKitzmiller\Tiny; |
|
5 | 7 | ||
6 | 8 | /** |
|
7 | 9 | * Class TinyStrategy |
|
8 | - | * |
|
9 | 10 | */ |
|
10 | 11 | class TinyStrategy implements StrategyInterface |
|
11 | 12 | { |
|
12 | - | ||
13 | 13 | /** |
|
14 | 14 | * Random alpha-numeric set where each character must only be |
|
15 | 15 | * used exactly once. |
@@ -30,30 +30,24 @@
Loading
30 | 30 | * |
|
31 | 31 | * @param string $set Random alpha-numeric set. |
|
32 | 32 | */ |
|
33 | - | public function __construct($set) |
|
33 | + | public function __construct(string $set) |
|
34 | 34 | { |
|
35 | 35 | $this->_set = $set; |
|
36 | 36 | $this->_tiny = new Tiny($set); |
|
37 | 37 | } |
|
38 | 38 | ||
39 | 39 | /** |
|
40 | - | * {@inheritdoc} |
|
41 | - | * |
|
42 | - | * @param string $str String to obfuscate. |
|
43 | - | * @return string |
|
40 | + | * @inheritDoc |
|
44 | 41 | */ |
|
45 | - | public function obfuscate($str) |
|
42 | + | public function obfuscate($str): string |
|
46 | 43 | { |
|
47 | - | return $this->_tiny->to($str); |
|
44 | + | return $this->_tiny->to((string)$str); |
|
48 | 45 | } |
|
49 | 46 | ||
50 | 47 | /** |
|
51 | - | * {@inheritdoc} |
|
52 | - | * |
|
53 | - | * @param string $str String to elucidate. |
|
54 | - | * @return string |
|
48 | + | * @inheritDoc |
|
55 | 49 | */ |
|
56 | - | public function elucidate($str) |
|
50 | + | public function elucidate($str): int |
|
57 | 51 | { |
|
58 | 52 | return $this->_tiny->from($str); |
|
59 | 53 | } |
@@ -1,24 +1,25 @@
Loading
1 | 1 | <?php |
|
2 | + | declare(strict_types=1); |
|
3 | + | ||
2 | 4 | namespace Muffin\Obfuscate\Model\Behavior; |
|
3 | 5 | ||
4 | 6 | use ArrayObject; |
|
5 | - | use Cake\Core\Exception\Exception; |
|
7 | + | use Cake\Database\Expression\ComparisonExpression; |
|
6 | 8 | use Cake\Datasource\EntityInterface; |
|
7 | - | use Cake\Event\Event; |
|
9 | + | use Cake\Event\EventInterface; |
|
8 | 10 | use Cake\ORM\Behavior; |
|
9 | 11 | use Cake\ORM\Query; |
|
10 | - | use Cake\ORM\ResultSet; |
|
12 | + | use InvalidArgumentException; |
|
11 | 13 | use Muffin\Obfuscate\Model\Behavior\Strategy\StrategyInterface; |
|
14 | + | use RuntimeException; |
|
12 | 15 | ||
13 | 16 | /** |
|
14 | 17 | * Class ObfuscateBehavior |
|
15 | - | * |
|
16 | 18 | */ |
|
17 | 19 | class ObfuscateBehavior extends Behavior |
|
18 | 20 | { |
|
19 | - | ||
20 | 21 | /** |
|
21 | - | * {@inheritdoc} |
|
22 | + | * @inheritDoc |
|
22 | 23 | */ |
|
23 | 24 | protected $_defaultConfig = [ |
|
24 | 25 | 'strategy' => null, |
@@ -38,7 +39,7 @@
Loading
38 | 39 | * @param array $config Behavior's configuration. |
|
39 | 40 | * @return void |
|
40 | 41 | */ |
|
41 | - | public function initialize(array $config) |
|
42 | + | public function initialize(array $config): void |
|
42 | 43 | { |
|
43 | 44 | $this->verifyConfig(); |
|
44 | 45 | } |
@@ -48,16 +49,16 @@
Loading
48 | 49 | * |
|
49 | 50 | * @return void |
|
50 | 51 | */ |
|
51 | - | public function verifyConfig() |
|
52 | + | public function verifyConfig(): void |
|
52 | 53 | { |
|
53 | 54 | $strategy = $this->getConfig('strategy'); |
|
54 | - | if (!$strategy) { |
|
55 | - | throw new Exception('Missing required obfuscation strategy.'); |
|
55 | + | if (empty($strategy)) { |
|
56 | + | throw new InvalidArgumentException('Missing required obfuscation strategy.'); |
|
56 | 57 | } |
|
57 | 58 | ||
58 | 59 | if (!($strategy instanceof StrategyInterface)) { |
|
59 | - | throw new Exception( |
|
60 | - | 'Strategy must implement the `Muffin\Obfuscate\Model\Behavior\Strategy\StrategyInterface`' |
|
60 | + | throw new InvalidArgumentException( |
|
61 | + | 'Strategy must implement ' . StrategyInterface::class |
|
61 | 62 | ); |
|
62 | 63 | } |
|
63 | 64 |
@@ -67,14 +68,17 @@
Loading
67 | 68 | /** |
|
68 | 69 | * Callback to obfuscate the record(s)' primary key returned after a save operation. |
|
69 | 70 | * |
|
70 | - | * @param \Cake\ORM\Behavior\Event $event Event. |
|
71 | - | * @param \Cake\ORM\Behavior\EntityInterface $entity Entity. |
|
71 | + | * @param \Cake\Event\EventInterface $event EventInterface. |
|
72 | + | * @param \Cake\Datasource\EntityInterface $entity Entity. |
|
72 | 73 | * @param \ArrayObject $options Options. |
|
73 | 74 | * @return void |
|
74 | 75 | */ |
|
75 | - | public function afterSave(Event $event, EntityInterface $entity, ArrayObject $options) |
|
76 | + | public function afterSave(EventInterface $event, EntityInterface $entity, ArrayObject $options) |
|
76 | 77 | { |
|
77 | 78 | $pk = $this->_table->getPrimaryKey(); |
|
79 | + | if (is_array($pk)) { |
|
80 | + | throw new RuntimeException('Composite primary keys are not supported.'); |
|
81 | + | } |
|
78 | 82 | $entity->set($pk, $this->obfuscate($entity->{$pk})); |
|
79 | 83 | $entity->setDirty($pk, false); |
|
80 | 84 | } |
@@ -82,13 +86,13 @@
Loading
82 | 86 | /** |
|
83 | 87 | * Callback to set the `obfuscated` finder on all associations. |
|
84 | 88 | * |
|
85 | - | * @param \Cake\ORM\Behavior\Event $event Event. |
|
89 | + | * @param \Cake\Event\EventInterface $event EventInterface. |
|
86 | 90 | * @param \Cake\ORM\Query $query Query. |
|
87 | 91 | * @param \ArrayObject $options Options. |
|
88 | 92 | * @param bool $primary True if this is the primary table. |
|
89 | 93 | * @return void |
|
90 | 94 | */ |
|
91 | - | public function beforeFind(Event $event, Query $query, ArrayObject $options, $primary) |
|
95 | + | public function beforeFind(EventInterface $event, Query $query, ArrayObject $options, bool $primary) |
|
92 | 96 | { |
|
93 | 97 | if (empty($options['obfuscate']) || !$primary) { |
|
94 | 98 | return; |
@@ -96,8 +100,12 @@
Loading
96 | 100 | ||
97 | 101 | $query->traverseExpressions(function ($expression) { |
|
98 | 102 | $pk = $this->_table->getPrimaryKey(); |
|
103 | + | if (is_array($pk)) { |
|
104 | + | throw new RuntimeException('Composite primary keys are not supported.'); |
|
105 | + | } |
|
106 | + | ||
99 | 107 | if ( |
|
100 | - | method_exists($expression, 'getField') |
|
108 | + | $expression instanceof ComparisonExpression |
|
101 | 109 | && in_array($expression->getField(), [$pk, $this->_table->aliasField($pk)]) |
|
102 | 110 | ) { |
|
103 | 111 | $expression->setValue($this->elucidate($expression->getValue())); |
@@ -151,10 +159,10 @@
Loading
151 | 159 | /** |
|
152 | 160 | * Proxy to the obfuscating strategy's `obfuscate()`. |
|
153 | 161 | * |
|
154 | - | * @param string $str String to obfuscate. |
|
162 | + | * @param string|int $str String to obfuscate. |
|
155 | 163 | * @return string |
|
156 | 164 | */ |
|
157 | - | public function obfuscate($str) |
|
165 | + | public function obfuscate($str): string |
|
158 | 166 | { |
|
159 | 167 | return $this->strategy()->obfuscate($str); |
|
160 | 168 | } |
@@ -162,10 +170,10 @@
Loading
162 | 170 | /** |
|
163 | 171 | * Proxy to the obfuscating strategy's `elucidate()`. |
|
164 | 172 | * |
|
165 | - | * @param string $str String to elucidate. |
|
166 | - | * @return string |
|
173 | + | * @param int|string $str String to elucidate. |
|
174 | + | * @return int |
|
167 | 175 | */ |
|
168 | - | public function elucidate($str) |
|
176 | + | public function elucidate($str): int |
|
169 | 177 | { |
|
170 | 178 | return $this->strategy()->elucidate($str); |
|
171 | 179 | } |
@@ -173,9 +181,9 @@
Loading
173 | 181 | /** |
|
174 | 182 | * Get the configured strategy. |
|
175 | 183 | * |
|
176 | - | * @return \Muffin\Obfuscate\Model\Behavior\ObfuscateStrategy\StrategyInterface |
|
184 | + | * @return \Muffin\Obfuscate\Model\Behavior\Strategy\StrategyInterface |
|
177 | 185 | */ |
|
178 | - | public function strategy() |
|
186 | + | public function strategy(): StrategyInterface |
|
179 | 187 | { |
|
180 | 188 | return $this->getConfig('strategy'); |
|
181 | 189 | } |
@@ -1,39 +1,22 @@
Loading
1 | 1 | <?php |
|
2 | + | declare(strict_types=1); |
|
3 | + | ||
2 | 4 | namespace Muffin\Obfuscate\Model\Behavior\Strategy; |
|
3 | 5 | ||
4 | 6 | use Cake\Core\Configure; |
|
5 | 7 | use Hashids\Hashids; |
|
6 | 8 | ||
7 | 9 | /** |
|
8 | - | * Class DefaultStrategy |
|
9 | - | * |
|
10 | + | * Class HashidStrategy |
|
10 | 11 | */ |
|
11 | 12 | class HashidStrategy implements StrategyInterface |
|
12 | 13 | { |
|
13 | - | ||
14 | - | protected $_hashid; |
|
15 | - | ||
16 | - | /** |
|
17 | - | * Random alpha-numeric set where each character must only be |
|
18 | - | * used exactly once. |
|
19 | - | * |
|
20 | - | * @var string |
|
21 | - | */ |
|
22 | - | protected $_salt; |
|
23 | - | ||
24 | 14 | /** |
|
25 | - | * The minimum hash length. |
|
15 | + | * Obfuscator. |
|
26 | 16 | * |
|
27 | - | * @var int |
|
17 | + | * @var \Hashids\Hashids |
|
28 | 18 | */ |
|
29 | - | protected $_minLength; |
|
30 | - | ||
31 | - | /** |
|
32 | - | * Custom alphabet to use. |
|
33 | - | * |
|
34 | - | * @var string |
|
35 | - | */ |
|
36 | - | protected $_alphabet; |
|
19 | + | protected $_hashid; |
|
37 | 20 | ||
38 | 21 | /** |
|
39 | 22 | * Constructor. |
@@ -43,7 +26,7 @@
Loading
43 | 26 | * @param string $alphabet Custom alphabet to use. |
|
44 | 27 | * @throws \Exception |
|
45 | 28 | */ |
|
46 | - | public function __construct($salt = null, $minLength = 0, $alphabet = null) |
|
29 | + | public function __construct(?string $salt = null, int $minLength = 0, ?string $alphabet = null) |
|
47 | 30 | { |
|
48 | 31 | if ($salt === null) { |
|
49 | 32 | $salt = Configure::read('Obfuscate.salt'); |
@@ -51,9 +34,6 @@
Loading
51 | 34 | if (empty($salt)) { |
|
52 | 35 | throw new \Exception('Missing salt for Hashid strategy'); |
|
53 | 36 | } |
|
54 | - | $this->_salt = $salt; |
|
55 | - | $this->_minLength = $minLength; |
|
56 | - | $this->_alphabet = $alphabet; |
|
57 | 37 | ||
58 | 38 | if ($alphabet === null) { |
|
59 | 39 | $this->_hashid = new Hashids($salt, $minLength); |
@@ -63,24 +43,18 @@
Loading
63 | 43 | } |
|
64 | 44 | ||
65 | 45 | /** |
|
66 | - | * {@inheritdoc} |
|
67 | - | * |
|
68 | - | * @param string $str String to obfuscate. |
|
69 | - | * @return string |
|
46 | + | * @inheritDoc |
|
70 | 47 | */ |
|
71 | - | public function obfuscate($str) |
|
48 | + | public function obfuscate($str): string |
|
72 | 49 | { |
|
73 | - | return $this->_hashid->encode($str); |
|
50 | + | return $this->_hashid->encode((string)$str); |
|
74 | 51 | } |
|
75 | 52 | ||
76 | 53 | /** |
|
77 | - | * {@inheritdoc} |
|
78 | - | * |
|
79 | - | * @param string $str String to elucidate. |
|
80 | - | * @return string |
|
54 | + | * @inheritDoc |
|
81 | 55 | */ |
|
82 | - | public function elucidate($str) |
|
56 | + | public function elucidate($str): int |
|
83 | 57 | { |
|
84 | - | return current($this->_hashid->decode($str)); |
|
58 | + | return current($this->_hashid->decode((string)$str)); |
|
85 | 59 | } |
|
86 | 60 | } |
Files | Complexity | Coverage |
---|---|---|
src/Model/Behavior | 39 | 93.55% |
Project Totals (5 files) | 39 | 93.55% |
520306512
Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file.
The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files.
The size and color of each slice is representing the number of statements and the coverage, respectively.