qcubed/framework

View on GitHub
includes/base_controls/QBlockControl.class.php

Summary

Maintainability
D
1 day
Test Coverage
<?php
    /**
     * This file contains the QBlockControl class.
     * 
     * @package Controls
     */

    /**
     * This abstract class is designed to be a base for class for span and div controls. It adds additional drag and
     * drop support to these objects, as well as templating.
     *
     * @package Controls
     *
     * @property string $Text is the Html that you want rendered
     * @property string $Format is a sprintf string that the Text property will be sent to for further formatting.
     * @property string $Template Path to the HTML template (.tpl.php) file (applicable in case a template is being used for Render)
     * @property boolean $AutoRenderChildren Render the child controls of this control automatically
     * @property string $TagName HTML tag to be used by the control (such as div or span)
     * @property boolean $HtmlEntities hould htmlentities be used on the contents of this control
     * @property boolean $DropTarget Is this a drop target?
     * @property string $HorizontalAlign
     * @property string $VerticalAlign
     * @property integer $ResizeHandleMinimum
     * @property integer $ResizeHandleMaximum
     * @property string $ResizeHandleDirection
     */
    abstract class QBlockControl extends QControl {
        ///////////////////////////
        // Private Member Variables
        ///////////////////////////

        // APPEARANCE
        /** @var string The text on the control */
        protected $strText = null;
            /** @var string The format specifier for rendering the control  */
        protected $strFormat = null;
        /** @var string Path to the HTML template (.tpl.php) file (applicable in case a template is being used for Render) */
        protected $strTemplate = null;
        /** @var bool Render the child controls of this control automatically? */
        protected $blnAutoRenderChildren = false;
        /** @var string HTML tag to be used by the control (such as div or span) */
        protected $strTagName = null;
        /** @var bool Should htmlentities be used on the contents of this control? */
        protected $blnHtmlEntities = true;

        // BEHAVIOR
        /** @var bool Is it a drop target? */
        protected $blnDropTarget = false;

        // Move Targets and Drop Zones
        protected $objMovesControlsArray = array();
        protected $objDropsControlsArray = array();
        protected $objDropsGroupingsArray = array();
        protected $objIsDropZoneFor = array();

        public function AddControlToMove($objTargetControl = null) {        
            $this->strJavaScripts = __JQUERY_EFFECTS__;
            if($objTargetControl && $objTargetControl->ControlId != $this->ControlId) {
                QApplication::ExecuteJavascript(sprintf('var pos_%s = $j("#%s").offset()', $objTargetControl->ControlId, $objTargetControl->ControlId));
                QApplication::ExecuteJavascript(sprintf('$j("#%s").on("drag",  function (ev, ui) { p = $j("#%s").offset(); p.left = pos_%s.left + ui.position.left; p.top = pos_%s.top + ui.position.top; $j("#%s").offset(p); } );', $this->strControlId,    $objTargetControl->ControlId,  $objTargetControl->ControlId,  $objTargetControl->ControlId, $objTargetControl->ControlId ));
                $this->objMovesControlsArray[$objTargetControl->ControlId] = true;

                // TODO:
                // Replace ExecuteJavascript with this:
                //$this->AddAttributeScript('qcubed', 'ctrlToMove', $objTargetControl->ControlId);
            }
            return;
        }

        public function RemoveControlToMove(QControl $objTargetControl) {
            unset($this->objMovesControlsArray[$objTargetControl->ControlId]);
        }

        public function RemoveAllControlsToMove() {
            $this->objMovesControlsArray = array();
            $this->RemoveAllDropZones();
        }

        public function AddDropZone($objParentObject) {
            $this->strJavaScripts = __JQUERY_EFFECTS__;
            $this->objDropsControlsArray[$objParentObject->ControlId] = true;
            $objParentObject->DropTarget = true;
            $objParentObject->objIsDropZoneFor[$this->ControlId] = true;            
        }

        public function RemoveDropZone($objParentObject) {
            if ($objParentObject instanceof QForm) {
                $this->objDropsControlsArray[$objParentObject->FormId] = false;
            } else if ($objParentObject instanceof QBlockControl) {
                $this->objDropsControlsArray[$objParentObject->ControlId] = false;
                $objParentObject->objIsDropZoneFor[$this->ControlId] = false;
            } else
                throw new QCallerException('ParentObject must be either a QForm or QBlockControl object');
        }

        public function RemoveAllDropZones() {
            QApplication::ExecuteControlCommand($this->strControlId, 'draggable', "option", "revert", "invalid");

            foreach ($this->objDropsControlsArray as $strControlId => $blnValue) {
                if ($blnValue) {
                    $objControl = $this->objForm->GetControl($strControlId);
                    if ($objControl)
                        $objControl->objIsDropZoneFor[$this->ControlId] = false;
                }
            }
            $this->objDropsControlsArray = array();
        }

        /**
         * Returns the End Script of the Control which is sent to the client when the control's Render is complete
         * @return string The JS EndScript for the control
         */
        public function GetEndScript() {
            $strToReturn = parent::GetEndScript();
            
            // DROP ZONES
            foreach ($this->objDropsControlsArray as $strKey => $blnIsDropZone) {
                if ($blnIsDropZone) {
                    QApplication::ExecuteControlCommand($strKey, 'droppable');
                }
            }

            foreach ($this->objIsDropZoneFor as $strKey => $blnIsDropZone) {
                if ($blnIsDropZone) {
                    $objControl = $this->objForm->GetControl($strKey);
                    if ($objControl && ($objControl->strRenderMethod)) {
                        QApplication::ExecuteControlCommand($this->strControlId, 'droppable', 'option', 'accept', '#' . $strKey);
                    }
                }
            }

            return $strToReturn;
        }

        //////////
        // Methods
        //////////
        /**
         * Public function (to be overridden in child classes) to Parse the POST data recieved by control
         */
        public function ParsePostData() {}


        /**
         * Returns the HTML of the QControl
         * @return string The HTML string
         */
        protected function GetControlHtml() {

            $strToReturn = $this->RenderTag($this->strTagName,
                null,
                null,
                $this->GetInnerHtml());

//            if ($this->blnDropTarget)
//                $strToReturn .= sprintf('<span id="%s_ctldzmask" style="position:absolute;"><span style="font-size: 1px">&nbsp;</span></span>', $this->strControlId);

            return $strToReturn;
        }

        /**
         * Return the inner html between the tags.
         *
         * @return string
         */
        protected function GetInnerHtml() {
            if ($this->strFormat) {
                $strText = sprintf($this->strFormat, $this->strText);
            }
            else {
                $strText = $this->strText;
            }

            if ($this->blnHtmlEntities) {
                $strText = QApplication::HtmlEntities($strText);
            }

            $strTemplateEvaluated = '';
            if ($this->strTemplate) {
                global $_CONTROL;
                $objCurrentControl = $_CONTROL;
                $_CONTROL = $this;
                $strTemplateEvaluated = $this->EvaluateTemplate($this->strTemplate);
                $_CONTROL = $objCurrentControl;
            }

            $strText .= $strTemplateEvaluated;

            if ($this->blnAutoRenderChildren) {
                $strText .= $this->RenderChildren(false);
            }
            return $strText;
        }

        /**
         * Public function to be overrriden by child classes
         *
         * It is used to determine if the input fed into the control is valid or not.
         * The rules are written in this function only. If the control is set for Validation,
         * this function is automatically called on postback.
         * @return bool Whether or not the input inside the control are valid
         */
        public function Validate() {return true;}

        /////////////////////////
        // Public Properties: GET
        /////////////////////////
        /**
         * PHP __get magic method implementation
         * @param string $strName Name of the property
         *
         * @return mixed
         * @throws Exception|QCallerException
         */
        public function __get($strName) {
            switch ($strName) {
                // APPEARANCE
                case "Text": return $this->strText;
                case "Format": return $this->strFormat;
                case "Template": return $this->strTemplate;
                case "AutoRenderChildren": return $this->blnAutoRenderChildren;
                case "TagName": return $this->strTagName;
                case "HtmlEntities": return $this->blnHtmlEntities;

                // BEHAVIOR
                case "DropTarget": return $this->blnDropTarget;

                default:
                    try {
                        return parent::__get($strName);
                    } catch (QCallerException $objExc) {
                        $objExc->IncrementOffset();
                        throw $objExc;
                    }
            }
        }

        /////////////////////////
        // Public Properties: SET
        /////////////////////////
        /**
         * PHP __set magic method implementation
         * @param string $strName Property Name
         * @param string $mixValue Property Value
         *
         * @return mixed
         * @throws Exception|QCallerException|QInvalidCastException
         */
        public function __set($strName, $mixValue) {
            switch ($strName) {
                // APPEARANCE
                case "Text":
                    try {
                        if ($this->strText !== ($mixValue = QType::Cast($mixValue, QType::String))) {
                            $this->blnModified = true;
                            $this->strText = $mixValue;
                        }
                        break;
                    } catch (QInvalidCastException $objExc) {
                        $objExc->IncrementOffset();
                        throw $objExc;
                    }

                case "Format":
                    try {
                        if ($this->strFormat !== ($mixValue = QType::Cast($mixValue, QType::String))) {
                            $this->blnModified = true;
                            $this->strFormat = $mixValue;
                        }
                        break;
                    } catch (QInvalidCastException $objExc) {
                        $objExc->IncrementOffset();
                        throw $objExc;
                    }

                case "Template":
                    try {
                        $this->blnModified = true;
                        if ($mixValue) {
                            if (file_exists($strPath = $this->GetTemplatePath($mixValue))) {
                                $this->strTemplate = QType::Cast($strPath, QType::String);
                            } else {
                                throw new QCallerException('Could not find template file: ' . $mixValue);
                            }
                        } else {
                            $this->strTemplate = null;
                        }
                        break;
                    } catch (QInvalidCastException $objExc) {
                        $objExc->IncrementOffset();
                        throw $objExc;
                    }

                case "AutoRenderChildren":
                    try {
                        if ($this->blnAutoRenderChildren !== ($mixValue = QType::Cast($mixValue, QType::Boolean))) {
                            $this->blnModified = true;
                            $this->blnAutoRenderChildren = $mixValue;
                        }
                        break;
                    } catch (QInvalidCastException $objExc) {
                        $objExc->IncrementOffset();
                        throw $objExc;
                    }

                case "TagName":
                    try {
                        if ($this->strTagName !== ($mixValue = QType::Cast($mixValue, QType::String))) {
                            $this->blnModified = true;
                            $this->strTagName = $mixValue;
                        }
                        break;
                    } catch (QInvalidCastException $objExc) {
                        $objExc->IncrementOffset();
                        throw $objExc;
                    }

                case "HtmlEntities":
                    try {
                        if ($this->blnHtmlEntities !== ($mixValue = QType::Cast($mixValue, QType::Boolean))) {
                            $this->blnModified = true;
                            $this->blnHtmlEntities = $mixValue;
                        }
                        break;
                    } catch (QInvalidCastException $objExc) {
                        $objExc->IncrementOffset();
                        throw $objExc;
                    }

                case "DropTarget":
                    try {
                        if ($this->blnDropTarget !== ($mixValue = QType::Cast($mixValue, QType::Boolean))) {
                            $this->blnModified = true;
                            $this->blnDropTarget = $mixValue;
                        }
                        break;
                    } catch (QInvalidCastException $objExc) {
                        $objExc->IncrementOffset();
                        throw $objExc;
                    }


                default:
                    try {
                        parent::__set($strName, $mixValue);
                    } catch (QCallerException $objExc) {
                        $objExc->IncrementOffset();
                        throw $objExc;
                    }
                    break;
            }
        }

    }

    $_CONTROL = null;