<?php

class Core_Doctrine_Template_Listener_Blameable extends Doctrine_Record_Listener
{
    /**
     * Array of timestampable options
     *
     * @var string
     */
    protected $_options = array();

    /**
     * The default value of the blameVar if one isn't available
     *
     * @var string
     */
    protected $_default = null;


    /**
     * __construct
     *
     * @param array $options
     *
     * @return void
     */
    public function __construct(array $options)
    {
        $this->_options = $options;
    }

    /**
     * Set the created and updated Blameable columns when a record is inserted
     *
     * @param Doctrine_Event $event
     * @return void
     */
    public function preInsert(Doctrine_Event $event)
    {
        if (!$this->_options['columns']['created']['disabled']) {
            $createdName = $event->getInvoker()->getTable()->getFieldName($this->_options['columns']['created']['name']);
            $modified = $event->getInvoker()->getModified();
            if (!isset($modified[$createdName])) {
                $event->getInvoker()->$createdName = $this->getUserId();
            }
        }

        if (!$this->_options['columns']['updated']['disabled'] && $this->_options['columns']['updated']['onInsert']) {
            $updatedName = $event->getInvoker()->getTable()->getFieldName($this->_options['columns']['updated']['name']);
            $modified = $event->getInvoker()->getModified();
            if (!isset($modified[$updatedName])) {
                $event->getInvoker()->$updatedName = $this->getUserId();
            }
        }
    }

    /**
     * Set updated Blameable column when a record is updated
     *
     * @param Doctrine_Event $event
     *
     * @return void
     */
    public function preUpdate(Doctrine_Event $event)
    {
        if (!$this->_options['columns']['updated']['disabled']) {
            $updatedName = $event->getInvoker()->getTable()->getFieldName($this->_options['columns']['updated']['name']);
            $modified = $event->getInvoker()->getModified();
            if (!isset($modified[$updatedName])) {
                $event->getInvoker()->$updatedName = $this->getUserId();
            }
        }
    }

    /**
     * Set the updated field for dql update queries
     *
     * @param Doctrine_Event $event
     *
     * @return void
     */
    public function preDqlUpdate(Doctrine_Event $event)
    {
        if (!$this->_options['columns']['updated']['disabled']) {
            $params = $event->getParams();
            $updatedName = $event->getInvoker()->getTable()->getFieldName($this->_options['columns']['updated']['name']);
            $field = $params['alias'] . '.' . $updatedName;
            $query = $event->getQuery();

            if (!$query->contains($field)) {
                $query->set($field, '?', $this->getUserId());
            }
        }
    }

    /**
     *
     * @return int
     */
    public function getUserId()
    {
        $provider = Core_Application::get($this->_options['provider']);

        if (!$provider instanceof Core_User_Model_Interface) {
            throw new Exception('Error while getting identity, provider "'. $this->_options['provider'] .'" is not an instance of Core_User_Model_Interface');
        }

        return $provider->getId();
    }
}
