<?php
/**
 * Implementation of blog administration controller for categories
 *
 * @package koubel homepage
 * @author Miroslav Kubelik (koubel@volny.cz)
 * @copyright Copyright (c) 2007-2009 Miroslav Kubelik
 * @license http://opensource.org/licenses/gpl-license.php GNU GPL
 */

/**
 * Serves administration actions for blog categories
 *
 * @package koubel homepage
 * @author Miroslav Kubelik (koubel@volny.cz)
 * @copyright Copyright (c) 2007-2009 Miroslav Kubelik
 * @license http://opensource.org/licenses/gpl-license.php GNU GPL
 */
class Blog_Admin_CategoryController extends Zend_Controller_Action
{

    /**
     * List of categories
     */
    public function indexAction()
    {
        $category = new Blog_Model_Category();
        $itemsCount = $category->getCount();
        $this->view->categoryCount = $itemsCount;
        if ($itemsCount) {
            $this->view->categories = $category->getAll();
        }
        
        if ($this->_helper->flashMessenger->hasMessages()) {
            $this->view->messages=$this->_helper->flashMessenger->getMessages();
        }
    }

    /**
     * Views a dialog for an addition of a new category.
     * It is used as target for the forward or redirect from the another actions,
     * hence it can set a form data from an old request, which will not serve in
     * another actions.
     */
    public function addAction()
    {
        if ($this->_helper->flashMessenger->hasMessages()) {
            $this->view->messages=$this->_helper->flashMessenger->getMessages();
        }

        //in POST are old data, it occures when current submitted data are
        //invalid, so we print old data in form, user can corrects these.
        if (isset($_POST["name"])) {
            $data=$_POST;
            $this->view->formData=$data;
        } else $this->view->formData=array();
    }

    /**
     * Action, which is as aim for the reciving of the add new category dialog
     * data.
     * It tries to save a new category into the database, if something fails,
     * forwards to the addAction. If additions was OK, redirects
     * to the addAction with some flash message.
     */
    public function addToDbAction()
    {
        // Don't auto render
        $this->_helper->viewRenderer->setNoRender();
        $data=$_POST;

        $inputFilter=self::getCategoryFormFilter();
        $inputFilter->setData($data);

        if ($inputFilter->isValid()) {
            $name=$inputFilter->getUnescaped("name");
            $titleUrl=$inputFilter->titleURL;

            $category = new Blog_Model_Category();

            try {
                $category->setName($name);
                $category->setTitleUrl($titleUrl);
                $category->insert();
            } catch (Zend_Db_Exception $e) {
                $message="Cannot save record, database error: ".$e->getMessage();
                $this->view->messages=array($message);
                $this->_forward("add");
                return;
            }

            $newEntryUrl = $this->_helper->url->url(
                array(
                    "controller" => "category",
                    "action" => "edit",
                    "itemId" => $category->getId()
                ),
                "blogAdminItemAction"
            );
            $message="Record <a href=\"".$newEntryUrl."\">$name</a> saved. Now, you can "
                . "<a href=\""
                . $this->_helper->url->url(
                    array("controller" => "category",
                        "action" => "edit-articles",
                        "itemId" => $category->getId()
                    ),
                    "blogAdminItemAction")
                . "\">add</a> some articles into this category.";
            $this->_helper->flashMessenger->addMessage($message);
            $this->_helper->redirector->setGoto("add");
            $this->_helper->redirector->redirectAndExit();
            return;

        } else {
            //invalid data
            $messages[]="Data are invalid:";
            $messages=array_merge($messages,MKLib_Utils::getMessagesOneArray($inputFilter));
            $this->view->messages=$messages;
            $this->_forward("add");
            return;
        }
    }

    /**
     * Prepares and returns input filter for the category entry dialog.
     * @return Zend_Filter_Input
     */
    public static function getCategoryFormFilter()
    {
        $filters = array(
            'name'   => 'StringTrim',
            'titleURL' => 'StringTrim'
        );

        $validators = array(
            'name'   => 'NotEmpty',
            'titleURL'   => array('NotEmpty',new Zend_Validate_Regex("/\w+/"))
        );

        $input = new Zend_Filter_Input($filters, $validators);
        return $input;
    }

    /**
     * Views a dialog for an edit category page with a form.
     * It is used as target for the forward or redirect from the another actions, hence
     * it can set a form data from an old request, which will not serve in another actions.
     */
    public function editAction()
    {
        $category = new Blog_Model_Category();

        //in POST are old data, it occures when current submitted data are invalid, so
        //we print old data in form, user can corrects these.
        if (isset($_POST["categoryId"])) {
            $data = $_POST;
            $this->view->formData = $data;
            $this->view->formData["id"] = $data["categoryId"];
            $category->findById($data["categoryId"]);
        } else {
            //no old data, gets data from database
            $category->findById( $this->_getParam("itemId") );
            $this->view->formData = $category->getDaoRow(false)->toArray();
        }

        $this->view->articleCount = $category->getArticleCount();

        if ($this->_helper->flashMessenger->hasMessages()) {
            $this->view->messages=$this->_helper->flashMessenger->getMessages();
        }
    }

