therselman
7 years ago
4 changed files with 366 additions and 2 deletions
@ -0,0 +1,177 @@
@@ -0,0 +1,177 @@
|
||||
<?php |
||||
|
||||
/** |
||||
* Collection class with dynamic members |
||||
* Similar functionality to an Array or Dictionary class |
||||
* 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 <therselman@gmail.com> |
||||
*/ |
||||
|
||||
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]); |
||||
} |
||||
} |
@ -0,0 +1,131 @@
@@ -0,0 +1,131 @@
|
||||
<?php |
||||
|
||||
namespace Twister\ORM; |
||||
|
||||
/** |
||||
* A Repository serves as a repository for entities with generic as well as |
||||
* business specific methods for retrieving entities. |
||||
* |
||||
* 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 <therselman@gmail.com> |
||||
*/ |
||||
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!" |
||||
); |
||||
} |
||||
|
||||
} |
Loading…
Reference in new issue