<?php
/*"******************************************************************************************************
*   (c) 2004-2006 by MulchProductions, www.mulchprod.de                                                 *
*   (c) 2007-2013 by Kajona, www.kajona.de                                                              *
*       Published under the GNU LGPL v2.1, see /system/licence_lgpl.txt                                 *
*-------------------------------------------------------------------------------------------------------*
*	$Id: class_element_admin.php 5409 2012-12-30 13:09:07Z sidler $                                      *
********************************************************************************************************/


/**
 * The base class for all page-elements
 *
 * @package module_pages
 * @author sidler@mulchprod.de
 * @abstract
 */
abstract class class_element_admin extends class_admin {

    private $bitDoValidation = false;

    protected $arrParamData = array();

    /**
     * Holds the content generated by the element to be places within the (hidden) system-form
     * elements aka. optional elements.
     *
     * @var string
     */
    private $strSystemFormElements = "";

    /**
     * Constructor
     */
    public function __construct() {

        $this->setArrModuleEntry("moduleId", _pages_elemente_modul_id_);
        $this->setArrModuleEntry("modul", "elements");

        parent::__construct();
    }


    /**
     * Forces the element to return a form and adds als stuff needed by the system to handle the request properly
     *
     * @param string $strMode edit || new
     *
     * @return string
     */
    final public function actionEdit($strMode = "edit") {
        $strReturn = "";
        //Right before we do anything, load the data of the current element
        if($strMode == "edit") {
            $arrElementData = $this->loadElementData();
        }
        else {
            $arrElementData = array();
        }

        //Load the form generated by the element
        $strFormElement = $this->getEditForm(array_merge($arrElementData, $this->getAllParams()));

        //Start by creating the form & action
        $strReturn .= $this->objToolkit->formHeader(getLinkAdminHref("pages_content", "saveElement"), "elEditForm");

        //validation errors?
        if($this->bitDoValidation) {
            $this->validateForm();
        }

        $strReturn .= $this->objToolkit->getValidationErrors($this, "saveElement");


        //add a folder containing optional system-fields
        $strSystemFields = "";
        $bitShow = false;

        $objStartDate = null;
        if(isset($arrElementData["system_date_start"]) && $arrElementData["system_date_start"] > 0) {
            $objStartDate = new class_date($arrElementData["system_date_start"]);
            $bitShow = true;
        }

        $objEndDate = null;
        if(isset($arrElementData["system_date_end"]) && $arrElementData["system_date_end"] > 0) {
            $objEndDate = new class_date($arrElementData["system_date_end"]);
            $bitShow = true;
        }

        $strInternalTitle = (isset($arrElementData["page_element_ph_title"]) ? $arrElementData["page_element_ph_title"] : "");
        if($strInternalTitle != "") {
            $bitShow = true;
        }

        $strSystemFields .= $this->objToolkit->formInputText("page_element_ph_title", $this->getLang("page_element_ph_title", "pages"), $strInternalTitle);

        $strSystemFields .= $this->objToolkit->formDateSingle("start", $this->getLang("page_element_start", "pages"), $objStartDate);
        $strSystemFields .= $this->objToolkit->formDateSingle("end", $this->getLang("page_element_end", "pages"), $objEndDate);

        //add content from sub-classes
        $strSystemFields .= $this->strSystemFormElements;

        $strReturn .= $this->objToolkit->formOptionalElementsWrapper($strSystemFields, $this->getLang("page_element_system_folder", "pages"), $bitShow);

        //Adding the element-stuff
        $strReturn .= $strFormElement;

        //Language is placed right here instead as a hidden field
        if($strMode == "edit") {
            $strReturn .= $this->objToolkit->formInputHidden("page_element_ph_language", $arrElementData["page_element_ph_language"]);
        }
        else {
            $strReturn .= $this->objToolkit->formInputHidden("page_element_ph_language", $this->getLanguageToWorkOn());
        }

        $strReturn .= $this->objToolkit->formInputHidden("placeholder", $this->getParam("placeholder"));
        $strReturn .= $this->objToolkit->formInputHidden("systemid", $this->getSystemid());
        $strReturn .= $this->objToolkit->formInputHidden("mode", $strMode);
        $strReturn .= $this->objToolkit->formInputHidden("element", $this->getParam("element"));
        //An finally the submit Button
        $strEventhandler = "";
        if($this->getParam("pe") == 1) {
            $strReturn .= $this->objToolkit->formInputHidden("peClose", "1");
        }
        $strReturn .= $this->objToolkit->formInputSubmit($this->getLang("commons_save"), "Submit", $strEventhandler);
        $strReturn .= $this->objToolkit->formClose();
        //and close the element


        return $strReturn;
    }

    /**
     * Loads the data of the current element
     *
     * @return mixed
     */
    public final function loadElementData() {
        //Element-Table given?
        if(isset($this->arrModule["table"]) && $this->arrModule["table"] != "") {
            $strQuery = "SELECT *
    					 FROM " . $this->arrModule["table"] . ",
    					 	  " . _dbprefix_ . "element,
    					 	  " . _dbprefix_ . "page_element,
    					 	  " . _dbprefix_ . "system
    					 LEFT JOIN " . _dbprefix_ . "system_date
    					    ON (system_id = system_date_id)
    					 WHERE element_name = page_element_ph_element
    					   AND page_element_id = content_id
    					   AND system_id = content_id
    					   AND system_id = ? ";
        }
        else {
            $strQuery = "SELECT *
    					 FROM " . _dbprefix_ . "element,
    					 	  " . _dbprefix_ . "page_element,
    					 	  " . _dbprefix_ . "system
    					 LEFT JOIN " . _dbprefix_ . "system_date
    					    ON (system_id = system_date_id)
    					 WHERE element_name = page_element_ph_element
    					   AND page_element_id = system_id
    					   AND system_id = ? ";

        }
        $arrElement = $this->objDB->getPRow($strQuery, array($this->getSystemid()));

        return $arrElement;
    }


