<?php
/**
 * Pimcore
 *
 * This source file is subject to the GNU General Public License version 3 (GPLv3)
 * For the full copyright and license information, please view the LICENSE.md and gpl-3.0.txt
 * files that are distributed with this source code.
 *
 * @copyright  Copyright (c) 2009-2016 pimcore GmbH (http://www.pimcore.org)
 * @license    http://www.pimcore.org/license     GNU General Public License version 3 (GPLv3)
 */

use Pimcore\Model\Element;
use Pimcore\Model\Asset;
use Pimcore\Model\Document;
use Pimcore\Model\Object;
use Pimcore\Model;

class Admin_ElementController extends \Pimcore\Controller\Action\Admin {
    
    public function lockElementAction()
    {
        Element\Editlock::lock($this->getParam("id"), $this->getParam("type"));
        exit;
    }

    public function unlockElementAction()
    {
        Element\Editlock::unlock($this->getParam("id"), $this->getParam("type"));
        exit;
    }

    public function getIdPathAction() {
        $id = (int) $this->getParam("id");
        $type = $this->getParam("type");

        $response = array("success" => true);

        if($element = Element\Service::getElementById($type, $id)) {
            $response["idPath"] = Element\Service::getIdPath($element);
        }

        $this->_helper->json($response);
    }

    public function getPageAction() {
        $idPath = $this->getParam("idpath");
        $type = $this->getParam("type");
        $size = $this->getParam("size");

        $response = array("success" => true);
        
        $IDs = explode('/', $idPath);
        $elementId = $IDs[count($IDs) - 1];
        $parentId = $IDs[count($IDs) - 2];

        $table = '';
        $id = 'id';
        $key = 'key';
        $parent = 'parentId';
        if ($type == 'customview' || $type == 'object') {
            //check if object is variant and if so shift the IDs one level up...
            $tmp = Object_Concrete::getById($elementId);
            if ($tmp->getType() == Object_Abstract::OBJECT_TYPE_VARIANT) {
                $elementId = $parentId;
                $parentId = $IDs[count($IDs) - 3];
            }
            $table = 'objects';
            $id = 'o_'.$id;
            $key = 'o_'.$key;
            $parent = 'o_'.$parent;
        } elseif ($type == 'document')  {
            $table = 'assets';
        } elseif ($type == 'asset') {
            $table = 'assets';
            $key = 'filename';
        }

        $result = Pimcore_Resource_Mysql::get()->select()->from($table, array($id))->where($parent.' = '.$parentId)->order($key.' asc')->query()->fetchAll(PDO::FETCH_COLUMN);
        $position = array_search($elementId, $result);
        $page = (int)floor($position / $size) + 1;

        $response['page'] = $page;

        $this->_helper->json($response);
    }

    /**
     * Returns the element data denoted by the given type and ID or path.
     */
    public function getSubtypeAction () {

        $idOrPath = trim($this->getParam("id"));
        $type = $this->getParam("type");
        if (is_numeric($idOrPath)) {
            $el = Element\Service::getElementById($type, (int) $idOrPath);
        } else {
            if ($type == "document") {
                $el = Document\Service::getByUrl($idOrPath);
            } else {
                $el = Element\Service::getElementByPath($type, $idOrPath);
            }
        }

        if($el) {
            if($el instanceof Asset || $el instanceof Document) {
                $subtype = $el->getType();
            } else if($el instanceof Object\Concrete) {
                $subtype = $el->getClassName();
            } else if ($el instanceof Object\Folder) {
                $subtype = "folder";
            }

            $this->_helper->json(array(
                "subtype" => $subtype,
                "id" => $el->getId(),
                "type" => $type,
                "success" => true
            ));
        } else {
            $this->_helper->json(array(
                "success" => false
            ));
        }
    }

