<?php

class Core_Doctrine_Template_Blameable extends Doctrine_Template
{
    /**
     * Array of Blameable options
     *
     * @var string
     */
    protected $_options = array(
        'listener'      => 'Core_Doctrine_Template_Listener_Blameable',
        'provider'      => 'user',
        'default'       => false,
        'columns'       => array(
            'created' => array(
                'name'          =>  'created_by',
                'alias'         =>  null,
                'type'          =>  'integer',
                'length'        =>  8,
                'disabled'      =>  false,
                'options'       =>  array('notnull' => true,)
            ),
            'updated' =>  array(
                'name'          =>  'updated_by',
                'alias'         =>  null,
                'type'          =>  'integer',
                'length'        =>  8,
                'disabled'      =>  false,
                'onInsert'      =>  true,
                'options'       =>  array('notnull' => true,)
            )
        ),
        'relations'     => array(
            'created' => array(
                'disabled'  => true,
                'name'      => 'CreatedBy',
                'class'     => 'User',
                'foreign'   => 'user_id',
            ),
            'updated' => array(
                'disabled'  => true,
                'name'      => 'UpdatedBy',
                'class'     => 'User',
                'foreign'   => 'user_id',
            ),
    ));

    /**
     * __construct
     *
     * @param array $options
     *
     * @return void
     */
    public function __construct(array $options = array())
    {

        if (!class_exists($this->_options['listener'], true)) {
            throw new Exception('Class: ' . $this->_options['listener'] . ' not found');
        }

        parent::__construct($options);

    }

    /**
     * Set table definition for Blameable behavior
     *
     * @return void
     */
    public function setTableDefinition()
    {
        if( ! $this->_options['columns']['created']['disabled']) {
            $name = $this->_options['columns']['created']['name'];
            if ($this->_options['columns']['created']['alias']) {
                $name .= ' as ' . $this->_options['columns']['created']['alias'];
            }
            $this->hasColumn(
                    $name,
                    $this->_options['columns']['created']['type'],
                    $this->_options['columns']['created']['length'],
                    $this->_options['columns']['created']['options']
            );
        }

        if( ! $this->_options['columns']['updated']['disabled']) {
            $name = $this->_options['columns']['updated']['name'];
            if ($this->_options['columns']['updated']['alias']) {
                $name .= ' as ' . $this->_options['columns']['updated']['alias'];
            }

            if (
                $this->_options['columns']['updated']['onInsert'] !== true &&
                $this->_options['columns']['updated']['options']['notnull'] === true
            ) {
                $this->_options['columns']['updated']['options']['notnull'] = false;
            }

            $this->hasColumn(
                $name,
                $this->_options['columns']['updated']['type'],
                $this->_options['columns']['updated']['length'],
                $this->_options['columns']['updated']['options']
            );
        }

        $listenerClass = $this->_options['listener'];
        $listener = new $listenerClass($this->_options);

        if (!$listener instanceof Core_Doctrine_Template_Listener_Blameable) {
            throw new Exception('Invalid listener. Must be instance of Core_Doctrine_Template_Listener_Blameable');
        }

        $this->addListener($listener, 'Blameable');
    }

    /**
     * Setup the relations for the Blameable behavior
     *
     * @return void
     */
    public function setUp()
    {

        if (!$this->_options['relations']['created']['disabled']) {
            $this->hasOne(
                $this->_options['relations']['created']['class'] . ' as ' . $this->_options['relations']['created']['name'],
                array(
                    'local' => $this->_options['columns']['created']['name'],
                    'foreign' => $this->_options['relations']['created']['foreign'],
                )
            );
        }

        if (!$this->_options['relations']['updated']['disabled'] && !$this->_options['columns']['updated']['disabled']) {
            $this->hasOne(
                $this->_options['relations']['updated']['class'] . ' as ' . $this->_options['relations']['updated']['name'],
                array(
                    'local' => $this->_options['columns']['updated']['name'],
                    'foreign' => $this->_options['relations']['updated']['foreign'],
                )
            );
        }
    }
}
