Skip to content

Instantly share code, notes, and snippets.

@caseyamcl
Created December 19, 2014 15:44
Show Gist options
  • Save caseyamcl/5711e444dadf9f8b8f6a to your computer and use it in GitHub Desktop.
Save caseyamcl/5711e444dadf9f8b8f6a to your computer and use it in GitHub Desktop.
<?php
class ContentItemMapper implements MapperInterface
{
private $isLoaded = false;
// ------------------------------------------------------
public function __construct(MapperCollection $mappers, IdentityMap $idMap, SplFileInfoToContentItem $transformer, $contentPath)
{
$mappers->add('contentItems', $this);
$this->mappers = $mappers;
$this->idMap = $idMap;
$this->transformer = $transformer;
$this->contentPath = $contentPath;
}
// ------------------------------------------------------
public function getItem($identifier)
{
// Be sure we have loaded the items
if ( ! $this->isLoaded) {
$this->getItems();
}
return $this->idMap->get('\Skimpy\Entity\Term', $identifier);
}
// ------------------------------------------------------
public function getItems()
{
foreach ($this->getContentFiles() as $f) {
$obj = $this->transformer->transform($f)
// As we are loading, we need to populate the 'terms' property with
// Term objects from the TermMapper
// (or you could do this in the transformer class...)
$obj->setTerms(new LazyLoadedCollection('terms', $termSlugsFromFileHere));
// Add it to the identityMap
$this->idMap->load($obj);
}
// Set isLoaded is true so we don't read the filesystem for every call to this method
$this->isLoaded = true;
// Get the items from the identiy map
return $this->idMap->getType('\Skimpy\Entity\Term');
}
// ------------------------------------------------------
protected function readItemFiles()
{
return (new Finder)->in($this->contentPath)->files();
}
}
<?php
/**
* Lazy Loaded Collection represents a collection of objects
* that don't exist when the object is constructed, but only loaded
* when requested
*/
class LazyLoadedCollection implements \IteratorAggregate, \Countable
{
public function __construct(MapperInterface $mapper, array $identifiers)
{
$this->items = [];
$this->mapper = $mapper;
$this->ids = $identifiers;
}
public function getIterator()
{
$this->loadEm();
return new \ArrayIterator($this->items);
}
public function count()
{
$this->loadEm();
return count($this->items);
}
protected function loadEm()
{
// Only laoad em once
if ( ! empty($this->items)) {
return;
}
foreach ($this->ids as $identifier) {
$this->items[$identifier] = $this->mapper->getItem($identifier);
}
}
}
<?php
class MapperCollection
{
/**
* @var array
*/
private $mappers;
/**
* Add a mapper
*/
public function add($mapperName, MapperInterface $mapper);
/**
* Get a mapper
*
* @return MapperInterface
* @throws MapperNotFoundException If could not find that mapper
*/
public function get($mapperName);
}
<?php
interface MapperInterface
{
function getItems();
function getItem($identifier);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment