From 099b5de451e7fcfe9eeb9dad2386a45c0243520f Mon Sep 17 00:00:00 2001 From: therselman Date: Thu, 24 Aug 2017 09:24:59 +0200 Subject: [PATCH] --- src/ORM/Collection.php | 305 +++++++++++++++++++++++++++++++++++++- src/ORM/EntityManager.php | 57 ++++++- src/ORM/Repository.php | 15 -- 3 files changed, 349 insertions(+), 28 deletions(-) diff --git a/src/ORM/Collection.php b/src/ORM/Collection.php index 2dd1be1..1386d3d 100644 --- a/src/ORM/Collection.php +++ b/src/ORM/Collection.php @@ -14,7 +14,7 @@ namespace Twister\ORM; -class Collection implements \Iterator, \Countable, \ArrayAccess +class Collection implements \Iterator, \Countable, \ArrayAccess, \IteratorAggregate //, JsonSerializable http://php.net/JsonSerializable { protected $members = null; @@ -36,20 +36,293 @@ class Collection implements \Iterator, \Countable, \ArrayAccess /** - * return all the array keys + * Get the keys of the collection members. + * + * @return static */ public function keys() { - return array_keys($this->members); + return new static(array_keys($this->members)); // or array_keys($this->members) } /** - * + * Get the items in the collection that are not present in the given array. + * + * @param mixed $items + * @return static + */ + public function diff($items) + { + return new static(array_diff($this->members, $this->getArrayableItems($items))); + } + + + /** + * Execute a callback over each item. + * + * @param callable $callback + * @return $this + */ + public function each(callable $callback) + { + foreach ($this->members as $key => $member) + { + if ($callback($key, $member) === false) { + break; + } + } + return $this; + } + + + /** + * Run a map over each of the members. + * + * @link http://php.net/manual/en/function.array-map.php + * + * @param callable $callback + * @return static + */ + public function map(callable $callback) + { + $keys = array_keys($this->members); + $members = array_map($callback, $this->members, $keys); + return new static(array_combine($keys, $members)); + } + + + /** + * Merge the collection with the given items. + * + * @param mixed $items + * @return static + */ + public function merge($items) + { + return new static(array_merge($this->items, $this->getArrayableItems($items))); + } + + + /** + * Results array of items from Collection or Arrayable. + * + * Used by PHP functions that only accept a standard array + * + * @param mixed $items + * @return array + */ + protected function getArrayableItems($items) + { + if ($items instanceof self) { + return $items->all(); + } else if (is_array($items)) { + return $items; + } else if ($items instanceof Arrayable) { + return $items->toArray(); + } else if ($items instanceof Jsonable) { + return json_decode($items->toJson(), true); + } else if (is_object($items) && method_exists($items, 'toArray')) { + return $items->toArray(); + } + return (array) $items; + } + + + /** + * Get and remove the last member from the collection. + * + * @link http://php.net/manual/en/function.array-pop.php + * + * @return mixed + */ + public function pop() + { + return array_pop($this->members); + } + + + /** + * Push an item onto the end of the collection. + * + * @link http://php.net/manual/en/function.array-push.php + * + * @param mixed $value + * @return $this + */ + public function push($value) + { + $this->members[] = $value; + return $this; + } + + + /** + * Put an item in the collection by key. + * + * @param mixed $key + * @param mixed $value + * @return $this + */ + public function put($key, $value) + { + $this->members[$key] = $value; + return $this; + } + + + /** + * Get one or more random members from the collection. + * + * @link http://php.net/manual/en/function.array-rand.php + * + * @param int $num + * @return mixed + */ + public function random($num = 1) + { + if ($num == 1) + return $this->members[array_rand($this->members)]; + + $keys = array_rand($this->members, $num); + return new static(array_intersect_key($this->members, array_flip($keys))); + } + + + /** + * Get and remove the first item from the collection. + * + * @link http://php.net/manual/en/function.array-shift.php + * + * @return mixed + */ + public function shift() + { + return array_shift($this->members); + } + + + /** + * Shuffle the members in the collection. + * + * @return static + */ + public function shuffle() + { + $members = $this->members; + shuffle($members); + return new static($members); + } + + + /** + * Slice the underlying collection array. + * + * @param int $offset + * @param int $length + * @param bool $preserve_keys + * @return static + */ + public function slice($offset, $length = null, $preserve_keys = false) + { + return new static(array_slice($this->members, $offset, $length, $preserve_keys)); + } + + + /** + * Take the first or last {$limit} members. + * + * @param int $limit + * @return static + */ + public function take($limit) + { + return $limit < 0 ? $this->slice($limit, abs($limit)) : $this->slice(0, $limit); + } + + + /** + * Run a filter over each of the members. + * + * @link http://php.net/manual/en/function.array-filter.php + * + * @param callable|null $callback + * @return static + */ + public function filter(callable $callback = null) + { + return new static($callback ? array_filter($this->members, $callback) : array_filter($this->members)); + } + + + /** + * Reset the keys on the underlying array. + * + * @link http://php.net/manual/en/function.array-values.php + * + * @return static + */ + public function values() + { + return new static(array_values($this->members)); + } + + + /** + * Prepend one or more members to the beginning of the collection + * + * @link http://php.net/manual/en/function.array-values.php + * + * @return $this + */ + public function unshift(...$values) + { + array_unshift($this->members, $values); + return $this; + } + + + /** + * Flip the members of the collection. + * + * @return static + */ + public function flip() + { + return new static(array_flip($this->members)); + } + + + /** + * Determine if the collection is empty or not. + * + * @return bool */ public function isEmpty() { - return count($this->members) === 0; + return empty($this->members); + } + + + /** + * Determine if the collection is not empty. + * + * @return bool + */ + public function isNotEmpty() + { + return ! empty($this->members); + } + + + /** + * Get an iterator for the members. + * + * @return \ArrayIterator + */ + public function getIterator() + { + return new ArrayIterator($this->members); } @@ -90,10 +363,28 @@ class Collection implements \Iterator, \Countable, \ArrayAccess } + /** + * Get the collection of items as a plain array. + * + * @return array + */ /** * Workaround for the `array access functions` eg. array_push($obj->toArray(), $value); */ - public function &toArray() + public function toArray() + { + return $this->members; + } + + + /** + * Get all of the items in the collection. + * + * @alias toArray() + * + * @return array + */ + public function all() { return $this->members; } @@ -135,7 +426,7 @@ class Collection implements \Iterator, \Countable, \ArrayAccess } public function valid() { - return key($this->members) !== null; + return key($this->members) !== null; // or current($this->attributes) !== false } diff --git a/src/ORM/EntityManager.php b/src/ORM/EntityManager.php index afa94e2..ecc0541 100644 --- a/src/ORM/EntityManager.php +++ b/src/ORM/EntityManager.php @@ -11,6 +11,8 @@ class EntityManager */ protected $conn = null; + protected $repos = null; + public function __construct(Container $c) { @@ -32,16 +34,59 @@ class EntityManager */ public function getRepository($entityName) { - static $repos = null; - if ( ! isset($repos[$entityName])) { + if ( ! isset($this->repos[$entityName])) { + $repoName = $entityName . 'Repository'; + $this->repos[$entityName] = new $repoName($this); + } + return $this->repos[$entityName]; + } + + + /** + * {@inheritDoc} + */ + public function find($entityName, ...$params) + { + if ( ! isset($this->repos[$entityName])) { $repoName = $entityName . 'Repository'; -echo 'loading: ' . $repoName; - $repos[$entityName] = new $repoName($this); + $this->repos[$entityName] = new $repoName($this); } - return $repos[$entityName]; + return $this->repos[$entityName]; } + /** + * Adds support for magic method calls. + * + * @param string $method + * @param array $args + * + * @return mixed The returned value from the resolved method. + * + * @throws ORMException + * @throws \BadMethodCallException If the method called is invalid + */ + public function __call($method, $args) + { + if (0 === strpos($method, 'get')) { + return $this->; + } + if (0 === strpos($method, 'findBy')) { + return $this->resolveMagicCall('findBy', substr($method, 6), $args); + } + if (0 === strpos($method, 'findOneBy')) { + return $this->resolveMagicCall('findOneBy', substr($method, 9), $args); + } + if (0 === strpos($method, 'countBy')) { + return $this->resolveMagicCall('count', substr($method, 7), $args); + } + throw new \BadMethodCallException( + "Undefined method '$method'. The method name must start with ". + "either findBy, findOneBy or countBy!" + ); + } + + /** * {@inheritDoc} */ @@ -54,7 +99,7 @@ echo 'loading: ' . $repoName; /** * {@inheritDoc} */ - public function transaction($func) // AKA `transactional` in Doctrine + public function transaction($func) // AKA `transactional` in Doctrine AKA transact { if (!is_callable($func)) { throw new \InvalidArgumentException('Expected argument of type "callable", got "' . gettype($func) . '"'); diff --git a/src/ORM/Repository.php b/src/ORM/Repository.php index 606f0ad..337d499 100644 --- a/src/ORM/Repository.php +++ b/src/ORM/Repository.php @@ -36,21 +36,6 @@ class Repository } - /** - * {@inheritDoc} - */ - public function getRepository($entityName) - { - static $repos = null; - if ( ! isset($repos[$entityName])) { - $repoName = $entityName . 'Repository'; -echo 'loading: ' . $repoName; - $repos[$entityName] = new $repoName($this); - } - return $repos[$entityName]; - } - - /** * {@inheritDoc} */