3

My question is related to the update section of @tereško's answer in "Who should handle the conditions in complex queries, the data mapper or the service layer?" Below is the code for reference and convenience.

$category = new Category;
$category->setTitle( 'privacy' );

$list = new ArticleCollection;

$list->setCondition( $category );
$list->setDateRange( mktime( 0, 0, 0, 12, 9, 2001) );
// it would make sense, if unset second value for range of dates 
// would default to NOW() in mapper

$mapper = new ArticleCollectionMapper;
$mapper->fetch( $list );

foreach ( $list as $article )
{
    $article->setFlag( Article::STATUS_REMOVED );
}

$mapper->store( $list );

In this code ArticleCollection is a collection of Domain Objects, let's call them Articles. The moment the ArticleCollectionMapper fetches data from the database, assigning it to $list, instances of Article need to be made (for each row). Would the instances of Article be added to our collection instance ($list) via a method like $list->addArticle($newArticle), should a Factory Object like ArticleFactory be used for that, or is there another option I haven't considered?

Community
  • 1
  • 1

1 Answers1

2

I wouldn't think to actually use a factory object to add the articles. You may see yourself using one to make the instance of Article (in the second example), though. What I went ahead and did was add an addArticles () method to the ArticleCollection instance. This way you can simply call the method on your instance of ArticleCollection from the mapper. ArticleCollectionMapper may look something like:

class ArticleCollectionMapper extends DataMapperAbstract
{
    public function fetch ( ArticleCollection $articles )
    {
        $prepare = $this->connection->prepare( "SELECT ..." );
        $prepare->execute();
        // filter conditions

        $articles->addArticles( $prepare->fetchAll() );
    }
}

You'd need to do some filtering by getting the conditions from the ArticleCollection instance, which is excluded from the snippet above. Then our domain object's addArticles() implementation would look similar following:

class ArticleCollection extends DomainObjectAbstract
{
    protected $collection = array();

    public function addArticles ( Array $articles )
    {
        foreach ( $articles as $article )
        {
            $articleCollectionItem = new Article;
            $articleCollectionItem->setParams( $article );
            // however you prefer filling your list with `Article` instances

            $this->collection[] = $articleCollectionItem;
        }
    }
}

You may also want to add an addArticle() method depending on your needs, and then just replacing what's within the foreach above with a call to addArticle(). Note that the above examples are extremely simplified and code will need to be adapted in order to meet your standards.

jeremy
  • 9,455
  • 4
  • 36
  • 57
  • hey jeremy, thank you for your answer. In fact in the mean time i used a similar solution. Rather then using the addArticle you showed i have a newArticle and an addArticle method in the ArticleCollection. The first one just returns an article object, which the datamapper populate by its own method. And the addArticle Method just adds a given article object to the list. So you are right one does not need a factory for that. – Malte Behrmann Aug 09 '13 at 07:40