-
Notifications
You must be signed in to change notification settings - Fork 36
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
314 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
<?php | ||
|
||
/** | ||
* This file is part of the Lean Mapper library (http://www.leanmapper.com) | ||
* | ||
* Copyright (c) 2013 Vojtěch Kohout (aka Tharos) | ||
* | ||
* For the full copyright and license information, please view the file | ||
* license.md that was distributed with this source code. | ||
*/ | ||
|
||
declare(strict_types=1); | ||
|
||
namespace LeanMapper; | ||
|
||
trait Initialize | ||
{ | ||
/** | ||
* Creates & initializes entity instance from given argument | ||
* | ||
* @param Row|iterable<string, mixed>|null $arg | ||
*/ | ||
public static function initialize($arg): Entity | ||
{ | ||
$reflection = static::getReflection(); | ||
$entity = $reflection->newInstanceWithoutConstructor(); | ||
|
||
if ($arg instanceof Row) { | ||
if ($arg->isDetached()) { | ||
throw new Exception\InvalidArgumentException( | ||
'It is not allowed to create entity ' . get_called_class() . ' from detached instance of ' . Row::class . '.' | ||
); | ||
} | ||
|
||
$entity->row = $arg; | ||
$entity->mapper = $arg->getMapper(); | ||
|
||
} else { | ||
$entity->row = Result::createDetachedInstance()->getRow(); | ||
|
||
foreach ($entity->getCurrentReflection()->getEntityProperties() as $property) { | ||
if ($property->hasDefaultValue()) { | ||
$propertyName = $property->getName(); | ||
$entity->set($propertyName, $property->getDefaultValue()); | ||
} | ||
} | ||
|
||
$entity->initDefaults(); | ||
|
||
if ($arg !== null) { | ||
if (!is_iterable($arg)) { | ||
$type = Helpers::getType($arg); | ||
throw new Exception\InvalidArgumentException( | ||
"Argument \$arg in " . get_called_class( | ||
) . "::__construct must contain either null, array, instance of " . Row::class . " or instance of " . \Traversable::class . ", $type given." | ||
); | ||
} | ||
|
||
$entity->assign($arg); | ||
} | ||
} | ||
|
||
return $entity; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
use LeanMapper\Entity; | ||
use LeanMapper\Initialize; | ||
use LeanMapper\Result; | ||
use LeanMapper\Row; | ||
use Tester\Assert; | ||
|
||
require_once __DIR__ . '/../bootstrap.php'; | ||
|
||
$connection = Tests::createConnection(); | ||
$mapper = Tests::createMapper(); | ||
$entityFactory = Tests::createEntityFactory(); | ||
|
||
////////// | ||
|
||
/** | ||
* @property int $id | ||
* @property string $name | ||
* @property string $pubdate | ||
*/ | ||
class Book extends Entity | ||
{ | ||
use Initialize; | ||
|
||
|
||
public function __construct( | ||
string $name, | ||
string $pubdate | ||
) | ||
{ | ||
parent::__construct(); | ||
|
||
$this->name = $name; | ||
$this->pubdate = $pubdate; | ||
} | ||
} | ||
|
||
////////// | ||
|
||
$book = Book::initialize([]); | ||
|
||
Assert::type(Book::class, $book); | ||
|
||
////////// | ||
|
||
$data = [ | ||
'id' => 1, | ||
'name' => 'PHP guide', | ||
'pubdate' => '2013-06-13', | ||
]; | ||
|
||
$book = Book::initialize($data); | ||
|
||
Assert::type(Book::class, $book); | ||
Assert::equal($data, $book->getData()); | ||
|
||
////////// | ||
|
||
$dibiRow = new \Dibi\Row($data); | ||
$row = new Row(Result::createInstance($dibiRow, 'book', $connection, $mapper), 1); | ||
$book = Book::initialize($row); | ||
|
||
Assert::type(Book::class, $book); | ||
Assert::equal($data, $book->getData()); | ||
|
||
////////// | ||
|
||
$dibiRow = new \Dibi\Row($data); | ||
$row = Result::createInstance($dibiRow, 'book', $connection, $mapper)->getRow(1); | ||
$book = Book::initialize($row); | ||
|
||
Assert::type(Book::class, $book); | ||
Assert::equal($data, $book->getData()); | ||
|
||
////////// | ||
|
||
$book = Book::initialize(new ArrayObject($data)); | ||
|
||
Assert::type(Book::class, $book); | ||
Assert::equal($data, $book->getData()); | ||
|
||
////////// | ||
|
||
Assert::exception( | ||
function () { | ||
Book::initialize(false); | ||
}, | ||
LeanMapper\Exception\InvalidArgumentException::class, | ||
'Argument $arg in Book::__construct must contain either null, array, instance of LeanMapper\Row or instance of Traversable, boolean given.' | ||
); | ||
|
||
Assert::exception( | ||
function () { | ||
Book::initialize('hello'); | ||
}, | ||
LeanMapper\Exception\InvalidArgumentException::class, | ||
'Argument $arg in Book::__construct must contain either null, array, instance of LeanMapper\Row or instance of Traversable, string given.' | ||
); | ||
|
||
////////// | ||
|
||
$dibiRow = new \Dibi\Row($data); | ||
$row = new Row(Result::createInstance($dibiRow, 'book', $connection, $mapper), 1); | ||
$row->detach(); | ||
|
||
Assert::exception( | ||
function () use ($row) { | ||
Book::initialize($row); | ||
}, | ||
LeanMapper\Exception\InvalidArgumentException::class, | ||
'It is not allowed to create entity Book from detached instance of LeanMapper\Row.' | ||
); | ||
|
||
////////// | ||
|
||
$data = [ | ||
'id' => 1, | ||
'name' => 'PHP guide', | ||
'pubdate' => '2013-06-13', | ||
]; | ||
|
||
$book = new Book( | ||
$data['name'], | ||
$data['pubdate'] | ||
); | ||
|
||
Assert::type(Book::class, $book); | ||
Assert::equal([ | ||
'name' => $data['name'], | ||
'pubdate' => $data['pubdate'], | ||
], $book->getRowData()); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
use LeanMapper\Entity; | ||
use LeanMapper\Initialize; | ||
use Tester\Assert; | ||
|
||
require_once __DIR__ . '/../bootstrap.php'; | ||
|
||
////////// | ||
|
||
/** | ||
* @property int $id | ||
* @property string $name | ||
* @property string|null $web | ||
* @property Book[] $books m:belongsToMany | ||
*/ | ||
class Author extends Entity | ||
{ | ||
use Initialize; | ||
|
||
|
||
public function __construct( | ||
string $name, | ||
?string $web | ||
) | ||
{ | ||
parent::__construct(); | ||
|
||
$this->name = $name; | ||
$this->web = $web; | ||
} | ||
} | ||
|
||
/** | ||
* @property int $id | ||
* @property string $name | ||
* @property string $pubdate | ||
* @property NULL|Author $author m:hasOne | ||
*/ | ||
class Book extends Entity | ||
{ | ||
use Initialize; | ||
|
||
|
||
public function __construct( | ||
string $name, | ||
string $pubdate, | ||
?Author $author | ||
) | ||
{ | ||
parent::__construct(); | ||
|
||
$this->name = $name; | ||
$this->pubdate = $pubdate; | ||
$this->author = $author; | ||
} | ||
} | ||
|
||
class BookRepository extends \LeanMapper\Repository | ||
{ | ||
|
||
public function find($id) | ||
{ | ||
$row = $this->connection->select('*')->from($this->getTable())->where('id = %i', $id)->fetch(); | ||
if ($row === false) { | ||
throw new \Exception('Entity was not found.'); | ||
} | ||
return $this->createEntity($row); | ||
} | ||
|
||
} | ||
|
||
////////// | ||
|
||
$connection = Tests::createConnection(); | ||
$mapper = Tests::createMapper(); | ||
$entityFactory = Tests::createEntityFactory(); | ||
|
||
$bookRepository = new BookRepository($connection, $mapper, $entityFactory); | ||
|
||
$book = $bookRepository->find(1); | ||
|
||
Assert::type(Author::class, $book->author); | ||
|
||
$author = $book->author; | ||
|
||
$book->author = null; | ||
|
||
Assert::equal(null, $book->author); | ||
|
||
Assert::equal( | ||
[ | ||
'author_id' => null, | ||
], | ||
$book->getModifiedRowData() | ||
); | ||
|
||
$book->author = $author; | ||
|
||
Assert::type(Author::class, $book->author); |