<?php
/**
 * Magento
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Open Software License (OSL 3.0)
 * that is bundled with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://opensource.org/licenses/osl-3.0.php
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@magentocommerce.com so we can send you a copy immediately.
 *
 * DISCLAIMER
 *
 * Do not edit or add to this file if you wish to upgrade Magento to newer
 * versions in the future. If you wish to customize Magento for your
 * needs please refer to http://www.magentocommerce.com for more information.
 *
 * @category    Mage
 * @package     Mage_XmlConnect
 * @copyright   Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
 * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 */

/**
 * XmlConnect review controller
 *
 * @author  Magento Core Team <core@magentocommerce.com>
 */
class Mage_XmlConnect_ReviewController extends Mage_XmlConnect_Controller_Action
{
    /**
     * Initialize and check product
     *
     * @return Mage_Catalog_Model_Product
     */
    protected function _initProduct()
    {
        Mage::dispatchEvent('review_controller_product_init_before', array('controller_action'=>$this));
        $productId  = (int) $this->getRequest()->getParam('id');
        $product = $this->_loadProduct($productId);

        try {
            Mage::dispatchEvent(
                'review_controller_product_init',
                array('product' => $product)
            );
            Mage::dispatchEvent(
                'review_controller_product_init_after',
                array(
                    'product'           => $product,
                    'controller_action' => $this
                )
            );
        } catch (Mage_Core_Exception $e) {
            Mage::logException($e);
            return false;
        }

        return $product;
    }

    /**
     * Load product model with data by passed id.
     * Return false if product was not loaded or has incorrect status.
     *
     * @param int $productId
     * @return bool | Mage_Catalog_Model_Product
     */
    protected function _loadProduct($productId)
    {
        if (!$productId) {
            return false;
        }

        $product = Mage::getModel('catalog/product')
            ->setStoreId(Mage::app()->getStore()->getId())
            ->load($productId);
        /** @var $product Mage_Catalog_Model_Product */
        if (!$product->getId() || !$product->isVisibleInCatalog() || !$product->isVisibleInSiteVisibility()) {
            return false;
        }

        Mage::register('current_product', $product);
        Mage::register('product', $product);

        return $product;
    }

    /**
     * Check if guest is allowed to write review
     *
     * Do check the customer is logged in or guest is allowed to write review
     *
     * @return bool
     */
    protected function _checkGuestAllowed()
    {
        if (Mage::getSingleton('customer/session')->isLoggedIn()
            || Mage::helper('review')->getIsGuestAllowToWrite()
        ) {
            return true;
        }

        $this->_message(
            $this->__('Only registered users can write reviews. Please, log in or register.'),
            self::MESSAGE_STATUS_ERROR
        );
        return false;
    }

    /**
     * Get review form
     *
     * @return void
     */
    public function formAction()
    {
        if (!$this->_checkGuestAllowed()) {
            return;
        }

        $this->loadLayout(false);
        $this->renderLayout();
    }

    /**
     * Save product review
     *
     * @return void
     */
    public function saveAction()
    {
        if (!$this->_checkGuestAllowed()) {
            return;
        }

        $data   = $this->getRequest()->getPost();
        $rating = $this->getRequest()->getPost('ratings', array());

        if (($product = $this->_initProduct()) && !empty($data)) {
            /** @var $review Mage_Review_Model_Review */
            $review     = Mage::getModel('review/review')->setData($data);

            if (($validate = $review->validate()) === true) {
                try {
                    $review->setEntityId($review->getEntityIdByCode(Mage_Review_Model_Review::ENTITY_PRODUCT_CODE))
                        ->setEntityPkValue($product->getId())
                        ->setStatusId(Mage_Review_Model_Review::STATUS_PENDING)
                        ->setCustomerId(Mage::getSingleton('customer/session')->getCustomerId())
                        ->setStoreId(Mage::app()->getStore()->getId())
                        ->setStores(array(Mage::app()->getStore()->getId()))
                        ->save();

                    foreach ($rating as $ratingId => $optionId) {
                        Mage::getModel('rating/rating')
                            ->setRatingId($ratingId)
                            ->setReviewId($review->getId())
                            ->setCustomerId(Mage::getSingleton('customer/session')->getCustomerId())
                            ->addOptionVote($optionId, $product->getId());
                    }

                    $review->aggregate();
                    $this->_message(
                        $this->__('Your review has been accepted for moderation.'),
                        self::MESSAGE_STATUS_SUCCESS
                    );
                } catch (Exception $e) {
                    $this->_message($this->__('Unable to post the review.'), self::MESSAGE_STATUS_ERROR);
                }
            } else {
                if (is_array($validate)) {
                    $this->_message(implode('. ', $validate), self::MESSAGE_STATUS_ERROR);
                } else {
                    $this->_message($this->__('Unable to post the review.'), self::MESSAGE_STATUS_ERROR);
                }
            }
        } else {
            $this->_message($this->__('Unable to post the review.'), self::MESSAGE_STATUS_ERROR);
        }
    }
}