    public function noteListAction () {

        $this->checkPermission("notes_events");

        $list = new Element\Note\Listing();

        $list->setLimit($this->getParam("limit"));
        $list->setOffset($this->getParam("start"));

        $sortingSettings = \Pimcore\Admin\Helper\QueryParams::extractSortingSettings($this->getAllParams());
        if($sortingSettings['orderKey'] && $sortingSettings['order']) {
            $list->setOrderKey($sortingSettings['orderKey']);
            $list->setOrder($sortingSettings['order']);
        } else {
            $list->setOrderKey(array("date", "id"));
            $list->setOrder(array("DESC", "DESC"));
        }

        $conditions = array();
        if($this->getParam("filter")) {
            $conditions[] = "(`title` LIKE " . $list->quote("%".$this->getParam("filter")."%") . " OR `description` LIKE " . $list->quote("%".$this->getParam("filter")."%") . " OR `type` LIKE " . $list->quote("%".$this->getParam("filter")."%") . ")";
        }

        if($this->getParam("cid") && $this->getParam("ctype")) {
            $conditions[] = "(cid = " . $list->quote($this->getParam("cid")) . " AND ctype = " . $list->quote($this->getParam("ctype")) . ")";
        }

        if(!empty($conditions)) {
            $list->setCondition(implode(" AND ", $conditions));
        }

        $list->load();

        $notes = array();

        foreach ($list->getNotes() as $note) {

            $cpath = "";
            if($note->getCid() && $note->getCtype()) {
                if($element = Element\Service::getElementById($note->getCtype(), $note->getCid())) {
                    $cpath = $element->getFullpath();
                }
            }

            $e = array(
                "id" => $note->getId(),
                "type" => $note->getType(),
                "cid" => $note->getCid(),
                "ctype" => $note->getCtype(),
                "cpath" => $cpath,
                "date" => $note->getDate(),
                "title" => $note->getTitle(),
                "description" => $note->getDescription()
            );

            // prepare key-values
            $keyValues = array();
            if(is_array($note->getData())) {
                foreach ($note->getData() as $name => $d) {

                    $type = $d["type"];
                    $data = $d["data"];

                    if($type == "document" || $type == "object" || $type == "asset") {
                        if($d["data"] instanceof Element\ElementInterface) {
                            $data = array(
                                "id" => $d["data"]->getId(),
                                "path" => $d["data"]->getFullpath(),
                                "type" => $d["data"]->getType()
                            );
                        }
                    } else if ($type == "date") {
                        if($d["data"] instanceof \Zend_Date) {
                            $data = $d["data"]->getTimestamp();
                        }
                    }

                    $keyValue = array(
                        "type" => $type,
                        "name" => $name,
                        "data" => $data
                    );

                    $keyValues[] = $keyValue;
                }
            }

            $e["data"] = $keyValues;


            // prepare user data
            if($note->getUser()) {
                $user = Model\User::getById($note->getUser());
                if($user) {
                    $e["user"] = array(
                        "id" => $user->getId(),
                        "name" => $user->getName()
                    );
                } else {
                    $e["user"] = "";
                }
            }

            $notes[] = $e;
        }

        $this->_helper->json(array(
            "data" => $notes,
            "success" => true,
            "total" => $list->getTotalCount()
        ));
    }

    public function noteAddAction() {

        $this->checkPermission("notes_events");

        $note = new Element\Note();
        $note->setCid((int) $this->getParam("cid"));
        $note->setCtype($this->getParam("ctype"));
        $note->setDate(time());
        $note->setTitle($this->getParam("title"));
        $note->setDescription($this->getParam("description"));
        $note->setType($this->getParam("type"));
        $note->save();

        $this->_helper->json(array(
            "success" => true
        ));
    }

