Matthias Lantsch(11 months ago)
Rework collection classes. Remove unused methods / classes
Browse Filesdiff --git a/d97637caf43966a4293e98526aa8804762fe43a2 b/0bfa773fc80a214396f5c4441d3fc97ea1215cda
index d97637c..0bfa773 100644
--- a/d97637caf43966a4293e98526aa8804762fe43a2
+++ b/0bfa773fc80a214396f5c4441d3fc97ea1215cda
@@ -5,6 +5,7 @@
reportMixedIssues="false"
findUnusedPsalmSuppress="true"
findUnusedBaselineEntry="true"
+ findUnusedCode="false"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
diff --git a/ceda524845255f96824216ccf0e678a49e59f53d b/69958a66e10c26fd6ae1912e172cf3762a78fb6b
index ceda524..69958a6 100644
--- a/ceda524845255f96824216ccf0e678a49e59f53d
+++ b/69958a66e10c26fd6ae1912e172cf3762a78fb6b
@@ -9,24 +9,26 @@
namespace holonet\common\collection;
-use Countable;
use ArrayAccess;
use ArrayIterator;
+use Countable;
+use Iterator;
use IteratorAggregate;
-use holonet\common\ComparableInterface;
+use OutOfBoundsException;
/**
* The ChangeAwareCollection is used as a wrapper around an array
* it keeps track internally on how it's data changed.
+ * @psalm-suppress MissingTemplateParam
*/
-class ChangeAwareCollection implements ArrayAccess, ComparableInterface, Countable, IteratorAggregate {
+class ChangeAwareCollection implements Countable, ArrayAccess, IteratorAggregate {
/**
* Array with $all keys of newly added entries.
*/
protected array $added = array();
/**
- * @var array<int|string, mixed> $all An array containing all entries
+ * @var array<string, mixed> $all An array containing all entries
*/
protected array $all = array();
@@ -49,35 +51,28 @@ class ChangeAwareCollection implements ArrayAccess, ComparableInterface, Countab
* @param mixed $entry Either the key or the value that changes
* @return mixed reference to the value or null if it doesn't exist
*/
- public function &change($entry): mixed {
+ public function &change(mixed $entry): mixed {
$key = $this->findKeyForKeyOrEntry($entry);
if ($key !== null) {
$this->changed[] = $key;
return $this->all[$key];
}
+
+ throw new OutOfBoundsException("Entry not found");
}
/**
* @param mixed $val The data entry to be saved
- * @param string|null $key The key to save the entry under
+ * @param string $key The key to save the entry under
* @param bool $new Flag marking this entry as not new (not to be saved into $this->added)
*/
- public function add($val, ?string $key = null, bool $new = true): void {
+ public function add(mixed $val, string $key, bool $new = true): void {
if (is_object($val) && is_subclass_of($val, ChangeAwareInterface::class)) {
$val->belongsTo($this);
- //not every change aware object can know about a unique key
- if (method_exists($val, 'uniqKey') && $key === null) {
- $key = $val->uniqKey();
- }
}
- if ($key === null) {
- $this->all[] = $val;
- $key = array_search($val, $this->all, true);
- } else {
- $this->all[$key] = $val;
- }
+ $this->all[$key] = $val;
//if the override flag wasn't given, mark the entry as newly added
if ($new) {
@@ -90,8 +85,8 @@ class ChangeAwareCollection implements ArrayAccess, ComparableInterface, Countab
* @param bool $new Flag marking these entries as not new (not to be saved into $this->added)
*/
public function addAll(array $values, bool $new = true): void {
- foreach ($values as $val) {
- $this->add($val, null, $new);
+ foreach ($values as $key => $val) {
+ $this->add($val, $key, $new);
}
}
@@ -109,19 +104,6 @@ class ChangeAwareCollection implements ArrayAccess, ComparableInterface, Countab
return !empty($this->added) || !empty($this->removed) || !empty($this->changed);
}
- /**
- * compare this attribute set to another attribute set.
- * @param ComparableInterface $other The other object to compare this one to
- * @return bool if this object should be considered the same attribute set as the other one
- */
- public function compareTo(ComparableInterface $other): bool {
- if (!$other instanceof self) {
- return false;
- }
-
- return $this->compareToCollection($other);
- }
-
/**
* Only counts the "current" entries
* {@inheritDoc}
@@ -143,6 +125,8 @@ class ChangeAwareCollection implements ArrayAccess, ComparableInterface, Countab
if (isset($this->all[$key]) && !in_array($key, $this->removed)) {
return $this->all[$key];
}
+
+ return null;
}
/**
@@ -188,60 +172,8 @@ class ChangeAwareCollection implements ArrayAccess, ComparableInterface, Countab
return $this->all;
}
- /**
- * {@inheritDoc}
- */
- public function getIterator(): ArrayIterator {
- return new ArrayIterator($this->getAll());
- }
-
- public function has($value): bool {
- //if the given value is comparable, we can use that to find it
- if (is_object($value) && $value instanceof ComparableInterface) {
- foreach ($this->getAll('current') as $entry) {
- if (is_object($entry) && $entry instanceof ComparableInterface && $entry->compareTo($value)) {
- return true;
- }
- }
- } else {
- return in_array($value, $this->getAll('current'), true);
- }
-
- return false;
- }
-
- /**
- * Does not return true for "removed" entries.
- * {@inheritDoc}
- */
- public function offsetExists($offset): bool {
- return isset($this->all[$offset]) && !in_array($offset, $this->removed);
- }
-
- /**
- * Does only return values that aren't "removed".
- * {@inheritDoc}
- * @see self::get()
- */
- public function offsetGet($offset) {
- return $this->get($offset);
- }
-
- /**
- * {@inheritDoc}
- * @see self::set()
- */
- public function offsetSet($offset, $value): void {
- $this->set($offset, $value);
- }
-
- /**
- * Does only add the entry to "removed".
- * {@inheritDoc}
- * @see self::remove()
- */
- public function offsetUnset($offset): void {
- $this->remove($offset);
+ public function has(mixed $value): bool {
+ return $this->findKeyForKeyOrEntry($value) !== null;
}
/**
@@ -249,7 +181,7 @@ class ChangeAwareCollection implements ArrayAccess, ComparableInterface, Countab
* @param mixed $entry Either the key or the value that changes
* @return bool true or false on success or not
*/
- public function remove($entry): bool {
+ public function remove(mixed $entry): bool {
$key = $this->findKeyForKeyOrEntry($entry);
if ($key !== null) {
$this->removed[] = $key;
@@ -273,15 +205,15 @@ class ChangeAwareCollection implements ArrayAccess, ComparableInterface, Countab
/**
* setter function to set a value by its key
* either calls the add function or set the value.
- * @param string|null $key The key for the value
+ * @param string $key The key for the value
* @param mixed $value The value that is to be set
*/
- public function set(?string $key, $value): void {
- if ($key === null || !array_key_exists($key, $this->all)) {
+ public function set(string $key, mixed $value): void {
+ if (!array_key_exists($key, $this->all)) {
$this->add($value, $key);
} else {
if ($this->all[$key] !== $value) {
- $this->change($key);
+ $this->changed[] = $key;
}
if (is_object($value) && is_subclass_of($value, ChangeAwareInterface::class)) {
@@ -292,16 +224,6 @@ class ChangeAwareCollection implements ArrayAccess, ComparableInterface, Countab
}
}
- /**
- * compare this attribute set to another attribute set.
- * @param ChangeAwareCollection $other The other object to compare this one to
- * @return bool if this object should be considered the same attribute set as the other one
- */
- private function compareToCollection(self $other): bool {
- return $this->all === $other->all && $this->changed === $other->changed
- && $this->added === $other->added && $this->removed === $other->removed;
- }
-
/**
* helper function to figure out what an argument is
* first assumes the argument is a key
@@ -310,19 +232,46 @@ class ChangeAwareCollection implements ArrayAccess, ComparableInterface, Countab
* @param mixed $entry Either the key or the value
* @return mixed|null the key of the value/the key if it's a key
*/
- private function findKeyForKeyOrEntry($entry): mixed {
+ private function findKeyForKeyOrEntry(mixed $entry): ?string {
//check if $entry is an array key (allow null, so no isset)
- if ((is_string($entry) || is_int($entry)) && array_key_exists($entry, $this->all)) {
+ if (is_string($entry) && array_key_exists($entry, $this->all)) {
return $entry;
}
- if (is_object($entry) && $entry instanceof ComparableInterface) {
- foreach ($this->all as $key => $value) {
- if ($value instanceof ComparableInterface && $entry->compareTo($value)) {
- return $key;
- }
- }
- } elseif (($key = array_search($entry, $this->all)) !== false) {
+
+ if (($key = array_search($entry, $this->all, true)) !== false) {
return $key;
}
+
+ return null;
+ }
+
+ public function offsetExists(mixed $offset): bool {
+ // specifically use isset() in order to return false on null values
+ return isset($this->all[$offset]) && !in_array($offset, $this->removed);
+ }
+
+ /**
+ * @see self::get()
+ */
+ public function offsetGet(mixed $offset): mixed {
+ return $this->get($offset);
+ }
+
+ /**
+ * @see self::set()
+ */
+ public function offsetSet(mixed $offset, mixed $value): void {
+ $this->set($offset, $value);
+ }
+
+ /**
+ * @see self::remove()
+ */
+ public function offsetUnset(mixed $offset): void {
+ $this->remove($offset);
+ }
+
+ public function getIterator(): Iterator {
+ return new ArrayIterator($this->getAll());
}
}
diff --git a/d10b0620b948e97a9d30827c4f190cfe1611d0f6 b/d6a2eac05bc14dd84411460028e13cf6e055c3e9
index d10b062..d6a2eac 100644
--- a/d10b0620b948e97a9d30827c4f190cfe1611d0f6
+++ b/d6a2eac05bc14dd84411460028e13cf6e055c3e9
@@ -13,7 +13,7 @@ trait ChangeAwareTrait {
/**
* holds a reference to the ChangeAwareCollection that is keeping track of this object.
*/
- private ChangeAwareCollection $partOfCollection;
+ private ?ChangeAwareCollection $partOfCollection = null;
/**
* @param ChangeAwareCollection $coll A reference to the collection this object is part of
diff --git a/a032ecc3cd200babc8e821b4c22b6afbc67a0651 b/1143f81053f5f8ef420d7160d252fae32606b2b4
index a032ecc..1143f81 100644
--- a/a032ecc3cd200babc8e821b4c22b6afbc67a0651
+++ b/1143f81053f5f8ef420d7160d252fae32606b2b4
@@ -10,15 +10,18 @@
namespace holonet\common\collection;
use Countable;
-use ArrayAccess;
use ArrayIterator;
use IteratorAggregate;
/**
* The Collection is used as a wrapper around a data array
* it allows for the data to be accessed like an array or object.
+ * @template TKey of array-key
+ * @template T
+ *
+ * @implements IteratorAggregate<array-key, T>
*/
-class Collection implements ArrayAccess, Countable, IteratorAggregate {
+class Collection implements Countable, IteratorAggregate {
protected array $data = array();
public function __construct(array $initial = array()) {
@@ -50,7 +53,7 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate {
* return a reference so we can change e.g. sub arrays from this call
* => cannot use our own get() method.
*/
- public function &__get(string $key) {
+ public function __get(string $key): mixed {
if (is_object($this->data[$key]) || $this->data[$key] === null) {
//only actual variables should be returned by reference
return $this->data[$key];
@@ -81,7 +84,7 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate {
/**
* @param string[] $which Array with keys that are requested
*/
- public function getAll(?array $which = null): array {
+ public function all(?array $which = null): array {
if ($which !== null) {
return array_intersect_key($this->data, array_flip($which));
}
@@ -108,39 +111,6 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate {
}
}
- /**
- * {@inheritDoc}
- * @see self::__isset()
- */
- public function offsetExists($offset): bool {
- //use the isset method in order to return false for null value (the behaviour of isset())
- return $this->__isset($offset);
- }
-
- /**
- * {@inheritDoc}
- * @see self::get()
- */
- public function offsetGet($offset) {
- return $this->get($offset);
- }
-
- /**
- * {@inheritDoc}
- * @see self::set()
- */
- public function offsetSet($offset, $value): void {
- $this->set($offset, $value);
- }
-
- /**
- * {@inheritDoc}
- * @see self::remove()
- */
- public function offsetUnset($offset): void {
- $this->remove($offset);
- }
-
public function remove(string $key): void {
unset($this->data[$key]);
}
diff --git a/a45ef12f46df6871a502077a9d865e0ea42b5461 b/8bbbfc56bd777fa230760f9db2564a6153bd1b77
index a45ef12..8bbbfc5 100644
--- a/a45ef12f46df6871a502077a9d865e0ea42b5461
+++ b/8bbbfc56bd777fa230760f9db2564a6153bd1b77
@@ -18,7 +18,7 @@ use function holonet\common\dot_key_set;
* e.g. toplevel.lowerlevel => $data['toplevel']['lowerlevel']
* e.g. "%app.name%-test" => $data['app']['name'] . "-test".
*/
-class Registry implements ArrayAccess {
+class Registry {
/**
* @var array<string, mixed> $data Multilevel array with key=value pairs
*/
@@ -35,75 +35,35 @@ class Registry implements ArrayAccess {
$this->data = array();
}
- /**
- * @see self::offsetGet()
- */
public function get(string $key, mixed $default = null): mixed {
- return $this->offsetGet($key) ?? $default;
- }
+ $value = dot_key_get($this->data, $key, separator: $this->separator);
- /**
- * @see self::offsetExists()
- */
- public function has(string $key): bool {
- return $this->offsetExists($key);
+ return $this->replacePlaceholder($value) ?? $default;
}
- /**
- * {@inheritDoc}
- */
- public function offsetExists($offset): bool {
- $parts = explode($this->separator, $offset);
+ public function has(string $key): bool {
+ $parts = explode($this->separator, $key);
$position = $this->data;
- foreach ($parts as $sublevel) {
- if (!isset($position[$sublevel])) {
+ foreach ($parts as $subLevel) {
+ if (!isset($position[$subLevel])) {
return false;
}
- $position = $position[$sublevel];
+ $position = $position[$subLevel];
}
return true;
}
- /**
- * {@inheritDoc}
- */
- public function offsetGet($offset): mixed {
- $value = dot_key_get($this->data, $offset, separator: $this->separator);
-
- return $this->replacePlaceholder($value);
- }
-
- /**
- * {@inheritDoc}
- */
- public function offsetSet($offset, $value): void {
- dot_key_set($this->data, $offset, $value, $this->separator);
- }
-
- /**
- * {@inheritDoc}
- */
- public function offsetUnset($offset): void {
- dot_key_set($this->data, $offset, null, $this->separator);
- }
-
- /**
- * @see self::offsetSet()
- */
public function set(string $key, $value): void {
- $this->offsetSet($key, $value);
+ dot_key_set($this->data, $key, $value, $this->separator);
}
public function setAll(array $data): void {
$this->data = array_replace_recursive($this->data, $data);
}
- /**
- * @see self::offsetUnset()
- */
public function unset(string $key): void {
- $this->offsetUnset($key);
+ dot_key_set($this->data, $key, null, $this->separator);
}
/**
diff --git a/9cd09b5663fc7ee8ef75de35be5def0279e7b7a2 b/d3abc9f92256688586cc8184c20bd645b558828d
index 9cd09b5..d3abc9f 100644
--- a/9cd09b5663fc7ee8ef75de35be5def0279e7b7a2
+++ b/d3abc9f92256688586cc8184c20bd645b558828d
@@ -22,7 +22,7 @@ class ConfigRegistry extends Registry {
/**
* @template T
* Get an instance of a config dto class supplied by the user.
- * @param class-string<T>|T $cfgDto
+ * @psalm-param class-string<T>|T $cfgDto
* @return T
*/
public function asDto(string $configKey, string|object $cfgDto): object {
@@ -51,7 +51,7 @@ class ConfigRegistry extends Registry {
/**
* @template T
* Get a verified instance of a config dto class supplied by the user.
- * @param class-string<T>|T $cfgDto
+ * @psalm-param class-string<T>|T $cfgDto
* @return T
*/
public function verifiedDto(string $configKey, string|object $cfgDto): object {
diff --git a/a3a91deda75f58c115b6a114421878067ab6ab24 b/ca95b8884d1ed2a4e07e87642ed09b81350fabb1
index a3a91de..ca95b88 100644
--- a/a3a91deda75f58c115b6a114421878067ab6ab24
+++ b/ca95b8884d1ed2a4e07e87642ed09b81350fabb1
@@ -232,10 +232,10 @@ if (!function_exists(__NAMESPACE__.'\\dir_path')) {
if (!function_exists(__NAMESPACE__.'\\str_lreplace')) {
/**
- * Replace the last occurence of a string inside the subject.
+ * Replace the last occurrence of a string inside the subject.
* Courtesy of https://stackoverflow.com/a/3835653.
*/
- function str_lreplace($search, $replace, $subject) {
+ function str_lreplace(string $search, string $replace, string $subject): string {
$pos = mb_strrpos($subject, $search);
if ($pos !== false) {
diff --git a/8f27807563f695c567daef9563b091fc5557d4fa b/cf2d9dbb16aa2d33b6cfc46e01d50fa6af8dc728
index 8f27807..cf2d9db 100644
--- a/8f27807563f695c567daef9563b091fc5557d4fa
+++ b/cf2d9dbb16aa2d33b6cfc46e01d50fa6af8dc728
@@ -34,7 +34,7 @@ class Proof {
public function flat(): array {
$all = array();
- array_walk_recursive($this->errors, function ($error) use (&$all): void { $all[] = $error; });
+ array_walk_recursive($this->errors, function (string $error) use (&$all): void { $all[] = $error; });
return $all;
}
diff --git a/2a5535d60af59ae09cbb23de6b3f048bd83839bb b/6c341bec8ad5a2425ba2b7e586fbe18d1b376df2
index 2a5535d..6c341be 100644
--- a/2a5535d60af59ae09cbb23de6b3f048bd83839bb
+++ b/6c341bec8ad5a2425ba2b7e586fbe18d1b376df2
@@ -12,8 +12,10 @@ namespace holonet\common\verifier\rules;
use function holonet\common\stringify;
abstract class Rule {
- public function __construct(public ?string $message = null) {
- $this->message ??= static::defaultMessage();
+ public string $message;
+
+ public function __construct(string $message = null) {
+ $this->message = $message ?? static::defaultMessage();
}
public static function defaultMessage(): string {
diff --git a/9f92571b617b7c98d18637656df09c9e29452e81 b/54fbfbb38efa0260c20bd1ff2c56f61e81f1e46e
index 9f92571..54fbfbb 100644
--- a/9f92571b617b7c98d18637656df09c9e29452e81
+++ b/54fbfbb38efa0260c20bd1ff2c56f61e81f1e46e
@@ -18,26 +18,6 @@ use PHPUnit\Framework\Attributes\CoversFunction;
#[CoversFunction('holonet\common\dot_key_get')]
#[CoversFunction('holonet\common\dot_key_set')]
class RegistryTest extends TestCase {
- public function testArrayAccessCalls(): void {
- $registry = new Registry();
-
- $data = array(
- 'array' => array(
- 'lowerval' => 'lower',
- 'arrayarray' => array(
- 'lowestval' => 'lowest'
- )
- )
- );
- $registry->setAll($data);
-
- $this->assertSame('lowest', $registry['array.arrayarray.lowestval']);
- $this->assertTrue(isset($registry['array.lowerval']));
- $this->assertFalse(isset($registry['array.invalid']));
- unset($registry['array.lowerval.arrayarray']);
- $this->assertNull($registry['array.lowerval.arrayarray']);
- }
-
public function testGetMultilevel(): void {
$registry = new Registry();
@@ -51,6 +31,7 @@ class RegistryTest extends TestCase {
);
$registry->setAll($data);
+ $this->assertFalse($registry->has('array.notexisting'));
$this->assertSame('lower', $registry->get('array.lowerval'));
$this->assertNull($registry->get('array.notexisting'));
$this->assertSame('lowest', $registry->get('array.arrayarray.lowestval'));