/** * Called before child nodes are visited. * * @param Twig_Node $node The node to visit * @param Twig_Environment $env The Twig environment instance * * @return Twig_Node The modified node */ public function enterNode(Twig_Node $node, Twig_Environment $env) { if ($node instanceof Twig_Node_Module) { $this->inAModule = true; $this->tags = array(); $this->filters = array(); $this->functions = array(); return $node; } elseif ($this->inAModule) { // look for tags if ($node->getNodeTag() && !isset($this->tags[$node->getNodeTag()])) { $this->tags[$node->getNodeTag()] = $node; } // look for filters if ($node instanceof Twig_Node_Expression_Filter && !isset($this->filters[$node->getNode('filter')->getAttribute('value')])) { $this->filters[$node->getNode('filter')->getAttribute('value')] = $node; } // look for functions if ($node instanceof Twig_Node_Expression_Function && !isset($this->functions[$node->getAttribute('name')])) { $this->functions[$node->getAttribute('name')] = $node; } // wrap print to check __toString() calls if ($node instanceof Twig_Node_Print) { return new Twig_Node_SandboxedPrint($node->getNode('expr'), $node->getLine(), $node->getNodeTag()); } } return $node; }
public function replace(Node $node, TemplateContext $context) { // we only overwrite assetic nodes if (!$node instanceof AsseticNode) { return null; } // we leave images as they are $tagName = $node->getNodeTag(); if (!in_array($tagName, array('stylesheets', 'javascripts'), true)) { return null; } // we only handle collection of file assets $asset = $node->getAttribute('asset'); if (!$asset instanceof AssetCollectionInterface) { throw new \RuntimeException('Unexpected asset type: ' . get_class($asset)); } // skip assetic nodes that has some (not-ignored) filters defined $additionalFilters = array_diff($node->getAttribute('filters'), $this->ignoredFilters); if (count($additionalFilters) > 0) { $context->addNotice(sprintf('Skipping %s in %s as filter is used (%s). Remove filter and re-run if you want to migrate this tag', $tagName, $context->getTemplateName(), implode(' ', $additionalFilters))); return null; } $count = $context->getAttribute(self::ATTRIBUTE_NODE_COUNT); $count = $count !== null ? $count : 0; $context->setAttribute(self::ATTRIBUTE_NODE_COUNT, $count + 1); $postfix = $count === 0 ? '' : '-' . $count; $templateName = $context->getTemplateName(); $assetPath = str_replace('/Resources/views/', '/' . $this->pathInBundle . '/', $templateName); $assetPath = preg_replace('/(\\.html)?\\.twig$/', '', $assetPath) . $postfix . '.js'; $variables = $asset->getVars(); if (count($variables) === 0) { $expression = $this->dumpAssets($node, $asset, $tagName, $assetPath); } else { $combinations = VarUtils::getCombinations($variables, $this->possibleVariables); $expression = null; foreach ($combinations as $combination) { $combinationAssetPath = substr($assetPath, 0, -2) . implode('.', $combination) . '.js'; if ($expression === null) { // first combination will be in "else" part (if no other combinations will match) $expression = $this->dumpAssets($node, $asset, $tagName, $combinationAssetPath, $combination); } else { // we recursively build condition like this: // matchesCombination ? webpack_asset(combinationPath) : [recursion] $expression = $this->buildCombinationCondition($combination) . "\n" . '? ' . $this->dumpAssets($node, $asset, $tagName, $combinationAssetPath, $combination) . "\n" . ': (' . "\n" . $this->indent($expression) . "\n" . ')'; } } } $body = $node->getNode('body'); // we find and replace "asset_url" to our expression return $this->replaceAssetUrl($body, $body, $expression); }