3

I have a ZF2 application that has database tables for posts and hash tags with a many-to-many relationship. The table definitions are:

CREATE TABLE `hash_tag` (
    `id` int(11) NOT NULL,
    `tag` varchar(255) NOT NULL
)

CREATE TABLE `post` (
    `id` int(11) NOT NULL,
    `text` varchar(255)NOT NULL,
    `addedOn` datetime NOT NULL
)

CREATE TABLE `post_hashtag` (
    `post_id` int(11) NOT NULL,
    `hashtag_id` int(11) NOT NULL
)

I've also created models following the patterns explained in the ZF2 documentation's user guide. The HashTag model is as follows:

namespace Application\Model;

use Application\Model\Post;

class HashTag
{
    public $id;
    public $tag;

    protected $posts = array();

    public function exchangeArray($data)
    {
        $this->id = empty($data['id']) ? null : $data['id'];
        $this->tag = empty($data['tag']) ? null : $data['tag'];
    }

    public function getPosts()
    {
        return $this->posts;
    }

    public function addPost(Post $post)
    {
        $this->posts[] = $post;
        return $this;
    }

}

While the guide gives a pretty good explanation of how to handle basic database models, I'm looking to do something a bit more complicated.

Basically, when I retrieve the hash tag records, I also want to retrieve their associated posts and somehow store them in each individual HashTag object. Doing a normal join query results in a new record for each hash tag AND its accompanying post, which doesn't really help. The documentation doesn't go into any detail about how to do this either, nor can I find anything on Google about it with any decent examples.

I've used Doctrine 2 in the past, and would normally continue to do so. However, I'm preparing for a new job, and my new employer uses Zend\Db. I'm basically doing this to get practice handling database operations without using Doctrine.

blainarmstrong
  • 1,040
  • 1
  • 13
  • 33

1 Answers1

0

Had the same problem and i still dont know if my way is a good way to do but it works. I create a "Mapper"(Generic names ftw) for every Entity that need to work with m-m relations. Here some example:

class AddresseeMapper {

private $resultSet;

private $addresseeArray = array();
private $addreseeObjectsArray = array();

public function __construct($resultSet)
{
    $this->resultSet = $resultSet;
}

public function init()
{
    foreach($this->resultSet as $key => $result)
    {
        $addressee = array();

        if(!empty($this->addresseeArray[$result['AddresseeID']]))
        {
            $addressee = $this->addresseeArray[$result['AddresseeID']];
        }
        else
        {
            $addressee['id'] = $result['AddresseeID'];
            $addressee['documentID'] = $result['AddresseeDocumentID'];
            $addressee['communicationID'] = $result['AddresseeCommunicationID'];
            $addressee['addressID'] = (!empty($result['AddresseeAddressID'])) ? $result['AddresseeAddressID'] : null;
            $addressee['salutation'] = (!empty($result['AddresseeSalutation'])) ? $result['AddresseeSalutation'] : null;
            $addressee['tempEmail'] = (!empty($result['AddresseeTempEmail'])) ? $result['AddresseeTempEmail'] : null;

            if((!empty($result['ContactID'])) && $result['ContactID'])
            {
                $addressee['Contact'] = $this->setContact($this->resultSet);
            }

            if((!empty($result['MailingListID'])) && $result['MailingListID'])
            {
                $addressee['MailingList'] = $this->exchangeMailingList($result);
            }

        }
        $this->addresseeArray[$result['AddresseeID']] = $addressee;
    }
}

private function setContact($resultSet)
{
    $contactMapper = new ContactMapper($resultSet);
    $contactMapper->init();
    $contactMapper->serilizeObjects();

    return $contactMapper->getContact();
}

private function exchangeMailingList($result)
{
    $mailingList = new MailingList();
    $mailingList->exchangeArray($result);

    return $mailingList;
}

public function serilizeObjects()
{
    foreach($this->addresseeArray as $addresseeArray)
    {
        $addressee = new Addressee();
        $addressee = $this->loop($addresseeArray, $addressee);

        $this->addreseeObjectsArray[] = $addressee;
    }

}

private function loop($array, $object)
{
    foreach($array as $key => $value)
    {
        if(is_array($value) && is_object($object->$key))
        {
            $object->$key = $this->deepLoop($value, $object->$key);
        }
        elseif(is_array($object->$key))
        {
            foreach($value as $key2 => $value2)
            {
                array_push($object->$key, $value2);
            }
        }
        else
        {
            $object->$key = $value;
        }

    }

    return $object;
}

private function deepLoop($array, $object)
{
    foreach($array as $key => $value)
    {
        //var_dump($key);
        //var_dump($value);
        $object->$key = $value;
    }

    return $object;
}

public function getAddressees()
{
    return $this->addreseeObjectsArray;
}

public function getAddressee()
{
    foreach($this->addreseeObjectsArray as $addressee)
    {
        return $addressee;
    }

    return false;
}

}

Tiega
  • 387
  • 4
  • 16