Last active
September 10, 2015 14:31
-
-
Save chrisguitarguy/8c723d9512471dae610b to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| <?php | |
| interface Article | |
| { | |
| public function getIdentifier(); | |
| public function getTitle(); | |
| public function setTitle($title); | |
| public function getBody(); | |
| public function setBody($body); | |
| public function getYear(); | |
| public function setYear($year); | |
| } |
This file contains hidden or 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
| <?php | |
| interface ArticleRepository | |
| { | |
| public function find($id); | |
| public function findAll(); | |
| public function findByYear($year); | |
| public function add(Article $article); | |
| public function remove($article); | |
| } |
This file contains hidden or 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
| <?php | |
| use Doctrine\ORM\EntityRepository; | |
| final class DoctrineArticleRepository extends EntityRepository implements ArticleRepository | |
| { | |
| // EntityRepository provides this method | |
| // but we override it to get ordering | |
| public function findAll() | |
| { | |
| return $this->findBy([], [ | |
| 'year' => 'DESC', | |
| 'title' => 'ASC', | |
| ]); | |
| } | |
| public function add(Article $article) | |
| { | |
| $em = $this->getEntityManager(); | |
| $em->persist($article); | |
| $em->flush(); // probably not a good idea in a larger app | |
| return $article->getIdentifier(); | |
| } | |
| } |
This file contains hidden or 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
| <?php | |
| use Illuminate\Database\Eloquent\Model; | |
| class EloquentArticle extends Model implements Article | |
| { | |
| // configures some stuff for Eloquent | |
| public $timestamps = false; | |
| protected $table = 'articles'; | |
| } |
This file contains hidden or 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
| <?php | |
| final class EloquentArticleRepository implements ArticleRepository | |
| { | |
| public function findAll() | |
| { | |
| return EloquentArticle::query() | |
| ->orderBy('year', 'DESC') | |
| ->orderBy('title', 'ASC') | |
| ->get(); | |
| } | |
| public function add(Article $article) | |
| { | |
| if (!$article instanceof EloquentArticle) { | |
| throw new \InvalidArgumentException(sprintf( | |
| '%s expects and instance of %s, got "%s"', | |
| __METHOD__, | |
| EloquentArticle::class, | |
| get_class($article) | |
| )); | |
| } | |
| $article->save(); | |
| return $article->id; | |
| } | |
| } |
This file contains hidden or 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
| <?php | |
| final class PdoArticleRepository implements ArticleRepository | |
| { | |
| const TABLE = 'articles'; | |
| /** | |
| * @var PDO | |
| */ | |
| private $conn; | |
| public function __construct(\PDO $conn) | |
| { | |
| $this->conn = $conn; | |
| } | |
| public function findAll() | |
| { | |
| $stm = $this->conn->query( | |
| $this->getSelect().' ORDER BY publish_year DESC, title ASC' | |
| ); | |
| $out = $this->statementToObjects($stm); | |
| $stm->closeCursor(); | |
| return $out; | |
| } | |
| public function add(Article $article) | |
| { | |
| $id = $article->getIdentifier(); | |
| $params = [ | |
| ':title' => $article->getTitle(), | |
| ':body' => $article->getBody(), | |
| ':year' => $article->getYear(), | |
| ]; | |
| $bind = [ | |
| ':year' => \PDO::PARAM_INT, | |
| ]; | |
| if ($id) { | |
| $sql = 'UPDATE '.self::TABLE.' SET title = :title, body = :body, publish_year = :year WHERE id = :id'; | |
| $params[':id'] = $id; | |
| $bind[':id'] = \PDO::PARAM_INT; | |
| } else { | |
| $sql = 'INSERT INTO '.self::TABLE.' (title, body, publish_year) VALUES (:title, :body, :year)'; | |
| } | |
| $stm = $this->conn->prepare($sql); | |
| foreach ($params as $name => $val) { | |
| $stm->bindValue( | |
| $name, | |
| $val, | |
| isset($bind[$name]) ? $bind[$name] : \PDO::PARAM_STR | |
| ); | |
| } | |
| $stm->execute(); | |
| return $id ? $id : intval($this->conn->lastInsertId()); | |
| } | |
| // may make more sense to use a factory object here, but | |
| // let's keep this somewhat simple. | |
| private function toObject(array $row) | |
| { | |
| $article = new SimpleArticle($row['id']); | |
| $article->setTitle($row['title']); | |
| $article->setBody($row['body']); | |
| $article->setYear($row['publish_year']); | |
| return $article; | |
| } | |
| private function statementToObjects(\PDOStatement $stm) | |
| { | |
| // could very easily use an iterator or a generator here | |
| // with big data sets, again, let's keep it simple. | |
| $stm->setFetchMode(\PDO::FETCH_ASSOC); | |
| return array_map([$this, 'toObject'], $stm->fetchAll()); | |
| } | |
| private function getSelect() | |
| { | |
| return 'SELECT id, title, body, publish_year FROM '.self::TABLE; | |
| } | |
| } |
This file contains hidden or 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
| <doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" | |
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
| xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping | |
| http://raw.github.com/doctrine/doctrine2/master/doctrine-mapping.xsd"> | |
| <entity name="PMG\ThreeRepositories\SimpleArticle" table="articles" repository-class="PMG\ThreeRepositories\DoctrineArticleRepository"> | |
| <id name="id" type="integer"> | |
| <generator strategy="AUTO" /> | |
| </id> | |
| <field name="title" type="text" /> | |
| <field name="body" type="text" /> | |
| <field name="year" column="publish_year" type="integer" /> | |
| </entity> | |
| </doctrine-mapping> |
This file contains hidden or 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
| <?php | |
| abstract class TestCase extends \PHPUnit_Framework_TestCase | |
| { | |
| protected $repo; | |
| public function testArticlesCanBePersistedUpdatedFetchedAndRemoved() | |
| { | |
| $this->assertEmpty($this->repo->findAll()); | |
| $this->assertEmpty($this->repo->findByYear(2015)); | |
| $article = $this->createArticle(); | |
| $article->setTitle('Hello'); | |
| $article->setBody('World'); | |
| $article->setYear(2015); | |
| $id = $this->repo->add($article); | |
| $this->assertCount(1, $this->repo->findAll()); | |
| $this->assertEmpty($this->repo->findByYear(2014)); | |
| $this->assertCount(1, $this->repo->findByYear(2015)); | |
| $article = $this->repo->find($id); | |
| $this->assertInstanceOf(Article::class, $article); | |
| $article->setTitle('changed'); | |
| $this->repo->add($article); | |
| $article = $this->repo->find($id); | |
| $this->assertInstanceOf(Article::class, $article); | |
| $this->assertEquals('changed', $article->getTitle()); | |
| $this->repo->remove($article); | |
| $this->assertNull($this->repo->find($id)); | |
| } | |
| abstract protected function createArticle(); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment