<?php

/**
 * Core_Doctrine_Model_SitemapTable
 *
 * This class has been auto-generated by the Doctrine ORM Framework
 */
class Core_Doctrine_Model_SitemapTable extends Core_Doctrine_Table implements
    Core_Router_Route_Plugin_Model_Interface,
    Core_Doctrine_Table_Interface
{
    const CONTENT_TYPE_ID = 3;

    /**
     * Display related content as listing
     */
    const TYPE_LISTING  = 1;

    /**
     * Display related content as grid
     */
    const TYPE_GRID     = 2;

    /**
     * Display widgetized layout
     */
    const TYPE_WIDGET   = 3;

    /**
     * Display content which is wysiwyg
     */
    const TYPE_WYSIWYG  = 4;

    /**
     * Display content which is markup
     */
    const TYPE_MARKUP   = 5;

    /**
     * Display content which is redirect to first content
     */
    const TYPE_REDIRECT_CONTENT   = 6;

    /**
     * Display content which is redirect to first child
     */
    const TYPE_REDIRECT_CHILD   = 7;

    /**
     * Display content which is redirect to static url
     */
    const TYPE_REDIRECT_URL   = 8;
    
    /**
     * Display login page
     */
    const TYPE_LOGIN   = 9;

    /**
     * Returns an instance of this class.
     *
     * @return object SitemapTable
     */
    public static function getInstance()
    {
        return Doctrine_Core::getTable('Sitemap');
    }

    /**
     * Get display types for Sitemap nodes (these are defaults)
     *
     * @return array
     */
    public function getTypes()
    {
        $types = array(
            self::TYPE_LISTING          => array(
                'id'    => self::TYPE_LISTING,
                'title' => 'Listing',
            ),
            self::TYPE_GRID             => array(
                'id'    => self::TYPE_GRID,
                'title' => 'Grid',
            ),
            self::TYPE_WIDGET           => array(
                'id'    => self::TYPE_WIDGET,
                'title' => 'Widget',
            ),
            self::TYPE_WYSIWYG          => array(
                'id'    => self::TYPE_WYSIWYG,
                'title' => 'WYSIWYG',
            ),
            self::TYPE_MARKUP           => array(
                'id'    => self::TYPE_MARKUP,
                'title' => 'Markup',
            ),
            self::TYPE_REDIRECT_CONTENT => array(
                'id'    => self::TYPE_REDIRECT_CONTENT,
                'title' => 'Redirect - first content',
            ),
            self::TYPE_REDIRECT_CHILD   => array(
                'id'    => self::TYPE_REDIRECT_CHILD,
                'title' => 'Redirect - first child',
            ),
            self::TYPE_REDIRECT_URL     => array(
                'id'    => self::TYPE_REDIRECT_URL,
                'title' => 'Redirect - static URL'
            ),
            self::TYPE_LOGIN     => array(
                'id'    => self::TYPE_LOGIN,
                'title' => 'Login form'
            )
        );

        return $types;
    }

    /**
     * Match route according to sitemap slug
     * - used by Core_Router_Module
     *
     * @param   array   $values
     * @return  array
     */
    public function match(array $values)
    {
        $q = $this->createQuery('s');
        $q->select('s.*')
            ->where('s.path = ?', (string) $values['path']);

        //$language = Core_Application::getInstance()->getLanguage();
        $language = $values['lang'];

        if (strlen($language) && isset(Core_Application::get('Config')->app->languages->$language)) {
            $language_id  = Core_Application::get('Config')->app->languages->$language->id;
            $q->andWhere('s.language_id = ?', $language_id);
        }

        $params = array();
        $node   = $q->fetchOne();
        $security = Core_Application::get('Security');
        $user = Core_Application::get('User');

        // print_r($user);
        if ($node) {
            if (!($security->isAllowed($user, $node))) {
                throw new Core_Application_UnauthorizedException;
            }

            $params = compact('node');

            // this changes module so proper node types are dispatched to proper modules/views/etc.
            $contentTypes = $this->getContentTypes();

            if (isset($contentTypes[$node['related_content_id']])) {
                $contentType = $contentTypes[$node['related_content_id']];
            } else {
                $contentType = $contentTypes[self::CONTENT_TYPE_ID];
            }

            // Take only that which you need, otherwise, id url param might be replaced
            // with content type id
            $contentType = array_intersect_key($contentType, array(
                'module'        => true,
                'controller'    => true,
                'action'        => true,
                'model'         => true
            ));

            $params = array_merge($params, $contentType);
        }

        return $params;
    }

    public function save(Doctrine_Record $entity)
    {
        $config = Core_Application::get('resourceFinder')
            ->find('sharedForm', new Core_Dispatcher_Location, array('name' => 'sitemap.yml'));
        $this->_validate($entity, $config);

        $new = $entity->id === null;

        $versionOption  = $entity->getAuditLog()->getOption('version');
        $versionName    = $versionOption['alias'] === null ? $versionOption['name'] : $versionOption['alias'];

        if (isset($entity->$versionName) && $entity->$versionName > 0) {
            $saveMethod = 'update';
        } else {
            $saveMethod = 'save';
        }

        $parentNode = isset($entity->parent_id) && $entity->parent_id > 0 ? $this->find($entity->parent_id) : false;
        $entity->parent_id = $parentNode ? $parentNode->id : null;

        $entity->$saveMethod();

        if ($parentNode) {
            // Child
            $entity->insertAsLastChildOf($parentNode);
        } elseif ($new) {
            // Create root only if entity is new, else don't touch
            /* @var $treeObject Doctrine_Tree_NestedSet  */
            $treeObject = $this->getTree();
            $treeObject->createRoot($entity);
        }

        if ($new) {
            // Revert to first version, delete second version
            $data = $entity->toArray();
            unset($data['version']);
            $entity->revert(1);

            $entity->fromArray($data);
            $entity->update();
            $entity->deleteVersion(2);
        }

        return $entity;
    }
}