Automad = $Automad; $this->Runtime = $Runtime; $this->InPage = $InPage; } /** * Process a file related snippet like `<@ foreach "*.jpg" { options } @> ... <@ end @>`. * * @param string $file * @param array $options * @param string $snippet * @param string $directory * @param bool $collectSnippetDefinitions * @return string the processed file snippet */ public function processFileSnippet( string $file, array $options, string $snippet, string $directory, bool $collectSnippetDefinitions, ): string { $runtimeShelf = $this->Runtime->shelve(); // Store current filename and its basename in the system variable buffer. $this->Runtime->set(Fields::FILE, $file); $this->Runtime->set(Fields::BASENAME, basename($file)); // If $file is an image, also provide width and height (and possibly a new filename after a resize). if (FileUtils::fileIsImage($file)) { // The Original file size. $imgSize = getimagesize(AM_BASE_DIR . $file); $this->Runtime->set(Fields::WIDTH, $imgSize[0]); $this->Runtime->set(Fields::HEIGHT, $imgSize[1]); // If any options are given, create a resized version of the image. if (!empty($options)) { $options = array_merge( array( 'width' => 0, 'height' => 0, 'crop' => false ), $options ); $img = new Image(AM_BASE_DIR . $file, $options['width'], $options['height'], $options['crop']); $this->Runtime->set(Fields::FILE_RESIZED, $img->file); $this->Runtime->set(Fields::WIDTH_RESIZED, $img->width); $this->Runtime->set(Fields::HEIGHT_RESIZED, $img->height); } } // Process snippet. $TemplateProcessor = new TemplateProcessor( $this->Automad, $this->Runtime, new ContentProcessor( $this->Automad, $this->Runtime, $this->InPage ) ); $html = $TemplateProcessor->process($snippet, $directory, $collectSnippetDefinitions); // Unshelve runtime data. $this->Runtime->unshelve($runtimeShelf); return $html; } /** * Process content variables and optional string functions. Like {[ var | function1 ( parameters ) | function2 | ... ]} * * Find and replace all variables within $str with values from either the context page data array or, if not defined there, from the shared data array, * or from the $_GET array (only those starting with a "?"). * * By first checking the page data (handled by the Page class), basically all shared data variables can be easily overridden by a page. * Optionally all values can be parsed as "JSON safe" ($isOptionString), by escaping all quotes and wrapping variable is quotes when needed. * In case a variable is used as an option value for a method and is not part of a string, that variable doesn't need to be * wrapped in double quotes to work within the JSON string - the double quotes get added automatically. * * By setting $inPageEdit to true, for every processed variable, a temporary markup for an edit button is appended to the actual value. * That temporary button still has to be processed later by calling processInPageEditButtons(). * * @param string $str * @param bool $isOptionString * @param bool $inPageEdit * @return string The processed $str */ public function processVariables(string $str, bool $isOptionString = false, bool $inPageEdit = false): string { if ($isOptionString) { $str = preg_replace_callback( '/' . PatternAssembly::keyValue() . '/s', function ($pair) { if (strpos($pair['value'], Delimiters::VAR_OPEN) === 0) { $pair['value'] = '"' . trim($pair['value']) . '"'; } return $pair['key'] . ':' . $pair['value']; }, $str ); } return preg_replace_callback( '/' . PatternAssembly::variable('var') . '/s', function ($matches) use ($isOptionString, $inPageEdit) { // Get the value. $value = $this->getValue($matches['varName']); // Resolve URLs in content before passing it to pipe functions // to make sure images and files can be used correctly in custom // pipe functions. $value = URLProcessor::resolveUrls($value, 'relativeUrlToBase', array($this->Automad->Context->get())); // Get pipe functions. $functions = array(); preg_match_all('/' . PatternAssembly::pipe('pipe') . '/s', $matches['varFunctions'], $pipes, PREG_SET_ORDER); foreach ($pipes as $pipe) { if (!empty($pipe['pipeFunction'])) { $parametersArray = array(); if (isset($pipe['pipeParameters'])) { preg_match_all('/' . PatternAssembly::csv() . '/s', $pipe['pipeParameters'], $pipeParameters, PREG_SET_ORDER); foreach ($pipeParameters as $match) { $parameter = trim($match[1]); if (in_array($parameter, array('true', 'false'))) { $parameter = filter_var($parameter, FILTER_VALIDATE_BOOLEAN); } else { // Remove outer quotes and strip slashes. $parameter = preg_replace('/^([\'"])(.*)\1$/s', '$2', $parameter); $parameter = stripcslashes($this->processVariables($parameter)); } $parametersArray[] = $parameter; } } $functions[] = array( 'name' => $pipe['pipeFunction'], 'parameters' => $parametersArray ); } // Math. if (!empty($pipe['pipeOperator'])) { $functions[] = array( 'name' => $pipe['pipeOperator'], 'parameters' => $this->processVariables($pipe['pipeNumber']) ); } } // Modify $value by processing all matched string functions. $value = Pipe::process($value, $functions); // Escape values to be used in option strings. if ($isOptionString) { $value = Str::escape($value); } // Inject "in-page edit" button in case varName starts with a word-char and an user is logged in. // The button needs to be wrapped in delimiters to enable a secondary cleanup step to remove buttons within HTML tags. if ($inPageEdit) { $value = $this->InPage->injectTemporaryEditButton( $value, $matches['varName'], $this->Automad->Context ); } return $value; }, $str ); } /** * Get the value of a given variable key depending on the current context - either from the page data, * the system variables or from the $_GET array. * * @param string $key * @return string The value */ private function getValue(string $key): string { if (strpos($key, '?') === 0) { $key = substr($key, 1); return Request::query($key); } // Session variable. if (strpos($key, '%') === 0) { return SessionData::get($key); } // Blocks variable. if (strpos($key, '+') === 0) { $value = Blocks::render( $this->Automad->Context->get()->get($key, true), $this->Automad ); return $value; } // First try to get the value from the current Runtime object. $value = $this->Runtime->get($key); // If $value is NULL (!), try the current context. if (is_null($value)) { $value = $this->Automad->Context->get()->get($key); } return strval($value); } } __halt_compiler();----SIGNATURE:----RURYhIdt+CDG/vl0Z4TkGv1WOG3kMbWssGIJ9IRKtVqhlla4XTee/FqrP797Z7oAhgtZfH6D81Ymn7bAuP9otmt1ew8mqbEump8jrX/wAwIhGCOT+MD5pvh2X60LW5lWjcCnPO5tjjp4EKMcPZZQbVmrmrEoDgGPRAL3DmvnA9TT1R3etQcKJ01NjfYhdMr6aqAR4wx3i1l1IQjgEsCxcX6oswDxwOg7B0CJKlV28vmxsKv/24xaCzAnVEBA3JP7FqXmfrRR0RyAl28fP7NzoikMXXY0F+OhxVKHfFWA1kTyriXp7SPa8FazuLpKLehpPjHgqgUIXRWK2E8lfeWl6hkPhTTZaR03EbL2zCfOius8ERxSGPoNfYHql+CFhoufVHqv+AON8Y40KyU0amTYJuY5rIwdcepKSrGwmMm6vuKSNOo/6XIiiBO54v1K+rv6dxJQqQAWWbS5PwilkfNzQTvjBpXkehs4ONExZMTaDhnkaRlqjOatWEA+kHGn/b5h/4YftJBCTh6owi+Ywl9UtkO+JUE9Z9/OeVQIdIqmpM0FM6KNP1tQJSQcJUSmOTCGgbUqo7MJZw+Hidv1NiKpa5qlGVFi95hI9CwkO4+cRgIIE8e44G1WplP6PrTFCOb3FZLvaj52sGCEa5UWfzWmzSWNUKihoOZikKfC8ZZbNrQ=----ATTACHMENT:----NTg2NDYxMjg4ODY4NzI3NSA0NDY5NDQ4Mzk5NDk3NDIzIDY1NTA4MjM1NTgwMDg3Mzc=