From 60e3aae302a1329265b5678caf64c50cb2981e34 Mon Sep 17 00:00:00 2001 From: therselman Date: Wed, 23 Aug 2017 23:30:45 +0200 Subject: [PATCH] --- src/Collection.php | 177 +++++++++++++++++++++++++++++++++++++++ src/ORM/ActiveRecord.php | 2 +- src/ORM/Collection.php | 58 ++++++++++++- src/ORM/Model.php | 131 +++++++++++++++++++++++++++++ 4 files changed, 366 insertions(+), 2 deletions(-) create mode 100644 src/Collection.php create mode 100644 src/ORM/Model.php diff --git a/src/Collection.php b/src/Collection.php new file mode 100644 index 0000000..1b13781 --- /dev/null +++ b/src/Collection.php @@ -0,0 +1,177 @@ + + */ + +namespace Twister; + +class Collection implements \Iterator, \Countable, \ArrayAccess +{ + protected $members = null; + + public function __construct(array $members = []) + { + $this->members =& $members; + } + + + /** + * Countable interface + */ + public function find(...$params) + { + if (count($params) === 1) + return count($this->members); + + } + + + /** + * return all the array keys + */ + public function keys() + { + return array_keys($this->members); + } + + + /** + * + */ + public function isEmpty() + { + return count($this->members) === 0; + } + + + /** + * Get member by id/index + * + * Note: This is not very useful, because most members will be indexed by integer. + * + * @param string|int $idx + * @return mixed + */ + public function __get($idx) + { + return $this->members[$idx]; + } + + + /** + * Set member by id/index + * + * @param string|int $idx + * @param mixed $value + * @return void + */ + public function __set($idx, $value) + { + $this->members[$idx] = $value; + } + + + function __isset($idx) + { + return isset($this->members[$idx]); + } + function __unset($idx) + { + unset($this->members[$idx]); + } + + + /** + * Workaround for the `array access functions` eg. array_push($obj->toArray(), $value); + */ + public function &toArray() + { + return $this->members; + } + + + /** + * + */ + public function toJson() + { + return json_encode($this->members); + } + + + public function __toString() + { + return json_encode($this->members); + } + + + /** + * Iterator interface + */ + public function rewind() + { + return reset($this->members); + } + public function current() + { + return current($this->members); + } + public function key() + { + return key($this->members); + } + public function next() + { + return next($this->members); + } + public function valid() + { + return key($this->members) !== null; + } + + + /** + * Countable interface + */ + public function count() + { + return count($this->members); + } + /** + * @alias count() + */ + public function length() + { + return count($this->members); + } + + + /** + * ArrayAccess interface + */ + public function offsetGet($idx) // eg. var_dump($obj['two']); + { + return $this->members[$idx]; + } + public function offsetSet($idx, $value) // eg. $obj['two'] = 'A value'; + { + $this->members[$idx] = $value; + } + public function offsetExists($idx) // eg. isset($obj['two']) + { + return isset($this->members[$idx]); + } + public function offsetUnset($idx) // eg. unset($obj['two']); + { + unset($this->members[$idx]); + } +} diff --git a/src/ORM/ActiveRecord.php b/src/ORM/ActiveRecord.php index 66720df..e2f15ab 100644 --- a/src/ORM/ActiveRecord.php +++ b/src/ORM/ActiveRecord.php @@ -9,7 +9,7 @@ namespace Twister\ORM; * This class is designed for inheritance and users can subclass this class to * write their own repositories with business-specific methods to locate entities. * - * @author Trevor Herselman + * @author Trevor Herselman */ class ActiveRecord { diff --git a/src/ORM/Collection.php b/src/ORM/Collection.php index 560fab0..2dd1be1 100644 --- a/src/ORM/Collection.php +++ b/src/ORM/Collection.php @@ -6,6 +6,10 @@ * Typically holding a collection/array of Entity members * This class is not particularly useful compared to a standard array, * but it's used to `extend` the functionality of standard arrays. + * + * @link https://laravel.com/docs/5.4/eloquent-collections#available-methods + * + * @author Trevor Herselman */ namespace Twister\ORM; @@ -14,12 +18,41 @@ class Collection implements \Iterator, \Countable, \ArrayAccess { protected $members = null; - public function __construct(array $members = null) + public function __construct(array $members = []) { $this->members =& $members; } + /** + * Countable interface + */ + public function find(...$params) + { + if (count($params) === 1) + return count($this->members); + + } + + + /** + * return all the array keys + */ + public function keys() + { + return array_keys($this->members); + } + + + /** + * + */ + public function isEmpty() + { + return count($this->members) === 0; + } + + /** * Get member by id/index * @@ -33,6 +66,7 @@ class Collection implements \Iterator, \Countable, \ArrayAccess return $this->members[$idx]; } + /** * Set member by id/index * @@ -65,6 +99,21 @@ class Collection implements \Iterator, \Countable, \ArrayAccess } + /** + * + */ + public function toJson() + { + return json_encode($this->members); + } + + + public function __toString() + { + return json_encode($this->members); + } + + /** * Iterator interface */ @@ -97,6 +146,13 @@ class Collection implements \Iterator, \Countable, \ArrayAccess { return count($this->members); } + /** + * @alias count() + */ + public function length() + { + return count($this->members); + } /** diff --git a/src/ORM/Model.php b/src/ORM/Model.php new file mode 100644 index 0000000..1d13558 --- /dev/null +++ b/src/ORM/Model.php @@ -0,0 +1,131 @@ + + */ +class Model +{ + /** + * The database connection used by the EntityManager. + * + * @var \Doctrine\DBAL\Connection + */ + protected $em = null; + + + public function __construct(Container $c) + { + $this->conn = $c->db; + } + + + /** + * {@inheritDoc} + */ + public function getConnection() + { + return $this->conn; + } + + + /** + * {@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} + */ + public function beginTransaction() + { + $this->conn->beginTransaction(); + } + + + /** + * {@inheritDoc} + */ + public function transaction($func) // AKA `transactional` in Doctrine + { + if (!is_callable($func)) { + throw new \InvalidArgumentException('Expected argument of type "callable", got "' . gettype($func) . '"'); + } + $this->conn->beginTransaction(); + try { + $return = call_user_func($func, $this); + $this->flush(); + $this->conn->commit(); + return $return ?: true; + } catch (Exception $e) { + $this->close(); + $this->conn->rollBack(); + throw $e; + } + } + + + /** + * {@inheritDoc} + */ + public function commit() + { + $this->conn->commit(); + } + + + /** + * {@inheritDoc} + */ + public function rollback() + { + $this->conn->rollBack(); + } + + + /** + * 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, '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!" + ); + } + +}