factory = $factory; $this->tag = $tag; $this->output = $output; $this->single = $single; $this->extensions = $extensions; } public function parse(\Twig_Token $token) { $inputs = array(); $filters = array(); $name = null; $attributes = array( 'output' => $this->output, 'var_name' => 'asset_url', 'vars' => array(), ); $stream = $this->parser->getStream(); while (!$stream->test(\Twig_Token::BLOCK_END_TYPE)) { if ($stream->test(\Twig_Token::STRING_TYPE)) { // '@jquery', 'js/src/core/*', 'js/src/extra.js' $inputs[] = $stream->next()->getValue(); } elseif ($stream->test(\Twig_Token::NAME_TYPE, 'filter')) { // filter='yui_js' $stream->next(); $stream->expect(\Twig_Token::OPERATOR_TYPE, '='); $filters = array_merge($filters, array_filter(array_map('trim', explode(',', $stream->expect(\Twig_Token::STRING_TYPE)->getValue())))); } elseif ($stream->test(\Twig_Token::NAME_TYPE, 'output')) { // output='js/packed/*.js' OR output='js/core.js' $stream->next(); $stream->expect(\Twig_Token::OPERATOR_TYPE, '='); $attributes['output'] = $stream->expect(\Twig_Token::STRING_TYPE)->getValue(); } elseif ($stream->test(\Twig_Token::NAME_TYPE, 'name')) { // name='core_js' $stream->next(); $stream->expect(\Twig_Token::OPERATOR_TYPE, '='); $name = $stream->expect(\Twig_Token::STRING_TYPE)->getValue(); } elseif ($stream->test(\Twig_Token::NAME_TYPE, 'as')) { // as='the_url' $stream->next(); $stream->expect(\Twig_Token::OPERATOR_TYPE, '='); $attributes['var_name'] = $stream->expect(\Twig_Token::STRING_TYPE)->getValue(); } elseif ($stream->test(\Twig_Token::NAME_TYPE, 'debug')) { // debug=true $stream->next(); $stream->expect(\Twig_Token::OPERATOR_TYPE, '='); $attributes['debug'] = 'true' == $stream->expect(\Twig_Token::NAME_TYPE, array('true', 'false'))->getValue(); } elseif ($stream->test(\Twig_Token::NAME_TYPE, 'combine')) { // combine=true $stream->next(); $stream->expect(\Twig_Token::OPERATOR_TYPE, '='); $attributes['combine'] = 'true' == $stream->expect(\Twig_Token::NAME_TYPE, array('true', 'false'))->getValue(); } elseif ($stream->test(\Twig_Token::NAME_TYPE, 'vars')) { // vars=['locale','browser'] $stream->next(); $stream->expect(\Twig_Token::OPERATOR_TYPE, '='); $stream->expect(\Twig_Token::PUNCTUATION_TYPE, '['); while ($stream->test(\Twig_Token::STRING_TYPE)) { $attributes['vars'][] = $stream->expect(\Twig_Token::STRING_TYPE)->getValue(); if (!$stream->test(\Twig_Token::PUNCTUATION_TYPE, ',')) { break; } $stream->next(); } $stream->expect(\Twig_Token::PUNCTUATION_TYPE, ']'); } elseif ($stream->test(\Twig_Token::NAME_TYPE, $this->extensions)) { // an arbitrary configured attribute $key = $stream->next()->getValue(); $stream->expect(\Twig_Token::OPERATOR_TYPE, '='); $attributes[$key] = $stream->expect(\Twig_Token::STRING_TYPE)->getValue(); } else { $token = $stream->getCurrent(); throw new \Twig_Error_Syntax(sprintf('Unexpected token "%s" of value "%s"', \Twig_Token::typeToEnglish($token->getType()), $token->getValue()), $token->getLine(), $stream->getFilename()); } } $stream->expect(\Twig_Token::BLOCK_END_TYPE); $body = $this->parser->subparse(array($this, 'testEndTag'), true); $stream->expect(\Twig_Token::BLOCK_END_TYPE); if ($this->single && 1 < count($inputs)) { $inputs = array_slice($inputs, -1); } if (!$name) { $name = $this->factory->generateAssetName($inputs, $filters, $attributes); } $asset = $this->factory->createAsset($inputs, $filters, $attributes + array('name' => $name)); return $this->createBodyNode($asset, $body, $inputs, $filters, $name, $attributes, $token->getLine(), $this->getTag()); } public function getTag() { return $this->tag; } public function testEndTag(\Twig_Token $token) { return $token->test(array('end'.$this->getTag())); } /** * @param AssetInterface $asset * @param \Twig_Node $body * @param array $inputs * @param array $filters * @param string $name * @param array $attributes * @param int $lineno * @param string $tag * * @return \Twig_Node */ protected function createBodyNode(AssetInterface $asset, \Twig_Node $body, array $inputs, array $filters, $name, array $attributes = array(), $lineno = 0, $tag = null) { $reflector = new \ReflectionMethod($this, 'createNode'); if (__CLASS__ !== $reflector->getDeclaringClass()->name) { @trigger_error(sprintf('Overwriting %s::createNode is deprecated since 1.3. Overwrite %s instead.', __CLASS__, __METHOD__), E_USER_DEPRECATED); return $this->createNode($asset, $body, $inputs, $filters, $name, $attributes, $lineno, $tag); } return new AsseticNode($asset, $body, $inputs, $filters, $name, $attributes, $lineno, $tag); } /** * @param AssetInterface $asset * @param \Twig_NodeInterface $body * @param array $inputs * @param array $filters * @param string $name * @param array $attributes * @param int $lineno * @param string $tag * * @return \Twig_Node * * @deprecated since 1.3.0, to be removed in 2.0. Use createBodyNode instead. */ protected function createNode(AssetInterface $asset, \Twig_NodeInterface $body, array $inputs, array $filters, $name, array $attributes = array(), $lineno = 0, $tag = null) { @trigger_error(sprintf('The %s method is deprecated since 1.3 and will be removed in 2.0. Use createBodyNode instead.', __METHOD__), E_USER_DEPRECATED); if (!$body instanceof \Twig_Node) { throw new \InvalidArgumentException('The body must be a Twig_Node. Custom implementations of Twig_NodeInterface are not supported.'); } return new AsseticNode($asset, $body, $inputs, $filters, $name, $attributes, $lineno, $tag); } }