public function __construct($arrAttributes = null) { // check against arrAttributes, as 'onsubmit_callback' => 'multifileupload_moveFiles' does not provide valid attributes if ($arrAttributes !== null && !$arrAttributes['uploadFolder']) { throw new \Exception(sprintf($GLOBALS['TL_LANG']['ERR']['noUploadFolderDeclared'], $this->name)); } $arrAttributes['uploadAction'] = static::$uploadAction; if (TL_MODE == 'FE') { $arrAttributes['uploadActionParams'] = http_build_query(AjaxAction::getParams(MultiFileUpload::NAME, static::$uploadAction)); } $arrAttributes['addRemoveLinks'] = isset($arrAttributes['addRemoveLinks']) ? $arrAttributes['addRemoveLinks'] : true; if (!is_array($arrAttributes['value']) && !Validator::isBinaryUuid($arrAttributes['value'])) { $arrAttributes['value'] = json_decode($arrAttributes['value']); } // bin to string -> never pass binary to the widget!! if ($arrAttributes['value']) { if (is_array($arrAttributes['value'])) { $arrAttributes['value'] = array_map(function ($val) { return \Validator::isBinaryUuid($val) ? \StringUtil::binToUuid($val) : $val; }, $arrAttributes['value']); } else { $arrAttributes['value'] = array(\Validator::isBinaryUuid($arrAttributes['value']) ? \StringUtil::binToUuid($arrAttributes['value']) : $arrAttributes['value']); } } parent::__construct($arrAttributes); $this->objUploader = new MultiFileUpload($arrAttributes); // add onsubmit_callback: move files after form submission $GLOBALS['TL_DCA'][$this->strTable]['config']['onsubmit_callback']['multifileupload_moveFiles'] = array('HeimrichHannot\\MultiFileUpload\\FormMultiFileUpload', 'moveFiles'); Ajax::runActiveAction(MultiFileUpload::NAME, MultiFileUpload::ACTION_UPLOAD, $this); }
public function show() { global $objPage; $back = \Controller::generateFrontendUrl($objPage->row(), null, null, true); $blnAjax = false; $objModal = new Modal($this->objModal, $this->arrConfig); $objModal->setBackLink($back); $objResponse = new ResponseSuccess(); $objResponse->setResult(new ResponseData($objModal->generate(), array('id' => $this->objModal->id))); $objResponse->setUrl(AjaxAction::removeAjaxParametersFromUrl(Request::getInstance()->getRequestUri())); return $objResponse; }
protected function generateField($strName, $arrData, $skipValidation = false) { $strClass = $GLOBALS['TL_FFL'][$arrData['inputType']]; // overwrite the widget in readonly mode if ($this->viewMode == FORMHYBRID_VIEW_MODE_READONLY || $this->viewMode == FORMHYBRID_VIEW_MODE_DEFAULT && $this->addReadOnly && in_array($strName, $this->arrReadOnly)) { $strClass = 'HeimrichHannot\\FormHybrid\\FormReadonlyField'; $skipValidation = true; } $strInputMethod = $this->strInputMethod; // Continue if the class is not defined if (!class_exists($strClass)) { return false; } $arrWidgetErrors = array(); // contains the load_callback! $varDefault = $this->getDefaultFieldValue($strName, $arrData); $varValue = $varDefault; if ($this->isSubmitted && !$skipValidation) { $varValue = \Input::$strInputMethod($strName) !== null ? \Input::$strInputMethod($strName) : $varValue; $varValue = FormSubmission::prepareSpecialValueForSave($varValue, $arrData, $this->strTable, $this->intId, $varDefault, $arrWidgetErrors); } // overwrite required fields if ($this->overwriteRequired) { // set mandatory to false $arrData['eval']['mandatory'] = false; // overwrite mandatory by config if (!$arrData['eval']['mandatory'] && in_array($strName, $this->arrRequired)) { $arrData['eval']['mandatory'] = true; } } // prevent name for GET and submit widget, otherwise url will have submit name in if ($this->strMethod == FORMHYBRID_METHOD_GET && $arrData['inputType'] == 'submit') { $strName = ''; } $arrData['eval']['tagTable'] = $this->strTable; // always disable validation for filter form if ($this->isFilterForm) { $arrData['eval']['mandatory'] = false; } // to make captcha form related, add the form id without entity id if ($arrData['inputType'] == 'captcha') { $strName .= '_' . $this->getFormId(false); } $this->strField = $strName; $this->strInputName = $strName; $this->varValue = is_array($varValue) ? $varValue : \Controller::replaceInsertTags($varValue); $arrWidget = \Widget::getAttributesFromDca($arrData, $strName, is_array($varValue) ? $varValue : \Controller::replaceInsertTags($varValue), $strName, $this->strTable, $this); $this->updateWidget($arrWidget, $arrData); list($blnActive, $strSubPalette, $arrFields, $arrSubPaletteFields, $blnAutoSubmit, $blnToggleSubpalette) = $this->retrieveSubpaletteWithState($strName, array_keys($this->arrFields)); // support submitOnChange as form submission if ($arrData['eval']['submitOnChange'] && $blnToggleSubpalette) { if ($blnAutoSubmit) { $arrWidget['onchange'] = $this->async ? 'FormhybridAjaxRequest.asyncSubmit(this.form);' : "this.form.submit();"; } else { $strEvent = 'onclick'; switch ($arrData['inputType']) { case 'select': $strEvent = 'onchange'; break; } $arrWidget[$strEvent] = "FormhybridAjaxRequest.toggleSubpalette(this, 'sub_" . $strName . "', '" . $strName . "', '" . AjaxAction::generateUrl(Form::FORMHYBRID_NAME, 'toggleSubpalette') . "')"; unset($arrWidget['submitOnChange']); } } else { if ($arrWidget['submitOnChange']) { $strEvent = null; if ($arrWidget['onchange']) { $strEvent = 'onchange'; } else { if ($arrWidget['onclick']) { $strEvent = 'onclick'; } } if ($strEvent !== null) { $arrWidget[$strEvent] = "FormhybridAjaxRequest.reload('" . $this->getFormId() . "', '" . AjaxAction::generateUrl(Form::FORMHYBRID_NAME, 'reload') . "')"; unset($arrWidget['submitOnChange']); } } } $objWidget = new $strClass($arrWidget); if (isset($arrData['formHybridOptions'])) { $arrFormHybridOptions = $arrData['formHybridOptions']; $this->import($arrFormHybridOptions[0]); $objWidget->options = $this->{$arrFormHybridOptions}[0]->{$arrFormHybridOptions}[1](); } if ($objWidget instanceof \uploadable) { $this->hasUpload = true; } // always xss clean the user input (also if filter, non-model submission, ...) -> done another time // FrontendWidget::validateGetAndPost() in $objWidget->value = FormHelper::xssClean($objWidget->value, $arrData['eval']['allowHtml']); if ($this->isSubmitted) { // add filter class if filter is active if ($objWidget->value && $this->isFilterForm) { $objWidget->class = 'filtered'; } // do not validate fields if not submitted or skipvalidation issset // do not submit if ajax request and group is not formhybrid, for example multifileupload (otherwise captcha fields will be validated does not match visible one) if (!($this->isSkipValidation() || $skipValidation) && Ajax::isRelated(Form::FORMHYBRID_NAME) !== false) { FrontendWidget::validateGetAndPost($objWidget, $this->strMethod, $this->getFormId(), $arrData); if (is_array($arrWidgetErrors)) { foreach ($arrWidgetErrors as $strError) { $objWidget->addError($strError); } } // Make sure unique fields are unique if ($arrData['eval']['unique'] && $varValue != '' && !\Database::getInstance()->isUniqueValue($this->strTable, $strName, $varValue, $this->intId > 0 ? $this->intId : null)) { $objWidget->addError(sprintf($GLOBALS['TL_LANG']['ERR']['unique'], $arrData['label'][0] ?: $strName)); } // trigger save_callbacks before assertion of the new value to objActiveRecord if (is_array($arrData['save_callback'])) { foreach ($arrData['save_callback'] as $callback) { if (is_array($callback)) { $this->import($callback[0]); $varValue = $this->{$callback}[0]->{$callback}[1]($varValue, $this); } elseif (is_callable($callback)) { $varValue = $callback($varValue, $this); } } } if ($objWidget->hasErrors()) { $this->doNotSubmit = true; $this->arrInvalidFields[] = $strName; } elseif ($arrData['inputType'] == 'tag' && in_array('tags_plus', \ModuleLoader::getActive())) { $varValue = deserialize($objWidget->value); if (!is_array($varValue)) { $varValue = array($varValue); } if ($this->intId) { \HeimrichHannot\TagsPlus\TagsPlus::saveTags($this->strTable, $this->intId, array_map('urldecode', $varValue)); } } elseif ($objWidget->submitInput()) { // save non escaped to database if (is_array($objWidget->value)) { $this->objActiveRecord->{$strName} = array_map(function ($varVal) use($arrData) { $varVal = FormSubmission::prepareSpecialValueForSave($varVal, $arrData, $this->strTable, $this->intId); if (is_array($varVal)) { foreach ($varVal as $key => $val) { $varVal[$key] = html_entity_decode($val); } } else { $varVal = html_entity_decode($varVal); } return $varVal; }, $objWidget->value); } else { $this->objActiveRecord->{$strName} = html_entity_decode(FormSubmission::prepareSpecialValueForSave($objWidget->value, $arrData, $this->strTable, $this->intId)); } } elseif ($objWidget instanceof \uploadable && $arrData['inputType'] == 'multifileupload') { $strMethod = strtolower($this->strMethod); if (\Input::$strMethod($strName)) { $arrValue = json_decode(\Input::$strMethod($strName)); if (!empty($arrValue)) { $arrValue = array_map(function ($val) { return \String::uuidToBin($val); }, $arrValue); $this->objActiveRecord->{$strName} = serialize($arrValue); } else { $this->objActiveRecord->{$strName} = serialize($arrValue); } } // delete the files scheduled for deletion $objWidget->deleteScheduledFiles(json_decode(\Input::$strMethod('deleted_' . $strName))); } elseif ($objWidget instanceof \uploadable && isset($_SESSION['FILES'][$strName]) && \Validator::isUuid($_SESSION['FILES'][$strName]['uuid'])) { $this->objActiveRecord->{$strName} = $_SESSION['FILES'][$strName]['uuid']; } } } return $objWidget; }
/** * Get config value from transformed arrData and add logic to modify the value here * @param $strKey * * @return mixed|string */ public function __get($strKey) { $varValue = $this->arrData[$strKey]; switch ($strKey) { case 'strAction': if ($varValue && ($objActionPage = \PageModel::findWithDetails($varValue)) !== null) { $varValue = \Controller::generateFrontendUrl($objActionPage->row(), null, null, true); } else { $varValue = Url::removeQueryString(array('file'), \Environment::get('uri')); // remove all query parameters within ajax request if (Ajax::isRelated(Form::FORMHYBRID_NAME) !== false) { $varValue = AjaxAction::removeAjaxParametersFromUrl($varValue); } } // async form if ($this->async) { $varValue = AjaxAction::generateUrl(Form::FORMHYBRID_NAME, 'asyncFormSubmit'); } // add hash if ($this->addHashToAction) { $varValue .= '#' . ($this->customHash ?: $this->strFormId); } break; case 'arrDefaultValues': $varValue = FormHelper::getAssocMultiColumnWizardList($varValue, 'field'); break; } return $varValue; }
/** * Generate an modal URL depending on the current rewriteURL setting * * @param array $arrRow An array of modal parameters * @param mixed $jumpTo An optional jumpTo Page * @param boolean $blnAjax Determine if ajax request, can be overwritten * * @return string An URL that can be used in the front end */ public static function generateModalUrl(array $arrRow = array(), $jumpTo = null, &$blnAjax = true, &$blnRedirect = true) { global $objPage; $strUrl = ''; $strParams = \Config::get('useAutoItem') && !\Config::get('disableAlias') ? '/' : '/modals/'; $strParams .= !\Config::get('disableAlias') && $arrRow['alias'] != '' ? $arrRow['alias'] : $arrRow['id']; if ($jumpTo !== null && ($objJumpTo = \PageModel::findPublishedByIdOrAlias($jumpTo)) !== null) { $objJumpTo = $objJumpTo->current(); $strUrl = $objJumpTo->getFrontendUrl($strParams); } else { if ($objPage !== null) { $strUrl = $objPage->getFrontendUrl($strParams); } } if ($blnAjax) { // trigger ajax action if jumpto is same page if ($objJumpTo === null || $objPage->id == $objJumpTo->id) { $blnRedirect = false; $strUrl = AjaxAction::generateUrl(Modal::MODAL_NAME, 'show', array(), false, $strUrl); } else { $blnAjax = false; } } // HOOK: add custom logic if (isset($GLOBALS['TL_HOOKS']['generateModalUrl']) && is_array($GLOBALS['TL_HOOKS']['generateModalUrl'])) { foreach ($GLOBALS['TL_HOOKS']['generateModalUrl'] as $callback) { $strUrl = static::importStatic($callback[0])->{$callback[1]}($arrRow, $strParams, $strUrl, $blnAjax); } } return $strUrl; }