    /**
     * Updates category in the database.
     * If something fails, forwards to the editCategoryAction. If the database update  was OK, redirects
     * to the editCategoryAction with some flash message.
     */
    public function updateDbAction()
    {
        // Don't auto render
        $this->_helper->viewRenderer->setNoRender();
        $data = $_POST;

        $inputFilter = self::getCategoryFormFilter();
        $inputFilter->setData($data);

        if ($inputFilter->isValid()) {
            $name = $inputFilter->name;
            $titleUrl = $inputFilter->titleURL;

            $category = new Blog_Model_Category();

            try {
                $category->setId($data["categoryId"]);
                $category->setName($name);
                $category->setTitleUrl($titleUrl);
                $category->update();
            } catch (Zend_Db_Exception $e) {
                $message = "Cannot update record, database error: ".$e->getMessage();
                $this->view->messages=array($message);
                $this->_forward("edit");
                return;
            }

            $message="Record was updated";
            $this->_helper->flashMessenger->addMessage($message);
            $this->_helper->redirector->gotoUrlAndExit($this->_helper->url->url(
                array(
                    "controller" => "category",
                    "action" => "edit",
                    "itemId" => $category->getId()
                ),"blogAdminItemAction"),
                array("prependBase"=>false)
            );
            return;

        } else {
            //invalid data
            $messages[] = "Data are invalid:";
            $messages = array_merge($messages,MKLib_Utils::getMessagesOneArray($inputFilter));
            $this->view->messages = $messages;
            $this->_forward("edit");
            return;
        }
    }

    /**
     * Action, which is complete responsible for a removing category from the database.
     * It views dialog for the confirmation, than if we realy want delete item and
     * serves database removing also.
     */
    public function deleteAction()
    {
        $category = new Blog_Model_Category();
        $itemId = $this->_getParam("itemId");
        $currentCategory = $category->findById($itemId);

        //"really want" delete flag
        $delflag = false;

        //confirmation was send
        if (isset($_GET['wantdel']))
        {
            //No - redirect to category list
            if ($_GET['wantdel']=="No") {
                $this->_helper->redirector->gotoUrlAndExit($this->_helper->url->url(
                    array(
                        "controller" => "category",
                        "action" => "index",
                    ),"blogAdmin"),array("prependBase"=>false));
                return;
            }
            //Yes - delete
            $delflag = $_GET['wantdel']=="Yes" ? true : false;
        }

        //if really want delete, make it
        if ($delflag) {
            //delete from database
            try {
                $category->delete();
            } catch (Zend_Db_Exception $e) {
                $message = "Cannot delete record, database error: ".$e->getMessage();
                $this->_helper->flashMessenger->addMessage($message);
                $this->_helper->redirector->gotoUrlAndExit($this->_helper->url->url(
                    array(
                        "controller" => "category",
                        "action" => "delete",
                        "itemId" => $category->getId()
                    ),"blogAdminItemAction"),
                    array("prependBase"=>false));
                return;
            }

            //redirect after successful deleting
            $this->_helper->flashMessenger->addMessage("Category with ID: ".$category->getId()
                . " name: ".$category->getName()." was deleted");
            $this->_helper->redirector->gotoUrlAndExit($this->_helper->url->url(
                    array(
                        "controller" => "category",
                        "action" => "index",
                    ),"blogAdmin"),array("prependBase"=>false));
            return;
        }

        $this->view->subject = "blog category ".$category->getId()." ".$category->getName();
        $this->view->nextInfo = "Be aware, when you delete a category, all atricles"
            . " and their comments will be deleted also.";

        $this->view->wasDeleted = $delflag;
        //delete url
        $this->view->deleteUrl = $this->_helper->url->url(
            array(
                "controller" => "category",
                "action" => "delete",
                "itemId" => $category->getId()
            ),"blogAdminItemAction");

        if ($this->_helper->flashMessenger->hasMessages()) {
            $this->view->messages = $this->_helper->flashMessenger->getMessages();
        }

        $this->_helper->viewRenderer->setRender("admin/deleteItem",null,true);
    }

    /**
     * Views a dialog for a form, which is responsible for the adding and removing
     * articles from one particular category. It also servers database operation, when form
     * is submitted.
     */
    public function editArticlesAction()
    {
        $category = new Blog_Model_Category();

        $category->findById( $this->_getParam("itemId") );
        $this->view->category = $category;

        //data was send
        if (isset($_POST["action"])) {
            $data=$_POST;
            try {
                $category->updateArticles( isset($data["assigned"]) ? $data["assigned"] : array() );
            } catch (Zend_Db_Exception $e) {
                unset($_POST["action"]);
                $message="Cannot update record, database error: ".$e->getMessage();
                $this->view->messages = array($message);
                $this->_forward("edit-articles");
                return;
            }

            $message = "Articles for this category were updated.";
            $this->_helper->flashMessenger->addMessage($message);
            $this->_helper->redirector->gotoUrlAndExit(
                $this->_helper->url->url(
                    array(
                        "controller" => "category",
                        "action" => "edit-articles",
                        "itemId" => $category->getId()
                    ),
                    "blogAdminItemAction"
                ),
                array("prependBase"=>false));
            return;
        }

        $this->view->categoryArticles = $category->getArticles();

        $article = new Blog_Model_Article();
        $this->view->allArticles = $article->getAll();

        if ($this->_helper->flashMessenger->hasMessages()) {
            $this->view->messages=$this->_helper->flashMessenger->getMessages();
        }
    }
}