    public function updateForeignElement() {
        $strElementTableColumns = $this->getArrModule("tableColumns");
        if($strElementTableColumns != "") {

            //open new tx
            $this->objDB->transactionBegin();

            $arrElementParams = $this->getArrParamData();

            $arrTableRows = explode(",", $strElementTableColumns);
            if(count($arrTableRows) > 0) {
                $arrInserts = array();
                $arrParams = array();

                foreach($arrTableRows as $strTableColumnName) {

                    $strColumnValue = "";
                    if(isset($arrElementParams[$strTableColumnName])) {
                        $strColumnValue = $arrElementParams[$strTableColumnName];
                    }

                    $arrParams[] = $strColumnValue;
                    $arrInserts[] = " " . $this->objDB->encloseColumnName($strTableColumnName) . " = ? ";
                }

                $strRowUpdates = implode(", ", $arrInserts);
                $strUpdateQuery =
                    " UPDATE " . $this->getTable() . " SET "
                        . $strRowUpdates .
                        " WHERE content_id= ? ";

                $arrParams[] = $this->getSystemid();

                if(!$this->objDB->_pQuery($strUpdateQuery, $arrParams)) {
                    $this->objDB->transactionRollback();
                }
                else {
                    $this->objDB->transactionCommit();
                }
            }
            else {
                throw new class_exception("Element has invalid tableRows value!!!", class_exception::$level_ERROR);
            }
        }
        else {
            //To remain backwards-compatible:
            //Call the save-method of the element instead or if the element wants to update its data specially
            if(method_exists($this, "actionSave") && !$this->actionSave($this->getSystemid())) {
                throw new class_exception("Element returned error saving to database!!!", class_exception::$level_ERROR);
            }
        }
    }

    /**
     * returns the table used by the element
     *
     * @return string
     */
    public function getTable() {
        return $this->getArrModule("table");
    }

    /**
     * The label of the first config-value.
     * Overwrite this method if the element makes use of a config-value.
     * The value itself may be read by accessing the instance of class_module_pages_pageelement
     * out of the admin-/portal-element-instance directly.
     *
     * @return string
     */
    public function getConfigVal1Name() {
        return "";
    }

    /**
     * The label of the second config-value.
     * Overwrite this method if the element makes use of a config-value.
     * The value itself may be read by accessing the instance of class_module_pages_pageelement
     * out of the admin-/portal-element-instance directly.
     *
     * @return string
     */
    public function getConfigVal2Name() {
        return "";
    }

    /**
     * The label of the third config-value.
     * Overwrite this method if the element makes use of a config-value.
     * The value itself may be read by accessing the instance of class_module_pages_pageelement
     * out of the admin-/portal-element-instance directly.
     *
     * @return string
     */
    public function getConfigVal3Name() {
        return "";
    }

    /**
     * Returns a short description of the saved content
     * Overwrite if needed
     *
     * @return string
     */
    public function getContentTitle() {
        return "";
    }


    /**
     * Returns a textual description of the current element, based
     * on the lang key element_description.
     *
     * @return string
     * @since 3.2.1
     */
    public function getElementDescription() {
        $strDesc = $this->getLang($this->arrModule["name"] . "_description");
        if($strDesc == "!" . $this->arrModule["name"] . "_description!") {
            $strDesc = "";
        }
        return $strDesc;
    }

    /**
     * Overwrite this method, if you want to execute
     * some special actions right after saving the element to the db, e.g.
     * cleanup functions.
     *
     * @since 3.2.1
     * @return void
     */
    public function doAfterSaveToDb() {
    }

    /**
     * Overwrite this method if you want to modify the params to be saved to the
     * database or run other actions right before the element is saved back to the database.
     *
     * @since 3.4.0
     * @return void
     */
    public function doBeforeSaveToDb() {
    }

    /**
     * If the form generated should be validated, pass true. This invokes
     * the internal validation and printing of errors.
     * By default, the value is false. The framework sets the value, so there's no
     * need to call this setter in concrete element classes.
     *
     * @param bool $bitDoValidation
     */
    public final function setDoValidation($bitDoValidation) {
        $this->bitDoValidation = $bitDoValidation;
    }

    /**
     * Sub-classes can use this method to add content to the system-form.
     * Elements in the system-form are hidden by default.
     * Using this form-section is usefull for mostly unused settings.
     *
     * @param string $strContent
     *
     * @since 3.3
     */
    protected final function addOptionalFormElement($strContent) {
        $this->strSystemFormElements .= $strContent;
    }


    /**
     * Returns the array of parameters passed by the request
     *
     * @return array
     */
    public function getArrParamData() {
        return $this->arrParamData;
    }

    /**
     * Sets the array of parameters passed by the request
     *
     * @param array $arrParamData
     */
    public function setArrParamData($arrParamData) {
        $this->arrParamData = $arrParamData;
    }

}