    public function findUsagesAction() {

        if($this->getParam("id")) {
            $element = Element\Service::getElementById($this->getParam("type"), $this->getParam("id"));
        } else if ($this->getParam("path")) {
            $element = Element\Service::getElementByPath($this->getParam("type"), $this->getParam("path"));
        }

        $results = array();
        $success = false;

        if($element) {
            $elements = $element->getDependencies()->getRequiredBy();
            foreach ($elements as $el) {
                $item = Element\Service::getElementById($el["type"], $el["id"]);
                if($item instanceof Element\ElementInterface) {
                    $el["path"] = $item->getFullpath();
                    $results[] = $el;
                }
            }
            $success = true;
        }

        $this->_helper->json(array(
            "data" => $results,
            "success" => $success
        ));
    }

    public function replaceAssignmentsAction() {

        $success = false;
        $message = "";
        $element = Element\Service::getElementById($this->getParam("type"), $this->getParam("id"));
        $sourceEl = Element\Service::getElementById($this->getParam("sourceType"), $this->getParam("sourceId"));
        $targetEl = Element\Service::getElementById($this->getParam("targetType"), $this->getParam("targetId"));

        if($element && $sourceEl && $targetEl
            && $this->getParam("sourceType") == $this->getParam("targetType")
            && $sourceEl->getType() == $targetEl->getType()
        ) {

            $rewriteConfig = array(
                $this->getParam("sourceType") => array(
                    $sourceEl->getId() => $targetEl->getId()
                )
            );

            if($element instanceof Document) {
                $element = Document\Service::rewriteIds($element, $rewriteConfig);
            } else if ($element instanceof Object\AbstractObject) {
                $element = Object\Service::rewriteIds($element, $rewriteConfig);
            } else if ($element instanceof Asset) {
                $element = Asset\Service::rewriteIds($element, $rewriteConfig);
            }

            $element->setUserModification($this->getUser()->getId());
            $element->save();

            $success = true;
        } else {
            $message = "source-type and target-type do not match";
        }

        $this->_helper->json(array(
            "success" => $success,
            "message" => $message
        ));
    }

    public function unlockPropagateAction() {

        $success = false;

        $element = Element\Service::getElementById($this->getParam("type"), $this->getParam("id"));
        if($element) {
            $element->unlockPropagate();
            $success = true;
        }

        $this->_helper->json(array(
            "success" => $success
        ));
    }

    public function typePathAction()
    {
        $id = $this->getParam("id");
        $type = $this->getParam("type");

        if ($type == "asset") {
            $asset = Asset::getById($id);
            $typePath = self::getAssetTypePath($asset);
            $data = array(
                "success" => true,
                "idPath" => Element_Service::getIdPath($asset),
                "typePath" => $typePath
            );
            $this->_helper->json($data);
        } else {
            $object = Object_Abstract::getById($id);
            $typePath = self::getTypePath($object);
            $data = array(
                "success" => true,
                "idPath" => Element_Service::getIdPath($object),
                "typePath" => $typePath
            );
            $this->_helper->json($data);

        }

    }

    public static function getAssetTypePath($element) {

        $path = "";

        if ($element) {
            $parentId = $element->getParentId();
            if ($parentId) {
                $ne = Asset::getById($element->getParentId());
            }
        }

        if ($ne) {
            $path = self::getAssetTypePath($ne, $path);
        }

        if ($element) {
            $path = $path . "/" . $element->getType();
        }

        return $path;
    }



    public static function getTypePath($element) {
        $path = "";

        if ($element) {
            $parentId = $element->getParentId();
            if ($parentId) {
                $ne = Object_Abstract::getById($element->getParentId());
            }
        }

        if ($ne) {
            $path = self::getTypePath($ne, $path);
        }

        if ($element) {
            $path = $path . "/" . $element->getType();
        }

        return $path;
    }

    public function versionUpdateAction()
    {

        $data = \Zend_Json::decode($this->getParam("data"));

        $version = Version::getById($data["id"]);
        $version->setPublic($data["public"]);
        $version->setNote($data["note"]);
        $version->save();

        $this->_helper->json(array("success" => true));
    }


}
