1<?php 2 3/* 4 * This file is part of Twig. 5 * 6 * (c) 2010 Fabien Potencier 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12/** 13 * Represents a trans node. 14 * 15 * @author Fabien Potencier <fabien.potencier@symfony-project.com> 16 */ 17class Twig_Extensions_Node_Trans extends Twig_Node 18{ 19 public function __construct(Twig_Node $body, Twig_Node $plural = null, Twig_Node_Expression $count = null, Twig_Node $notes = null, $lineno, $tag = null) 20 { 21 $nodes = array('body' => $body); 22 if (null !== $count) { 23 $nodes['count'] = $count; 24 } 25 if (null !== $plural) { 26 $nodes['plural'] = $plural; 27 } 28 if (null !== $notes) { 29 $nodes['notes'] = $notes; 30 } 31 32 parent::__construct($nodes, array(), $lineno, $tag); 33 } 34 35 /** 36 * {@inheritdoc} 37 */ 38 public function compile(Twig_Compiler $compiler) 39 { 40 $compiler->addDebugInfo($this); 41 42 list($msg, $vars) = $this->compileString($this->getNode('body')); 43 44 if ($this->hasNode('plural')) { 45 list($msg1, $vars1) = $this->compileString($this->getNode('plural')); 46 47 $vars = array_merge($vars, $vars1); 48 } 49 50 $function = $this->getTransFunction($this->hasNode('plural')); 51 52 if ($this->hasNode('notes')) { 53 $message = trim($this->getNode('notes')->getAttribute('data')); 54 55 // line breaks are not allowed cause we want a single line comment 56 $message = str_replace(array("\n", "\r"), ' ', $message); 57 $compiler->write("// notes: {$message}\n"); 58 } 59 60 if ($vars) { 61 $compiler 62 ->write('echo strtr('.$function.'(') 63 ->subcompile($msg) 64 ; 65 66 if ($this->hasNode('plural')) { 67 $compiler 68 ->raw(', ') 69 ->subcompile($msg1) 70 ->raw(', abs(') 71 ->subcompile($this->hasNode('count') ? $this->getNode('count') : null) 72 ->raw(')') 73 ; 74 } 75 76 $compiler->raw('), array('); 77 78 foreach ($vars as $var) { 79 if ('count' === $var->getAttribute('name')) { 80 $compiler 81 ->string('%count%') 82 ->raw(' => abs(') 83 ->subcompile($this->hasNode('count') ? $this->getNode('count') : null) 84 ->raw('), ') 85 ; 86 } else { 87 $compiler 88 ->string('%'.$var->getAttribute('name').'%') 89 ->raw(' => ') 90 ->subcompile($var) 91 ->raw(', ') 92 ; 93 } 94 } 95 96 $compiler->raw("));\n"); 97 } else { 98 $compiler 99 ->write('echo '.$function.'(') 100 ->subcompile($msg) 101 ; 102 103 if ($this->hasNode('plural')) { 104 $compiler 105 ->raw(', ') 106 ->subcompile($msg1) 107 ->raw(', abs(') 108 ->subcompile($this->hasNode('count') ? $this->getNode('count') : null) 109 ->raw(')') 110 ; 111 } 112 113 $compiler->raw(");\n"); 114 } 115 } 116 117 /** 118 * @param Twig_Node $body A Twig_Node instance 119 * 120 * @return array 121 */ 122 protected function compileString(Twig_Node $body) 123 { 124 if ($body instanceof Twig_Node_Expression_Name || $body instanceof Twig_Node_Expression_Constant || $body instanceof Twig_Node_Expression_TempName) { 125 return array($body, array()); 126 } 127 128 $vars = array(); 129 if (count($body)) { 130 $msg = ''; 131 132 foreach ($body as $node) { 133 if (get_class($node) === 'Twig_Node' && $node->getNode(0) instanceof Twig_Node_SetTemp) { 134 $node = $node->getNode(1); 135 } 136 137 if ($node instanceof Twig_Node_Print) { 138 $n = $node->getNode('expr'); 139 while ($n instanceof Twig_Node_Expression_Filter) { 140 $n = $n->getNode('node'); 141 } 142 $msg .= sprintf('%%%s%%', $n->getAttribute('name')); 143 $vars[] = new Twig_Node_Expression_Name($n->getAttribute('name'), $n->getTemplateLine()); 144 } else { 145 $msg .= $node->getAttribute('data'); 146 } 147 } 148 } else { 149 $msg = $body->getAttribute('data'); 150 } 151 152 return array(new Twig_Node(array(new Twig_Node_Expression_Constant(trim($msg), $body->getTemplateLine()))), $vars); 153 } 154 155 /** 156 * @param bool $plural Return plural or singular function to use 157 * 158 * @return string 159 */ 160 protected function getTransFunction($plural) 161 { 162 return $plural ? 'ngettext' : 'gettext'; 163 } 164} 165 166class_alias('Twig_Extensions_Node_Trans', 'Twig\Extensions\Node\TransNode', false); 167