/** * Set the options for this object * * @param array $parameters Configuration array * @return void */ protected function setOptions(array $parameters) { if (is_array($parameters)) { $keys = ArrayUtility::filterAndSortByNumericKeys($parameters); foreach ($keys as $key) { $class = $parameters[$key]; if ((int) $key && strpos($key, '.') === false) { if (isset($parameters[$key . '.']) && $class === 'CHECKBOX') { $childElementArguments = $parameters[$key . '.']; if (isset($childElementArguments['checked'])) { $childElementArguments['attributes']['selected'] = 'selected'; unset($childElementArguments['checked']); } if (isset($childElementArguments['value'])) { $childElementArguments['attributes']['value'] = $childElementArguments['value']; unset($childElementArguments['value']); } if (isset($childElementArguments['label.'])) { $childElementArguments['text'] = $childElementArguments['label.']['value']; unset($childElementArguments['label.']); } $this->configuration['options'][] = $childElementArguments; } } } } }
/** * Generates a frameset based on input configuration in a TypoScript array. * * @param array $setup The TypoScript properties of the PAGE object property "frameSet.". See link. * @return string A <frameset> tag. * @see \TYPO3\CMS\Frontend\Page\PageGenerator::renderContentWithHeader() */ public function make($setup) { $content = ''; if (is_array($setup)) { $sKeyArray = ArrayUtility::filterAndSortByNumericKeys($setup); foreach ($sKeyArray as $theKey) { $theValue = $setup[$theKey]; if ((int) $theKey && ($conf = $setup[$theKey . '.'])) { switch ($theValue) { case 'FRAME': $typeNum = (int) $GLOBALS['TSFE']->tmpl->setup[$conf['obj'] . '.']['typeNum']; if (!$conf['src'] && !$typeNum) { $typeNum = -1; } $content .= '<frame' . $this->frameParams($conf, $typeNum) . ' />' . LF; break; case 'FRAMESET': $frameset = GeneralUtility::makeInstance(__CLASS__); $content .= $frameset->make($conf) . LF; break; } } } return '<frameset' . $this->framesetParams($setup) . '>' . LF . $content . '</frameset>'; } return ''; }
/** * The main method called by the controller * * Iterates over the configured post processors and calls them with their * own settings * * @return string HTML messages from the called processors */ public function process() { $html = ''; if (is_array($this->postProcessorTypoScript)) { $keys = ArrayUtility::filterAndSortByNumericKeys($this->postProcessorTypoScript); foreach ($keys as $key) { if (!(int) $key || strpos($key, '.') !== false) { continue; } $className = false; $processorName = $this->postProcessorTypoScript[$key]; $processorArguments = array(); if (isset($this->postProcessorTypoScript[$key . '.'])) { $processorArguments = $this->postProcessorTypoScript[$key . '.']; } if (class_exists($processorName, true)) { $className = $processorName; } else { $classNameExpanded = 'TYPO3\\CMS\\Form\\PostProcess\\' . ucfirst(strtolower($processorName)) . 'PostProcessor'; if (class_exists($classNameExpanded, true)) { $className = $classNameExpanded; } } if ($className !== false) { $processor = $this->objectManager->get($className, $this->form, $processorArguments); if ($processor instanceof PostProcessorInterface) { $processor->setControllerContext($this->controllerContext); $html .= $processor->process(); } } } } return $html; }
/** * Set the various properties for the element * * For this element this is the prefix, suffix and middleName if they will * be shown in the form * * @param array $parameters Configuration array * @return void */ protected function setVarious(array $parameters) { if (is_array($parameters)) { $keys = ArrayUtility::filterAndSortByNumericKeys($parameters); foreach ($keys as $key) { if ((int) $key && strpos($key, '.') === false) { if (isset($parameters[$key . '.'])) { $childElementArguments = $parameters[$key . '.']; if (in_array($childElementArguments['name'], array('prefix', 'suffix', 'middleName'))) { $this->configuration['various'][$childElementArguments['name']] = true; } } } } } }
/** * Check for the availability of processors, defined in TypoScript, and use them for data processing * * @param ContentObjectRenderer $cObject * @param array $configuration Configuration array * @param array $variables the variables to be processed * @return array the processed data and variables as key/value store * @throws \UnexpectedValueException If a processor class does not exist */ public function process(ContentObjectRenderer $cObject, array $configuration, array $variables) { if (!empty($configuration['dataProcessing.']) && is_array($configuration['dataProcessing.'])) { $processors = $configuration['dataProcessing.']; $processorKeys = ArrayUtility::filterAndSortByNumericKeys($processors); foreach ($processorKeys as $key) { $className = $processors[$key]; if (!class_exists($className)) { throw new \UnexpectedValueException('Processor class name "' . $className . '" does not exist!', 1427455378); } if (!in_array(DataProcessorInterface::class, class_implements($className), true)) { throw new \UnexpectedValueException('Processor with class name "' . $className . '" ' . 'must implement interface "' . DataProcessorInterface::class . '"', 1427455377); } $processorConfiguration = isset($processors[$key . '.']) ? $processors[$key . '.'] : []; $variables = GeneralUtility::makeInstance($className)->process($cObject, $configuration, $processorConfiguration, $variables); } } return $variables; }
/** * The actual rendering of the image file. * Basically sets the dimensions, the background color, the traverses the array of GIFBUILDER objects and finally setting the transparent color if defined. * Creates a GDlib resource in $this->im and works on that * Called by gifBuild() * * @return void * @access private * @see gifBuild() */ public function make() { // Get trivial data $XY = $this->XY; // Reset internal properties $this->saveAlphaLayer = false; // Gif-start $this->im = imagecreatetruecolor($XY[0], $XY[1]); $this->w = $XY[0]; $this->h = $XY[1]; // Transparent layer as background if set and requirements are met if (!empty($this->setup['backColor']) && $this->setup['backColor'] === 'transparent' && $this->png_truecolor && !$this->setup['reduceColors'] && (empty($this->setup['format']) || $this->setup['format'] === 'png')) { // Set transparency properties imagesavealpha($this->im, true); // Fill with a transparent background $transparentColor = imagecolorallocatealpha($this->im, 0, 0, 0, 127); imagefill($this->im, 0, 0, $transparentColor); // Set internal properties to keep the transparency over the rendering process $this->saveAlphaLayer = true; // Force PNG in case no format is set $this->setup['format'] = 'png'; $BGcols = array(); } else { // Fill the background with the given color $BGcols = $this->convertColor($this->setup['backColor']); $Bcolor = imagecolorallocate($this->im, $BGcols[0], $BGcols[1], $BGcols[2]); imagefilledrectangle($this->im, 0, 0, $XY[0], $XY[1], $Bcolor); } // Traverse the GIFBUILDER objects an render each one: if (is_array($this->setup)) { $sKeyArray = ArrayUtility::filterAndSortByNumericKeys($this->setup); foreach ($sKeyArray as $theKey) { $theValue = $this->setup[$theKey]; if ((int) $theKey && ($conf = $this->setup[$theKey . '.'])) { // apply stdWrap to all properties, except for TEXT objects // all properties of the TEXT sub-object have already been stdWrap-ped // before in ->checkTextObj() if ($theValue !== 'TEXT') { $isStdWrapped = array(); foreach ($conf as $key => $value) { $parameter = rtrim($key, '.'); if (!$isStdWrapped[$parameter] && isset($conf[$parameter . '.'])) { $conf[$parameter] = $this->cObj->stdWrap($conf[$parameter], $conf[$parameter . '.']); $isStdWrapped[$parameter] = 1; } } } switch ($theValue) { case 'IMAGE': if ($conf['mask']) { $this->maskImageOntoImage($this->im, $conf, $this->workArea); } else { $this->copyImageOntoImage($this->im, $conf, $this->workArea); } break; case 'TEXT': if (!$conf['hide']) { if (is_array($conf['shadow.'])) { $isStdWrapped = array(); foreach ($conf['shadow.'] as $key => $value) { $parameter = rtrim($key, '.'); if (!$isStdWrapped[$parameter] && isset($conf[$parameter . '.'])) { $conf['shadow.'][$parameter] = $this->cObj->stdWrap($conf[$parameter], $conf[$parameter . '.']); $isStdWrapped[$parameter] = 1; } } $this->makeShadow($this->im, $conf['shadow.'], $this->workArea, $conf); } if (is_array($conf['emboss.'])) { $isStdWrapped = array(); foreach ($conf['emboss.'] as $key => $value) { $parameter = rtrim($key, '.'); if (!$isStdWrapped[$parameter] && isset($conf[$parameter . '.'])) { $conf['emboss.'][$parameter] = $this->cObj->stdWrap($conf[$parameter], $conf[$parameter . '.']); $isStdWrapped[$parameter] = 1; } } $this->makeEmboss($this->im, $conf['emboss.'], $this->workArea, $conf); } if (is_array($conf['outline.'])) { $isStdWrapped = array(); foreach ($conf['outline.'] as $key => $value) { $parameter = rtrim($key, '.'); if (!$isStdWrapped[$parameter] && isset($conf[$parameter . '.'])) { $conf['outline.'][$parameter] = $this->cObj->stdWrap($conf[$parameter], $conf[$parameter . '.']); $isStdWrapped[$parameter] = 1; } } $this->makeOutline($this->im, $conf['outline.'], $this->workArea, $conf); } $conf['imgMap'] = 1; $this->makeText($this->im, $conf, $this->workArea); } break; case 'OUTLINE': if ($this->setup[$conf['textObjNum']] == 'TEXT' && ($txtConf = $this->checkTextObj($this->setup[$conf['textObjNum'] . '.']))) { $this->makeOutline($this->im, $conf, $this->workArea, $txtConf); } break; case 'EMBOSS': if ($this->setup[$conf['textObjNum']] == 'TEXT' && ($txtConf = $this->checkTextObj($this->setup[$conf['textObjNum'] . '.']))) { $this->makeEmboss($this->im, $conf, $this->workArea, $txtConf); } break; case 'SHADOW': if ($this->setup[$conf['textObjNum']] == 'TEXT' && ($txtConf = $this->checkTextObj($this->setup[$conf['textObjNum'] . '.']))) { $this->makeShadow($this->im, $conf, $this->workArea, $txtConf); } break; case 'BOX': $this->makeBox($this->im, $conf, $this->workArea); break; case 'EFFECT': $this->makeEffect($this->im, $conf); break; case 'ADJUST': $this->adjust($this->im, $conf); break; case 'CROP': $this->crop($this->im, $conf); break; case 'SCALE': $this->scale($this->im, $conf); break; case 'WORKAREA': if ($conf['set']) { // this sets the workArea $this->setWorkArea($conf['set']); } if (isset($conf['clear'])) { // This sets the current to the default; $this->workArea = $this->defaultWorkArea; } break; case 'ELLIPSE': $this->makeEllipse($this->im, $conf, $this->workArea); break; } } } } // Preserve alpha transparency if (!$this->saveAlphaLayer) { if ($this->setup['transparentBackground']) { // Auto transparent background is set $Bcolor = imagecolorclosest($this->im, $BGcols[0], $BGcols[1], $BGcols[2]); imagecolortransparent($this->im, $Bcolor); } elseif (is_array($this->setup['transparentColor_array'])) { // Multiple transparent colors are set. This is done via the trick that all transparent colors get // converted to one color and then this one gets set as transparent as png/gif can just have one // transparent color. $Tcolor = $this->unifyColors($this->im, $this->setup['transparentColor_array'], (int) $this->setup['transparentColor.']['closest']); if ($Tcolor >= 0) { imagecolortransparent($this->im, $Tcolor); } } } }
/** * orderedStdWrap * Calls stdWrap for each entry in the provided array * * @param string $content Input value undergoing processing in this function. * @param array $conf stdWrap properties for orderedStdWrap. * @return string The processed input value */ public function stdWrap_orderedStdWrap($content = '', $conf = array()) { $sortedKeysArray = ArrayUtility::filterAndSortByNumericKeys($conf['orderedStdWrap.'], true); foreach ($sortedKeysArray as $key) { $content = $this->stdWrap($content, $conf['orderedStdWrap.'][$key . '.']); } return $content; }
/** * Will traverse input array with configuration per-item and create corresponding GIF files for the menu. * The data of the files are stored in $this->result * * @param array $conf Array with configuration for each item. * @return void * @access private * @see generate() */ public function makeImageMap($conf) { if (!is_array($conf)) { $conf = []; } if (is_array($this->mconf['main.'])) { $gifCreator = GeneralUtility::makeInstance(GifBuilder::class); $gifCreator->init(); $itemsConf = $conf; $conf = $this->mconf['main.']; if (is_array($conf)) { $sKeyArray = ArrayUtility::filterAndSortByNumericKeys($conf); $gifObjCount = (int) end($sKeyArray); // Now we add graphical objects to the gifbuilder-setup $waArr = []; foreach ($itemsConf as $key => $val) { if (is_array($val)) { $gifObjCount++; $waArr[$key]['free'] = $gifObjCount; $sKeyArray = ArrayUtility::filterAndSortByNumericKeys($val); foreach ($sKeyArray as $theKey) { $theValue = $val[$theKey]; if ((int) $theKey && ($theValArr = $val[$theKey . '.'])) { $cObjData = $this->menuArr[$key] ?: []; $gifObjCount++; if ($theValue === 'TEXT') { $waArr[$key]['textNum'] = $gifObjCount; $gifCreator->data = $cObjData; $theValArr = $gifCreator->checkTextObj($theValArr); // if this is not done it seems that imageMaps will be rendered wrong!! unset($theValArr['text.']); // check links $LD = $this->menuTypoLink($this->menuArr[$key], $this->mconf['target'], '', '', [], '', $this->mconf['forceTypeValue']); // If access restricted pages should be shown in menus, change the link of such pages to link to a redirection page: $this->changeLinksForAccessRestrictedPages($LD, $this->menuArr[$key], $this->mconf['target'], $this->mconf['forceTypeValue']); // Overriding URL / Target if set to do so: if ($this->menuArr[$key]['_OVERRIDE_HREF']) { $LD['totalURL'] = $this->menuArr[$key]['_OVERRIDE_HREF']; if ($this->menuArr[$key]['_OVERRIDE_TARGET']) { $LD['target'] = $this->menuArr[$key]['_OVERRIDE_TARGET']; } } // Setting target/url for Image Map: if ($theValArr['imgMap.']['url'] === '') { $theValArr['imgMap.']['url'] = $LD['totalURL']; } if ($theValArr['imgMap.']['target'] === '') { $theValArr['imgMap.']['target'] = $LD['target']; } if (is_array($theValArr['imgMap.']['altText.'])) { $cObj = GeneralUtility::makeInstance(ContentObjectRenderer::class); $cObj->start($cObjData, 'pages'); if (isset($theValArr['imgMap.']['altText.'])) { $theValArr['imgMap.']['altText'] = $cObj->stdWrap($theValArr['imgMap.']['altText'], $theValArr['imgMap.']['altText.']); } unset($theValArr['imgMap.']['altText.']); } if (is_array($theValArr['imgMap.']['titleText.'])) { $cObj = GeneralUtility::makeInstance(ContentObjectRenderer::class); $cObj->start($cObjData, 'pages'); if (isset($theValArr['imgMap.']['titleText.'])) { $theValArr['imgMap.']['titleText'] = $cObj->stdWrap($theValArr['imgMap.']['titleText'], $theValArr['imgMap.']['titleText.']); } unset($theValArr['imgMap.']['titleText.']); } } // This code goes one level in if the object is an image. If 'file' and/or 'mask' appears to be GIFBUILDER-objects, they are both searched for TEXT objects, and if a textobj is found, it's checked with the currently loaded record!! if ($theValue === 'IMAGE') { if ($theValArr['file'] === 'GIFBUILDER') { $temp_sKeyArray = ArrayUtility::filterAndSortByNumericKeys($theValArr['file.']); foreach ($temp_sKeyArray as $temp_theKey) { if ($theValArr['mask.'][$temp_theKey] === 'TEXT') { $gifCreator->data = $this->menuArr[$key] ?: []; $theValArr['mask.'][$temp_theKey . '.'] = $gifCreator->checkTextObj($theValArr['mask.'][$temp_theKey . '.']); // If this is not done it seems that imageMaps will be rendered wrong!! unset($theValArr['mask.'][$temp_theKey . '.']['text.']); } } } if ($theValArr['mask'] === 'GIFBUILDER') { $temp_sKeyArray = ArrayUtility::filterAndSortByNumericKeys($theValArr['mask.']); foreach ($temp_sKeyArray as $temp_theKey) { if ($theValArr['mask.'][$temp_theKey] === 'TEXT') { $gifCreator->data = $this->menuArr[$key] ?: []; $theValArr['mask.'][$temp_theKey . '.'] = $gifCreator->checkTextObj($theValArr['mask.'][$temp_theKey . '.']); // if this is not done it seems that imageMaps will be rendered wrong!! unset($theValArr['mask.'][$temp_theKey . '.']['text.']); } } } } // Checks if disabled is set... $setObjFlag = 1; if ($theValArr['if.']) { /** @var ContentObjectRenderer $cObj */ $cObj = GeneralUtility::makeInstance(ContentObjectRenderer::class); $cObj->start($cObjData, 'pages'); if (!empty($theValArr['if.']) && !$cObj->checkIf($theValArr['if.'])) { $setObjFlag = 0; } unset($theValArr['if.']); } // Set the object! if ($setObjFlag) { $conf[$gifObjCount] = $theValue; $conf[$gifObjCount . '.'] = $theValArr; } } } } } $gifCreator->start($conf, $this->getTypoScriptFrontendController()->page); // calculations $dConf = []; foreach ($waArr as $key => $val) { if ($dConf[$key] = $itemsConf[$key]['distrib']) { $textBB = $gifCreator->objBB[$val['textNum']]; $dConf[$key] = str_replace(['textX', 'textY'], [$textBB[0], $textBB[1]], $dConf[$key]); $dConf[$key] = GeneralUtility::intExplode(',', $gifCreator->calcOffset($dConf[$key])); } } $workArea = GeneralUtility::intExplode(',', $gifCreator->calcOffset($this->mconf['dWorkArea'])); foreach ($waArr as $key => $val) { $index = $val['free']; $gifCreator->setup[$index] = 'WORKAREA'; $workArea[2] = $dConf[$key][2] ?: $dConf[$key][0]; $workArea[3] = $dConf[$key][3] ?: $dConf[$key][1]; $gifCreator->setup[$index . '.']['set'] = implode(',', $workArea); $workArea[0] += $dConf[$key][0]; $workArea[1] += $dConf[$key][1]; } if ($this->mconf['debugRenumberedObject']) { echo '<h3>Renumbered GIFBUILDER object:</h3>'; debug($gifCreator->setup); } $gifCreator->createTempSubDir('menu/'); $gifFileName = $gifCreator->fileName('menu/'); // Gets the ImageMap from the cache... $cache = $this->getCache(); $imgHash = md5($gifFileName); $imgMap = $cache->get($imgHash); // File exists if ($imgMap && file_exists($gifFileName)) { $info = @getimagesize($gifFileName); $w = $info[0]; $h = $info[1]; } else { // file is generated $gifCreator->make(); $w = $gifCreator->w; $h = $gifCreator->h; $gifCreator->output($gifFileName); $gifCreator->destroy(); $imgMap = $gifCreator->map; $cache->set($imgHash, $imgMap, ['ident_MENUIMAGEMAP'], 0); } $imgMap .= $this->mconf['imgMapExtras']; $this->result = ['output_file' => $gifFileName, 'output_w' => $w, 'output_h' => $h, 'imgMap' => $imgMap]; } } }
/** * Splitting a string for ImageTTFBBox up into an array where each part has its own configuration options. * * @param string $string UTF-8 string * @param array $splitRendering Split-rendering configuration from GIFBUILDER TEXT object. * @param int $fontSize Current fontsize * @param string $fontFile Current font file * @return array Array with input string splitted according to configuration */ public function splitString($string, $splitRendering, $fontSize, $fontFile) { // Initialize by setting the whole string and default configuration as the first entry. $result = array(); $result[] = array('str' => $string, 'fontSize' => $fontSize, 'fontFile' => $fontFile); // Traverse the split-rendering configuration: // Splitting will create more entries in $result with individual configurations. if (is_array($splitRendering)) { $sKeyArray = ArrayUtility::filterAndSortByNumericKeys($splitRendering); // Traverse configured options: foreach ($sKeyArray as $key) { $cfg = $splitRendering[$key . '.']; // Process each type of split rendering keyword: switch ((string) $splitRendering[$key]) { case 'highlightWord': if ((string) $cfg['value'] !== '') { $newResult = array(); // Traverse the current parts of the result array: foreach ($result as $part) { // Explode the string value by the word value to highlight: $explodedParts = explode($cfg['value'], $part['str']); foreach ($explodedParts as $c => $expValue) { if ((string) $expValue !== '') { $newResult[] = array_merge($part, array('str' => $expValue)); } if ($c + 1 < count($explodedParts)) { $newResult[] = array('str' => $cfg['value'], 'fontSize' => $cfg['fontSize'] ? $cfg['fontSize'] : $part['fontSize'], 'fontFile' => $cfg['fontFile'] ? $cfg['fontFile'] : $part['fontFile'], 'color' => $cfg['color'], 'xSpaceBefore' => $cfg['xSpaceBefore'], 'xSpaceAfter' => $cfg['xSpaceAfter'], 'ySpaceBefore' => $cfg['ySpaceBefore'], 'ySpaceAfter' => $cfg['ySpaceAfter']); } } } // Set the new result as result array: if (!empty($newResult)) { $result = $newResult; } } break; case 'charRange': if ((string) $cfg['value'] !== '') { // Initialize range: $ranges = GeneralUtility::trimExplode(',', $cfg['value'], true); foreach ($ranges as $i => $rangeDef) { $ranges[$i] = GeneralUtility::intExplode('-', $ranges[$i]); if (!isset($ranges[$i][1])) { $ranges[$i][1] = $ranges[$i][0]; } } $newResult = array(); // Traverse the current parts of the result array: foreach ($result as $part) { // Initialize: $currentState = -1; $bankAccum = ''; // Explode the string value by the word value to highlight: $utf8Chars = $this->csConvObj->utf8_to_numberarray($part['str']); foreach ($utf8Chars as $utfChar) { // Find number and evaluate position: $uNumber = (int) $this->csConvObj->utf8CharToUnumber($utfChar); $inRange = 0; foreach ($ranges as $rangeDef) { if ($uNumber >= $rangeDef[0] && (!$rangeDef[1] || $uNumber <= $rangeDef[1])) { $inRange = 1; break; } } if ($currentState == -1) { $currentState = $inRange; } // Initialize first char // Switch bank: if ($inRange != $currentState && $uNumber !== 9 && $uNumber !== 10 && $uNumber !== 13 && $uNumber !== 32) { // Set result: if ($bankAccum !== '') { $newResult[] = array('str' => $bankAccum, 'fontSize' => $currentState && $cfg['fontSize'] ? $cfg['fontSize'] : $part['fontSize'], 'fontFile' => $currentState && $cfg['fontFile'] ? $cfg['fontFile'] : $part['fontFile'], 'color' => $currentState ? $cfg['color'] : '', 'xSpaceBefore' => $currentState ? $cfg['xSpaceBefore'] : '', 'xSpaceAfter' => $currentState ? $cfg['xSpaceAfter'] : '', 'ySpaceBefore' => $currentState ? $cfg['ySpaceBefore'] : '', 'ySpaceAfter' => $currentState ? $cfg['ySpaceAfter'] : ''); } // Initialize new settings: $currentState = $inRange; $bankAccum = ''; } // Add char to bank: $bankAccum .= $utfChar; } // Set result for FINAL part: if ($bankAccum !== '') { $newResult[] = array('str' => $bankAccum, 'fontSize' => $currentState && $cfg['fontSize'] ? $cfg['fontSize'] : $part['fontSize'], 'fontFile' => $currentState && $cfg['fontFile'] ? $cfg['fontFile'] : $part['fontFile'], 'color' => $currentState ? $cfg['color'] : '', 'xSpaceBefore' => $currentState ? $cfg['xSpaceBefore'] : '', 'xSpaceAfter' => $currentState ? $cfg['xSpaceAfter'] : '', 'ySpaceBefore' => $currentState ? $cfg['ySpaceBefore'] : '', 'ySpaceAfter' => $currentState ? $cfg['ySpaceAfter'] : ''); } } // Set the new result as result array: if (!empty($newResult)) { $result = $newResult; } } break; } } } return $result; }
/** * Build validation rules from typoscript. * The old breakOnError property are no longer supported * * @param array $rawArgument * @return void */ public function buildRules(array $rawArgument = array()) { $userConfiguredFormTyposcript = $this->configuration->getTypoScript(); $rulesTyposcript = isset($userConfiguredFormTyposcript['rules.']) ? $userConfiguredFormTyposcript['rules.'] : null; $this->rules[$this->configuration->getPrefix()] = array(); if (is_array($rulesTyposcript)) { $keys = ArrayUtility::filterAndSortByNumericKeys($rulesTyposcript); foreach ($keys as $key) { $ruleName = $rulesTyposcript[$key]; $validatorClassName = $this->typoScriptRepository->getRegisteredClassName($ruleName, 'registeredValidators'); if ($validatorClassName === null) { throw new \RuntimeException('Class "' . $validatorClassName . '" not registered via typoscript.'); } if ((int) $key && strpos($key, '.') === false) { $ruleArguments = $rulesTyposcript[$key . '.']; $fieldName = $this->formUtility->sanitizeNameAttribute($ruleArguments['element']); // remove unsupported validator options $validatorOptions = $ruleArguments; $validatorOptions['errorMessage'] = array($ruleArguments['error.'], $ruleArguments['error']); $keysToRemove = array_flip(array('breakOnError', 'message', 'message.', 'error', 'error.', 'showMessage')); $validatorOptions = array_diff_key($validatorOptions, $keysToRemove); // Instantiate the validator to check if all required options are assigned // and to use the validator message rendering function to pre-render the mandatory message /** @var AbstractValidator $validator */ $validator = $this->objectManager->get($validatorClassName, $validatorOptions); if ($validator instanceof AbstractValidator) { $validator->setRawArgument($rawArgument); $validator->setFormUtility($this->formUtility); if ((int) $ruleArguments['showMessage'] === 1) { $mandatoryMessage = $validator->renderMessage($ruleArguments['message.'], $ruleArguments['message']); } else { $mandatoryMessage = null; } $this->rules[$this->configuration->getPrefix()][$fieldName][] = array('validator' => $validator, 'validatorName' => $validatorClassName, 'validatorOptions' => $validatorOptions, 'mandatoryMessage' => $mandatoryMessage); } else { throw new \RuntimeException('Class "' . $validatorClassName . '" could not be loaded.'); } } } } }
/** * Handles the incoming form data * * @param Element $element * @param array $userConfiguredElementTypoScript * @return array */ protected function handleIncomingValues(Element $element, array $userConfiguredElementTypoScript) { if (!$this->getIncomingData()) { return; } $elementName = $element->getName(); if ($element->getHtmlAttribute('value') !== null) { $modelValue = $element->getHtmlAttribute('value'); } else { $modelValue = $element->getAdditionalArgument('value'); } if ($this->getIncomingData()->getIncomingField($elementName) !== null) { /* filter values and set it back to incoming fields */ /* remove xss every time */ $userConfiguredElementTypoScript['filters.'][-1] = 'removexss'; $keys = ArrayUtility::filterAndSortByNumericKeys($userConfiguredElementTypoScript['filters.']); foreach ($keys as $key) { $class = $userConfiguredElementTypoScript['filters.'][$key]; if ((int) $key && strpos($key, '.') === false) { $filterArguments = $userConfiguredElementTypoScript['filters.'][$key . '.']; $filterClassName = $this->typoScriptRepository->getRegisteredClassName((string) $class, 'registeredFilters'); if ($filterClassName !== null) { // toDo: handel array values if (is_string($this->getIncomingData()->getIncomingField($elementName))) { if (is_null($filterArguments)) { $filter = $this->objectManager->get($filterClassName); } else { $filter = $this->objectManager->get($filterClassName, $filterArguments); } if ($filter) { $value = $filter->filter($this->getIncomingData()->getIncomingField($elementName)); $this->getIncomingData()->setIncomingField($elementName, $value); } else { throw new \RuntimeException('Class "' . $filterClassName . '" could not be loaded.'); } } } else { throw new \RuntimeException('Class "' . $filterClassName . '" not registered via TypoScript.'); } } } if ($element->getHtmlAttribute('value') !== null) { $element->setHtmlAttribute('value', $this->getIncomingData()->getIncomingField($elementName)); } else { $element->setAdditionalArgument('value', $this->getIncomingData()->getIncomingField($elementName)); } } $this->signalSlotDispatcher->dispatch(__CLASS__, 'txFormHandleIncomingValues', array($element, $this->getIncomingData(), $modelValue, $this)); }
/** * @test * @dataProvider filterAndSortByNumericKeysWithoutAcceptAnyKey * * @param array $input * @param array $expected */ public function filterAndSortByNumericKeysBehavesCorrectlyForAcceptAnyKeysIsFalse($input, $expected) { $result = ArrayUtility::filterAndSortByNumericKeys($input); $this->assertEquals($result, $expected); }
/** * Takes a TypoScript array as input and returns an array which contains all integer properties found which had a value (not only properties). The output array will be sorted numerically. * Call it like \TYPO3\CMS\Core\TypoScript\TemplateService::sortedKeyList() * * @param array $setupArr TypoScript array with numerical array in * @param bool $acceptOnlyProperties If set, then a value is not required - the properties alone will be enough. * @return array An array with all integer properties listed in numeric order. * @see \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::cObjGet(), \TYPO3\CMS\Frontend\Imaging\GifBuilder, \TYPO3\CMS\Frontend\ContentObject\Menu\ImageMenuContentObject::makeImageMap() * @deprecated since TYPO3 v8, will be removed in TYPO3 v9, use ArrayUtility::filterAndSortByNumericKeys instead */ public static function sortedKeyList($setupArr, $acceptOnlyProperties = false) { GeneralUtility::logDeprecatedFunction(); return ArrayUtility::filterAndSortByNumericKeys($setupArr, $acceptOnlyProperties); }
/** * Rendering of a "numerical array" of Form objects from TypoScript * Creates new object for each element found * * @param AbstractJsonElement $parentElement Parent model object * @param array $typoscript Configuration array * @return void */ protected function getChildElementsByIntegerKey(AbstractJsonElement $parentElement, array $typoscript) { if (is_array($typoscript)) { $keys = ArrayUtility::filterAndSortByNumericKeys($typoscript); foreach ($keys as $key) { $class = $typoscript[$key]; if ((int) $key && strpos($key, '.') === false) { if (isset($typoscript[$key . '.'])) { $elementArguments = $typoscript[$key . '.']; } else { $elementArguments = array(); } $this->setElementType($parentElement, $class, $elementArguments); } } } }