/**
  * @param QControl|QControlBase $objControl   QControl for which the actions have to be rendered
  * @param string                $strEventName Name of the event for which the actions have to be rendered
  * @param QAction[]             $objActions   Array of actionss
  *
  * @return null|string
  * @throws Exception
  */
 public static function RenderActions(QControl $objControl, $strEventName, $objActions)
 {
     $strToReturn = '';
     $strJqUiProperty = null;
     if ($objControl->ActionsMustTerminate) {
         $strToReturn .= ' event.preventDefault();' . _nl();
     }
     if ($objActions && count($objActions)) {
         foreach ($objActions as $objAction) {
             if ($objAction->objEvent->EventName != $strEventName) {
                 throw new Exception('Invalid Action Event in this entry in the ActionArray');
             }
             if ($objAction->objEvent instanceof QJqUiPropertyEvent) {
                 $strJqUiProperty = $objAction->objEvent->JqProperty;
             }
             if ($objAction->objEvent->Delay > 0) {
                 $strCode = sprintf(" qcubed.setTimeout('%s', \$j.proxy(function(){%s},this), %s);", $objControl->ControlId, _nl() . _indent(trim($objAction->RenderScript($objControl))) . _nl(), $objAction->objEvent->Delay);
             } else {
                 $strCode = ' ' . $objAction->RenderScript($objControl);
             }
             // Add Condition (if applicable)
             if (strlen($objAction->objEvent->Condition)) {
                 $strCode = sprintf(' if (%s) {%s}', $objAction->objEvent->Condition, _nl() . _indent(trim($strCode)) . _nl());
             }
             $strCode .= _nl();
             // Append it to the Return Value
             $strToReturn .= $strCode;
         }
     }
     $strToReturn = _nl() . _indent($strToReturn);
     if (strlen($strToReturn)) {
         if ($strJqUiProperty) {
             $strOut = sprintf('$j("#%s").%s("option", {%s: function(event, ui){%s}});', $objControl->getJqControlId(), $objControl->getJqSetupFunction(), $strJqUiProperty, $strToReturn);
         } elseif ($objControl instanceof QControlProxy) {
             if ($objControl->TargetControlId) {
                 // Deprecated.
                 $strOut = sprintf('$j("#%s").on("%s", function(event, ui){%s});', $objControl->TargetControlId, $strEventName, $strToReturn);
             } else {
                 $strOut = sprintf('$j("#%s").on("%s", "[data-qpxy=\'%s\']", function(event, ui){%s});', $objControl->Form->FormId, $strEventName, $objControl->ControlId, $strToReturn);
             }
         } else {
             $strOut = sprintf('$j("#%s").on("%s", function(event, ui){%s});', $objControl->getJqControlId(), $strEventName, $strToReturn);
         }
         if (isset($strOut)) {
             if (!QApplication::$Minimize) {
                 // Render a comment
                 $strOut = _nl() . _nl() . sprintf('/*** Event: %s  Control Type: %s, Control Name: %s, Control Id: %s  ***/', $strEventName, get_class($objControl), $objControl->Name, $objControl->ControlId) . _nl() . _indent($strOut) . _nl() . _nl();
             }
             return $strOut;
         }
     }
     return null;
 }
 /**
  * Renders an html tag with the given attributes and inner html.
  *
  * If the innerHtml is detected as being wrapped in an html tag of some sort, it will attempt to format the code so that
  * it has a structured view in a browser, with the inner html indented and on a new line in between the tags. You
  * can turn this off by setting __MINIMIZE__, or by passing in true to $blnNoSpace.
  *
  * There area a few special cases to consider:
  * - Void elements will not be formatted to avoid adding unnecessary white space since these are generally
  *   inline elements
  * - Non-void elements always use internal newlines, even in __MINIMIZE__ mode. This is to prevent different behavior
  *   from appearing in __MINIMIZE__ mode on inline elements, because inline elements with internal space will render with space to separate
  *   from surrounding elements. Usually, this is not an issue, but in the special situations where you really need inline
  *   elements to be right up against its siblings, set $blnNoSpace to true.
  *
  *
  * @param string 		$strTag				The tag name
  * @param null|mixed 	$mixAttributes 		String of attribute values or array of attribute values.
  * @param null|string 	$strInnerHtml 		The html to print between the opening and closing tags. This will NOT be escaped.
  * @param boolean		$blnIsVoidElement 	True to print as a tag with no closing tag.
  * @param boolean		$blnNoSpace		 	Renders with no white-space. Useful in special inline situations.
  * @return string						The rendered html tag
  */
 public static function RenderTag($strTag, $mixAttributes, $strInnerHtml = null, $blnIsVoidElement = false, $blnNoSpace = false)
 {
     assert('!empty($strTag)');
     $strToReturn = '<' . $strTag;
     if ($mixAttributes) {
         if (is_string($mixAttributes)) {
             $strToReturn .= ' ' . trim($mixAttributes);
         } else {
             // assume array
             $strToReturn .= QHtml::RenderHtmlAttributes($mixAttributes);
         }
     }
     if ($blnIsVoidElement) {
         $strToReturn .= ' />';
         // conforms to both XHTML and HTML5 for both normal and foreign elements
     } elseif ($blnNoSpace || substr(trim($strInnerHtml), 0, 1) !== '<') {
         $strToReturn .= '>' . $strInnerHtml . '</' . $strTag . '>';
     } else {
         // the hardcoded newlines below are important to prevent different drawing behavior in MINIMIZE mode
         $strToReturn .= '>' . "\n" . _indent(trim($strInnerHtml)) . "\n" . '</' . $strTag . '>' . _nl();
     }
     return $strToReturn;
 }
    /**
     * Returns code to refresh the control from the saved object.
     *
     * @param QCodeGenBase $objCodeGen
     * @param QSqlTable $objTable
     * @param QSqlColumn $objColumn
     * @param bool $blnInit
     * @return string
     */
    public function ConnectorRefresh(QCodeGenBase $objCodeGen, QSqlTable $objTable, $objColumn, $blnInit = false)
    {
        $strPropName = QCodeGen::ModelConnectorPropertyName($objColumn);
        $strControlVarName = $this->VarName($strPropName);
        $strObjectName = $objCodeGen->ModelVariableName($objTable->Name);
        $strRet = '';
        if ($blnInit) {
            $strRet .= <<<TMPL
if (!\$this->str{$strPropName}NullLabel) {
\tif (!\$this->{$strControlVarName}->Required) {
\t\t\$this->str{$strPropName}NullLabel = '- None -';
\t}
\telseif (!\$this->blnEditMode) {
\t\t\$this->str{$strPropName}NullLabel = '- Select One -';
\t}
}

TMPL;
        } else {
            $strRet .= "\$this->{$strControlVarName}->RemoveAllItems();\n";
        }
        $strRet .= <<<TMPL
\$this->{$strControlVarName}->AddItem(QApplication::Translate(\$this->str{$strPropName}NullLabel), null);

TMPL;
        $options = $objColumn->Options;
        if (!$options || !isset($options['NoAutoLoad'])) {
            $strRet .= "\$this->{$strControlVarName}->AddItems(\$this->{$strControlVarName}_GetItems());\n";
        }
        if ($objColumn instanceof QSqlColumn) {
            $strRet .= "\$this->{$strControlVarName}->SelectedValue = \$this->{$strObjectName}->{$objColumn->PropertyName};\n";
        } elseif ($objColumn instanceof QReverseReference && $objColumn->Unique) {
            $strRet .= "if (\$this->{$strObjectName}->{$objColumn->ObjectPropertyName})\n";
            $strRet .= _indent("\$this->{$strControlVarName}->SelectedValue = \$this->{$strObjectName}->{$objColumn->ObjectPropertyName}->{$objCodeGen->GetTable($objColumn->Table)->PrimaryKeyColumnArray[0]->PropertyName};\n");
        } elseif ($objColumn instanceof QManyToManyReference) {
            if ($objColumn->IsTypeAssociation) {
                $strRet .= "\$this->{$strControlVarName}->SelectedValues = array_keys(\$this->{$strObjectName}->Get{$objColumn->ObjectDescription}Array());\n";
            } else {
                //$strRet .= $strTabs . "\$this->{$strControlVarName}->SelectedValues = \$this->{$strObjectName}->Get{$objColumn->ObjectDescription}Keys();\n";
            }
        }
        if (!$blnInit) {
            // wrap it with a test as to whether the control has been created.
            $strRet = _indent($strRet);
            $strRet = <<<TMPL
if (\$this->{$strControlVarName}) {
{$strRet}
}

TMPL;
        }
        $strRet = _indent($strRet, 3);
        return $strRet;
    }
    /**
     * Renders the end of the form, including the closing form and body tags.
     * Renders the html for hidden controls.
     * @param bool $blnDisplayOutput should the output be returned or directly printed to screen.
     *
     * @return null|string
     * @throws QCallerException
     */
    public function RenderEnd($blnDisplayOutput = true)
    {
        // Ensure that RenderEnd() has not yet been called
        switch ($this->intFormStatus) {
            case QFormBase::FormStatusUnrendered:
                throw new QCallerException('$this->RenderBegin() was never called');
            case QFormBase::FormStatusRenderBegun:
                break;
            case QFormBase::FormStatusRenderEnded:
                throw new QCallerException('$this->RenderEnd() has already been called');
                break;
            default:
                throw new QCallerException('FormStatus is in an unknown status');
        }
        $strHtml = '';
        // This will be the final output
        /**** Render any controls that get automatically rendered ****/
        foreach ($this->GetAllControls() as $objControl) {
            if ($objControl->AutoRender && !$objControl->Rendered) {
                $strRenderMethod = $objControl->PreferredRenderMethod;
                $strHtml .= $objControl->{$strRenderMethod}(false) . _nl();
            }
        }
        /**** Prepare Javascripts ****/
        // Clear included javascript array since we are completely redrawing the page
        $this->strIncludedJavaScriptFileArray = array();
        $strControlIdToRegister = array();
        $strEventScripts = '';
        // Add form level javascripts and libraries
        $strJavaScriptArray = $this->ProcessJavaScriptList($this->GetFormJavaScripts());
        QApplication::AddJavaScriptFiles($strJavaScriptArray);
        $strFormJsFiles = QApplication::RenderFiles();
        // Render the form-level javascript files separately
        // Go through all controls and gather up any JS or CSS to run or Form Attributes to modify
        foreach ($this->GetAllControls() as $objControl) {
            if ($objControl->Rendered || $objControl->ScriptsOnly) {
                $strControlIdToRegister[] = $objControl->ControlId;
                /* Note: GetEndScript may cause the control to register additional commands, or even add javascripts, so those should be handled after this. */
                if ($strControlScript = $objControl->GetEndScript()) {
                    $strControlScript = JavaScriptHelper::TerminateScript($strControlScript);
                    // Add comments for developer version of output
                    if (!QApplication::$Minimize) {
                        // Render a comment
                        $strControlScript = _nl() . _nl() . sprintf('/*** EndScript -- Control Type: %s, Control Name: %s, Control Id: %s  ***/', get_class($objControl), $objControl->Name, $objControl->ControlId) . _nl() . _indent($strControlScript);
                    }
                    $strEventScripts .= $strControlScript;
                }
            }
            // Include the javascripts specified by each control.
            if ($strScriptArray = $this->ProcessJavaScriptList($objControl->JavaScripts)) {
                QApplication::AddJavaScriptFiles($strScriptArray);
            }
            // Include any StyleSheets?  The control would have a
            // comma-delimited list of stylesheet files to include (if applicable)
            if ($strScriptArray = $this->ProcessStyleSheetList($objControl->StyleSheets)) {
                QApplication::AddStyleSheets(array_keys($strScriptArray));
            }
            // Form Attributes?
            if ($objControl->FormAttributes) {
                QApplication::ExecuteControlCommand($this->strFormId, 'attr', $objControl->FormAttributes);
                foreach ($objControl->FormAttributes as $strKey => $strValue) {
                    if (!array_key_exists($strKey, $this->strFormAttributeArray)) {
                        $this->strFormAttributeArray[$strKey] = $strValue;
                    } else {
                        if ($this->strFormAttributeArray[$strKey] != $strValue) {
                            $this->strFormAttributeArray[$strKey] = $strValue;
                        }
                    }
                }
            }
        }
        // Add grouping commands to events (Used for deprecated drag and drop, but not removed yet)
        foreach ($this->objGroupingArray as $objGrouping) {
            $strGroupingScript = $objGrouping->Render();
            if (strlen($strGroupingScript) > 0) {
                $strGroupingScript = JavaScriptHelper::TerminateScript($strGroupingScript);
                $strEventScripts .= $strGroupingScript;
            }
        }
        /*** Build the javascript block ****/
        // Start with variable settings and initForm
        $strEndScript = sprintf('qc.initForm("%s"); ', $this->strFormId);
        // Register controls
        if ($strControlIdToRegister) {
            $strEndScript .= sprintf("qc.regCA(%s); \n", JavaScriptHelper::toJsObject($strControlIdToRegister));
        }
        // Design mode event
        if (defined('__DESIGN_MODE__') && __DESIGN_MODE__ == 1) {
            // attach an event listener to the form to send context menu selections to the designer dialog for processing
            $strEndScript .= sprintf('$j("#%s").on("contextmenu", "[id]", 
						function(event) {
							$j("#qconnectoreditdlg").trigger("qdesignerclick", 
								[{id: event.target.id ? event.target.id : $j(event.target).parents("[id]").attr("id"), for: $j(event.target).attr("for")}]
							);
							return false;
						}
					);', $this->FormId);
        }
        // Add any application level js commands.
        // This will include high and medimum level commands
        $strEndScript .= QApplication::RenderJavascript(true);
        // Add the javascript coming from controls and events just after the medium level commands
        $strEndScript .= ';' . $strEventScripts;
        // Add low level commands and other things that need to execute at the end
        $strEndScript .= ';' . QApplication::RenderJavascript(false);
        // Create Final EndScript Script
        $strEndScript = sprintf('<script type="text/javascript">$j(document).ready(function() { %s; });</script>', $strEndScript);
        /**** Render the HTML itself, appending the javascript we generated above ****/
        foreach ($this->GetAllControls() as $objControl) {
            if ($objControl->Rendered) {
                $strHtml .= $objControl->GetEndHtml();
            }
            $objControl->ResetFlags();
            // Make sure controls are serialized in a reset state
        }
        $strHtml .= $strFormJsFiles . _nl();
        // Add form level javascript files
        // put javascript environment defines up early for use by other js files.
        $strHtml .= '<script type="text/javascript">' . sprintf('qc.baseDir = "%s"; ', __VIRTUAL_DIRECTORY__ . __SUBDIRECTORY__) . sprintf('qc.jsAssets = "%s"; ', __VIRTUAL_DIRECTORY__ . __JS_ASSETS__) . sprintf('qc.phpAssets = "%s"; ', __VIRTUAL_DIRECTORY__ . __PHP_ASSETS__) . sprintf('qc.cssAssets = "%s"; ', __VIRTUAL_DIRECTORY__ . __CSS_ASSETS__) . sprintf('qc.imageAssets = "%s"; ', __VIRTUAL_DIRECTORY__ . __IMAGE_ASSETS__) . '</script>' . _nl();
        $strHtml .= QApplication::RenderFiles() . _nl();
        // add plugin and control js files
        // Render hidden controls related to the form
        $strHtml .= sprintf('<input type="hidden" name="Qform__FormId" id="Qform__FormId" value="%s" />', $this->strFormId) . _nl();
        $strHtml .= sprintf('<input type="hidden" name="Qform__FormControl" id="Qform__FormControl" value="" />') . _nl();
        $strHtml .= sprintf('<input type="hidden" name="Qform__FormEvent" id="Qform__FormEvent" value="" />') . _nl();
        $strHtml .= sprintf('<input type="hidden" name="Qform__FormParameter" id="Qform__FormParameter" value="" />') . _nl();
        $strHtml .= sprintf('<input type="hidden" name="Qform__FormCallType" id="Qform__FormCallType" value="" />') . _nl();
        $strHtml .= sprintf('<input type="hidden" name="Qform__FormUpdates" id="Qform__FormUpdates" value="" />') . _nl();
        $strHtml .= sprintf('<input type="hidden" name="Qform__FormCheckableControls" id="Qform__FormCheckableControls" value="" />') . _nl();
        // Serialize and write out the formstate
        $strHtml .= sprintf('<input type="hidden" name="Qform__FormState" id="Qform__FormState" value="%s" />', QForm::Serialize(clone $this)) . _nl();
        // close the form tag
        $strHtml .= "</form>";
        // Add the JavaScripts rendered above
        $strHtml .= $strEndScript;
        // close the body tag
        if ($this->blnRenderedBodyTag) {
            $strHtml .= '</body>';
        }
        /**** Cleanup ****/
        // Update Form Status
        $this->intFormStatus = QFormBase::FormStatusRenderEnded;
        // Display or Return
        if ($blnDisplayOutput) {
            if (!QApplication::$CliMode) {
                print $strHtml;
            }
            return null;
        } else {
            if (!QApplication::$CliMode) {
                return $strHtml;
            } else {
                return '';
            }
        }
    }
 /**
  * RenderOutput should be the last call in your custom RenderMethod. It is responsible for the following:
  * - Creating the wrapper if you are using a wrapper, or
  * - Possibly creating a dummy control if not using a wrapper and the control is hidden.
  * - Generating the control's output in one of 3 ways:
  * 		- Generate straight html if drawing the control as part of a complete page refresh
  * 		- Generate straight html if in an ajax call, but a parent is getting redrawn, which requires this
  *        whole control to get drawn
  * 		- If in an ajax call and we are the top level control getting drawn, then generate special code that
  * 		  out javascript will read and put into the control's spot on the page. Requires coordination with
  * 		  the code in qcubed.js.
  *
  * @param string  $strOutput
  *   Your html-code which should be printed out
  * @param boolean $blnDisplayOutput
  *   should it be printed, or just be returned?
  *
  * @return string
  */
 protected function RenderOutput($strOutput, $blnDisplayOutput, $blnForceAsBlockElement = false)
 {
     if ($blnForceAsBlockElement) {
         $this->blnIsBlockElement = true;
         // must be remembered for ajax drawing
     }
     if ($this->blnUseWrapper) {
         if (!$this->blnVisible) {
             $strOutput = '';
         }
     } else {
         if (!$this->blnVisible) {
             /* No wrapper is used and the control is not visible. We must enter a span with the control id and
              *	display:none in order to be able change blnVisible to true in an Ajax call later and redraw the control.
              */
             $strOutput = sprintf('<span id="%s" style="display:none;"></span>', $this->strControlId);
         }
     }
     switch ($this->objForm->CallType) {
         case QCallType::Ajax:
             if ($this->objParentControl) {
                 if ($this->objParentControl->Rendered || $this->objParentControl->Rendering) {
                     // If we have a ParentControl and the ParentControl has NOT been rendered, then output
                     // as standard HTML
                     if ($this->blnUseWrapper) {
                         $strOutput = $this->RenderWrappedOutput($strOutput, $blnForceAsBlockElement) . $this->GetNonWrappedHtml();
                     } else {
                         $strOutput = $strOutput . $this->GetNonWrappedHtml();
                     }
                 } else {
                     // Do nothing. RenderAjax will handle it.
                 }
             } else {
                 // if this is an injected top-level control, then we need to render the whole thing
                 if (!$this->blnOnPage) {
                     if ($this->blnUseWrapper) {
                         $strOutput = $this->RenderWrappedOutput($strOutput, $blnForceAsBlockElement) . $this->GetNonWrappedHtml();
                     } else {
                         $strOutput = $strOutput . $this->GetNonWrappedHtml();
                     }
                 }
             }
             break;
         default:
             if ($this->blnUseWrapper) {
                 $strOutput = $this->RenderWrappedOutput($strOutput) . $this->GetNonWrappedHtml();
             } else {
                 $strOutput = $strOutput . $this->GetNonWrappedHtml();
             }
             $strOutput = $this->RenderComment(self::CommentStart) . _indent($strOutput) . $this->RenderComment(self::CommentEnd);
             break;
     }
     // Update watcher
     if ($this->objWatcher) {
         $this->objWatcher->MakeCurrent();
     }
     $this->blnRendering = false;
     $this->blnRendered = true;
     $this->blnOnPage = true;
     // Output or Return
     if ($blnDisplayOutput) {
         print $strOutput;
     } else {
         return $strOutput;
     }
 }
