ACC SHELL

Path : /srv/www/vhosts/centrumlb/3rdparty/Nette/Latte/Macros/
File Upload :
Current File : /srv/www/vhosts/centrumlb/3rdparty/Nette/Latte/Macros/CoreMacros.php

<?php

/**
 * This file is part of the Nette Framework (http://nette.org)
 * Copyright (c) 2004 David Grudl (http://davidgrudl.com)
 * @package Nette\Latte\Macros
 */



/**
 * Basic macros for Latte.
 *
 * - {if ?} ... {elseif ?} ... {else} ... {/if}
 * - {ifset ?} ... {elseifset ?} ... {/ifset}
 * - {for ?} ... {/for}
 * - {foreach ?} ... {/foreach}
 * - {$variable} with escaping
 * - {!$variable} without escaping
 * - {=expression} echo with escaping
 * - {!=expression} echo without escaping
 * - {?expression} evaluate PHP statement
 * - {_expression} echo translation with escaping
 * - {!_expression} echo translation without escaping
 * - {attr ?} HTML element attributes
 * - {capture ?} ... {/capture} capture block to parameter
 * - {var var => value} set template parameter
 * - {default var => value} set default template parameter
 * - {dump $var}
 * - {debugbreak}
 * - {l} {r} to display { }
 *
 * @author     David Grudl
 * @package Nette\Latte\Macros
 */
class NCoreMacros extends NMacroSet
{


	public static function install(NLatteCompiler $compiler)
	{
		$me = new self($compiler);

		$me->addMacro('if', array($me, 'macroIf'), array($me, 'macroEndIf'));
		$me->addMacro('elseif', '} elseif (%node.args) {');
		$me->addMacro('else', array($me, 'macroElse'));
		$me->addMacro('ifset', 'if (isset(%node.args)) {', '}');
		$me->addMacro('elseifset', '} elseif (isset(%node.args)) {');

		$me->addMacro('foreach', '', array($me, 'macroEndForeach'));
		$me->addMacro('for', 'for (%node.args) {', '}');
		$me->addMacro('while', 'while (%node.args) {', '}');
		$me->addMacro('continueIf', 'if (%node.args) continue');
		$me->addMacro('breakIf', 'if (%node.args) break');
		$me->addMacro('first', 'if ($iterator->isFirst(%node.args)) {', '}');
		$me->addMacro('last', 'if ($iterator->isLast(%node.args)) {', '}');
		$me->addMacro('sep', 'if (!$iterator->isLast(%node.args)) {', '}');

		$me->addMacro('var', array($me, 'macroVar'));
		$me->addMacro('assign', array($me, 'macroVar')); // deprecated
		$me->addMacro('default', array($me, 'macroVar'));
		$me->addMacro('dump', array($me, 'macroDump'));
		$me->addMacro('debugbreak', array($me, 'macroDebugbreak'));
		$me->addMacro('l', '?>{<?php');
		$me->addMacro('r', '?>}<?php');

		$me->addMacro('_', array($me, 'macroTranslate'), array($me, 'macroTranslate'));
		$me->addMacro('=', array($me, 'macroExpr'));
		$me->addMacro('?', array($me, 'macroExpr'));

		$me->addMacro('capture', array($me, 'macroCapture'), array($me, 'macroCaptureEnd'));
		$me->addMacro('include', array($me, 'macroInclude'));
		$me->addMacro('use', array($me, 'macroUse'));

		$me->addMacro('class', NULL, NULL, array($me, 'macroClass'));
		$me->addMacro('attr', array($me, 'macroOldAttr'), '', array($me, 'macroAttr'));
		$me->addMacro('href', NULL); // TODO: placeholder
	}


	/**
	 * Finishes template parsing.
	 * @return array(prolog, epilog)
	 */
	public function finalize()
	{
		return array('list($_l, $_g) = NCoreMacros::initRuntime($template, '
			. var_export($this->getCompiler()->getTemplateId(), TRUE) . ')');
	}


	/********************* macros ****************d*g**/


	/**
	 * {if ...}
	 */
	public function macroIf(NMacroNode $node, NPhpWriter $writer)
	{
		if ($node->data->capture = ($node->args === '')) {
			return 'ob_start()';
		}
		if ($node->prefix === NMacroNode::PREFIX_TAG) {
			return $writer->write($node->htmlNode->closing ? 'if (array_pop($_l->ifs)) {' : 'if ($_l->ifs[] = (%node.args)) {');
		}
		return $writer->write('if (%node.args) {');
	}