Example #6
0
 /**
  * Display the help message
  * @return void
  */
 public function showHelp()
 {
     $options = $this->getOptions();
     if (count($options)) {
         _writeln('Usage:');
         $usage = _indent() . $this->name . ' [options]';
         if (count($this->arguments)) {
             $usage .= ' [<' . implode('>] [<', $this->argumentNames) . '>]';
         }
         _writeln($usage);
         # Arguments
         if (count($this->arguments)) {
             _writeln();
             _writeln('Arguments:');
             $table = new ConsoleTable();
             $table->hideBorder()->setPadding(2);
             foreach ($this->arguments as $arg) {
                 $table->addRow();
                 $table->addColumn($arg['name']);
                 $desc = $arg['description'];
                 if ($arg['default']) {
                     $desc .= ' [default: "' . $arg['default'] . '"]';
                 }
                 $table->addColumn($desc);
             }
             $table->display();
         }
         # Options
         if (count($options)) {
             _writeln();
             _writeln('Options:');
             $table = new ConsoleTable();
             $table->hideBorder()->setPadding(2);
             foreach ($this->options as $name => $opt) {
                 $table->addRow();
                 $table->addColumn($opt['key']);
                 $desc = $opt['description'];
                 if ($opt['default']) {
                     $desc .= ' [default: "' . $opt['default'] . '"]';
                 }
                 $table->addColumn($desc);
             }
             $table->display();
         }
         if ($this->description) {
             _writeln();
             _writeln('Help:');
             _writeln(_indent() . $this->description);
         }
     }
 }