	/**
	 * {/if ...}
	 */
	public function macroEndIf(NMacroNode $node, NPhpWriter $writer)
	{
		if ($node->data->capture) {
			if ($node->args === '') {
				throw new NCompileException('Missing condition in {if} macro.');
			}
			return $writer->write('if (%node.args) '
				. (isset($node->data->else) ? '{ ob_end_clean(); ob_end_flush(); }' : 'ob_end_flush();')
				. ' else '
				. (isset($node->data->else) ? '{ $_else = ob_get_contents(); ob_end_clean(); ob_end_clean(); echo $_else; }' : 'ob_end_clean();')
			);
		}
		return '}';
	}


	/**
	 * {else}
	 */
	public function macroElse(NMacroNode $node, NPhpWriter $writer)
	{
		$ifNode = $node->parentNode;
		if ($ifNode && $ifNode->name === 'if' && $ifNode->data->capture) {
			if (isset($ifNode->data->else)) {
				throw new NCompileException("Macro {if} supports only one {else}.");
			}
			$ifNode->data->else = TRUE;
			return 'ob_start()';
		}
		return '} else {';
	}


	/**
	 * {_$var |modifiers}
	 */
	public function macroTranslate(NMacroNode $node, NPhpWriter $writer)
	{
		if ($node->closing) {
			return $writer->write('echo %modify($template->translate(ob_get_clean()))');

		} elseif ($node->isEmpty = ($node->args !== '')) {
			return $writer->write('echo %modify($template->translate(%node.args))');

		} else {
			return 'ob_start()';
		}
	}


	/**
	 * {include "file" [,] [params]}
	 */
	public function macroInclude(NMacroNode $node, NPhpWriter $writer)
	{
		$code = $writer->write('NCoreMacros::includeTemplate(%node.word, %node.array? + $template->getParameters(), $_l->templates[%var])',
			$this->getCompiler()->getTemplateId());

		if ($node->modifiers) {
			return $writer->write('echo %modify(%raw->__toString(TRUE))', $code);
		} else {
			return $code . '->render()';
		}
	}


	/**
	 * {use class MacroSet}
	 */
	public function macroUse(NMacroNode $node, NPhpWriter $writer)
	{
		NCallback::create($node->tokenizer->fetchWord(), 'install')
			->invoke($this->getCompiler())
			->initialize();
	}


	/**
	 * {capture $variable}
	 */
	public function macroCapture(NMacroNode $node, NPhpWriter $writer)
	{
		$variable = $node->tokenizer->fetchWord();
		if (substr($variable, 0, 1) !== '$') {
			throw new NCompileException("Invalid capture block variable '$variable'");
		}
		$node->data->variable = $variable;
		return 'ob_start()';
	}


	/**
	 * {/capture}
	 */
	public function macroCaptureEnd(NMacroNode $node, NPhpWriter $writer)
	{
		return $node->data->variable . $writer->write(" = %modify(ob_get_clean())");
	}


	/**
	 * {foreach ...}
	 */
	public function macroEndForeach(NMacroNode $node, NPhpWriter $writer)
	{
		if ($node->modifiers !== '|noiterator' && preg_match('#\W(\$iterator|include|require|get_defined_vars)\W#', $this->getCompiler()->expandTokens($node->content))) {
			$node->openingCode = '<?php $iterations = 0; foreach ($iterator = $_l->its[] = new NSmartCachingIterator('
			. preg_replace('#(.*)\s+as\s+#i', '$1) as ', $writer->formatArgs(), 1) . ') { ?>';
			$node->closingCode = '<?php $iterations++; } array_pop($_l->its); $iterator = end($_l->its) ?>';
		} else {
			$node->openingCode = '<?php $iterations = 0; foreach (' . $writer->formatArgs() . ') { ?>';
			$node->closingCode = '<?php $iterations++; } ?>';
		}
	}


	/**
	 * n:class="..."
	 */
	public function macroClass(NMacroNode $node, NPhpWriter $writer)
	{
		return $writer->write('if ($_l->tmp = array_filter(%node.array)) echo \' class="\' . %escape(implode(" ", array_unique($_l->tmp))) . \'"\'');
	}


	/**
	 * n:attr="..."
	 */
	public function macroAttr(NMacroNode $node, NPhpWriter $writer)
	{
		return $writer->write('echo NHtml::el(NULL, %node.array)->attributes()');
	}


	/**
	 * {attr ...}
	 * @deprecated
	 */
	public function macroOldAttr(NMacroNode $node)
	{
		return NStrings::replace($node->args . ' ', '#\)\s+#', ')->');
	}


	/**
	 * {dump ...}
	 */
	public function macroDump(NMacroNode $node, NPhpWriter $writer)
	{
		$args = $writer->formatArgs();
		return 'NDebugger::barDump(' . ($node->args ? "array(" . $writer->write('%var', $args) . " => $args)" : 'get_defined_vars()')
			. ', "Template " . str_replace(dirname(dirname($template->getFile())), "\xE2\x80\xA6", $template->getFile()))';
	}


	/**
	 * {debugbreak ...}
	 */
	public function macroDebugbreak(NMacroNode $node, NPhpWriter $writer)
	{
		return $writer->write(($node->args == NULL ? '' : 'if (!(%node.args)); else')
			. 'if (function_exists("debugbreak")) debugbreak(); elseif (function_exists("xdebug_break")) xdebug_break()');
	}


	/**
	 * {var ...}
	 * {default ...}
	 */
	public function macroVar(NMacroNode $node, NPhpWriter $writer)
	{
		$out = '';
		$var = TRUE;
		$tokenizer = $writer->preprocess();
		while ($token = $tokenizer->fetchToken()) {
			if ($var && ($token['type'] === NMacroTokenizer::T_SYMBOL || $token['type'] === NMacroTokenizer::T_VARIABLE)) {
				if ($node->name === 'default') {
					$out .= "'" . ltrim($token['value'], "$") . "'";
				} else {
					$out .= '$' . ltrim($token['value'], "$");
				}
				$var = NULL;

			} elseif (($token['value'] === '=' || $token['value'] === '=>') && $token['depth'] === 0) {
				$out .= $node->name === 'default' ? '=>' : '=';
				$var = FALSE;

			} elseif ($token['value'] === ',' && $token['depth'] === 0) {
				$out .= $node->name === 'default' ? ',' : ';';
				$var = TRUE;

			} elseif ($var === NULL && $node->name === 'default' && $token['type'] !== NMacroTokenizer::T_WHITESPACE) {
				throw new NCompileException("Unexpected '$token[value]' in {default $node->args}");

			} else {
				$out .= $writer->canQuote($tokenizer) ? "'$token[value]'" : $token['value'];
			}
		}
		return $node->name === 'default' ? "extract(array($out), EXTR_SKIP)" : $out;
	}


	/**
	 * {= ...}
	 * {? ...}
	 */
	public function macroExpr(NMacroNode $node, NPhpWriter $writer)
	{
		return $writer->write(($node->name === '?' ? '' : 'echo ') . '%modify(%node.args)');
	}


	/********************* run-time helpers ****************d*g**/


	/**
	 * Includes subtemplate.
	 * @param  mixed      included file name or template
	 * @param  array      parameters
	 * @param  ITemplate  current template
	 * @return NTemplate
	 */
	public static function includeTemplate($destination, array $params, ITemplate $template)
	{
		if ($destination instanceof ITemplate) {
			$tpl = $destination;

		} elseif ($destination == NULL) { // intentionally ==
			throw new InvalidArgumentException("Template file name was not specified.");

		} elseif ($template instanceof IFileTemplate) {
			if (substr($destination, 0, 1) !== '/' && substr($destination, 1, 1) !== ':') {
				$destination = dirname($template->getFile()) . '/' . $destination;
			}
			$tpl = clone $template;
			$tpl->setFile($destination);

		} else {
			throw new NotSupportedException('Macro {include "filename"} is supported only with IFileTemplate.');
		}

		$tpl->setParameters($params); // interface?
		return $tpl;
	}


	/**
	 * Initializes local & global storage in template.
	 * @return \stdClass
	 */
	public static function initRuntime(ITemplate $template, $templateId)
	{
		// local storage
		if (isset($template->_l)) {
			$local = $template->_l;
			unset($template->_l);
		} else {
			$local = new stdClass;
		}
		$local->templates[$templateId] = $template;

		// global storage
		if (!isset($template->_g)) {
			$template->_g = new stdClass;
		}

		return array($local, $template->_g);
	}

}

ACC SHELL 2018