00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 class Varien_Filter_Template implements Zend_Filter_Interface
00036 {
00037
00038
00039
00040 const CONSTRUCTION_PATTERN = '/{{([a-z]{0,10})(.*?)}}/si';
00041
00042
00043
00044
00045 const CONSTRUCTION_DEPEND_PATTERN = '/{{depend\s*(.*?)}}(.*?){{\\/depend\s*}}/si';
00046 const CONSTRUCTION_IF_PATTERN = '/{{if\s*(.*?)}}(.*?)({{else}}(.*?))?{{\\/if\s*}}/si';
00047
00048
00049
00050
00051
00052
00053 protected $_templateVars = array();
00054
00055
00056
00057
00058
00059
00060 protected $_includeProcessor = null;
00061
00062
00063
00064
00065
00066
00067 public function setVariables(array $variables)
00068 {
00069 foreach($variables as $name=>$value) {
00070 $this->_templateVars[$name] = $value;
00071 }
00072 return $this;
00073 }
00074
00075
00076
00077
00078
00079
00080 public function setIncludeProcessor(array $callback)
00081 {
00082 $this->_includeProcessor = $callback;
00083 return $this;
00084 }
00085
00086
00087
00088
00089
00090
00091 public function getIncludeProcessor()
00092 {
00093 return is_callable($this->_includeProcessor) ? $this->_includeProcessor : null;
00094 }
00095
00096
00097
00098
00099
00100
00101
00102 public function filter($value)
00103 {
00104
00105 foreach (array(
00106 self::CONSTRUCTION_DEPEND_PATTERN => 'dependDirective',
00107 self::CONSTRUCTION_IF_PATTERN => 'ifDirective',
00108 ) as $pattern => $directive) {
00109 if (preg_match_all($pattern, $value, $constructions, PREG_SET_ORDER)) {
00110 foreach($constructions as $index => $construction) {
00111 $replacedValue = '';
00112 $callback = array($this, $directive);
00113 if(!is_callable($callback)) {
00114 continue;
00115 }
00116 try {
00117 $replacedValue = call_user_func($callback, $construction);
00118 } catch (Exception $e) {
00119 throw $e;
00120 }
00121 $value = str_replace($construction[0], $replacedValue, $value);
00122 }
00123 }
00124 }
00125
00126 if(preg_match_all(self::CONSTRUCTION_PATTERN, $value, $constructions, PREG_SET_ORDER)) {
00127 foreach($constructions as $index=>$construction) {
00128 $replacedValue = '';
00129 $callback = array($this, $construction[1].'Directive');
00130 if(!is_callable($callback)) {
00131 continue;
00132 }
00133 try {
00134 $replacedValue = call_user_func($callback, $construction);
00135 } catch (Exception $e) {
00136 throw $e;
00137 }
00138 $value = str_replace($construction[0], $replacedValue, $value);
00139 }
00140 }
00141 return $value;
00142 }
00143
00144
00145 public function varDirective($construction)
00146 {
00147 if (count($this->_templateVars)==0) {
00148
00149 return $construction[0];
00150 }
00151
00152 $replacedValue = $this->_getVariable($construction[2], '');
00153 return $replacedValue;
00154 }
00155
00156 public function includeDirective($construction)
00157 {
00158
00159 $includeParameters = $this->_getIncludeParameters($construction[2]);
00160 if(!isset($includeParameters['template']) or !$this->getIncludeProcessor()) {
00161
00162 $replacedValue = '{' . __('Error in include processing') . '}';
00163 } else {
00164
00165 $templateCode = $includeParameters['template'];
00166 unset($includeParameters['template']);
00167 $includeParameters = array_merge_recursive($includeParameters, $this->_templateVars);
00168 $replacedValue = call_user_func($this->getIncludeProcessor(), $templateCode, $includeParameters);
00169 }
00170 return $replacedValue;
00171 }
00172
00173 public function dependDirective($construction)
00174 {
00175 if (count($this->_templateVars)==0) {
00176
00177 return $construction[0];
00178 }
00179
00180 if($this->_getVariable($construction[1], '')=='') {
00181 return '';
00182 } else {
00183 return $construction[2];
00184 }
00185 }
00186
00187 public function ifDirective($construction)
00188 {
00189 if (count($this->_templateVars) == 0) {
00190 return $construction[0];
00191 }
00192
00193 if($this->_getVariable($construction[1], '') == '') {
00194 if (isset($construction[3]) && isset($construction[4])) {
00195 return $construction[4];
00196 }
00197 return '';
00198 } else {
00199 return $construction[2];
00200 }
00201 }
00202
00203
00204
00205
00206
00207
00208
00209 protected function _getIncludeParameters($value)
00210 {
00211 $tokenizer = new Varien_Filter_Template_Tokenizer_Parameter();
00212 $tokenizer->setString($value);
00213 $params = $tokenizer->tokenize();
00214 foreach ($params as $key => $value) {
00215 if (substr($value, 0, 1) === '$') {
00216 $params[$key] = $this->_getVariable(substr($value, 1), null);
00217 }
00218 }
00219 return $params;
00220 }
00221
00222
00223
00224
00225
00226
00227
00228
00229 protected function _getVariable($value, $default='{no_value_defined}')
00230 {
00231 Varien_Profiler::start("email_template_proccessing_variables");
00232 $tokenizer = new Varien_Filter_Template_Tokenizer_Variable();
00233 $tokenizer->setString($value);
00234 $stackVars = $tokenizer->tokenize();
00235 $result = $default;
00236 $last = 0;
00237 for($i = 0; $i < count($stackVars); $i ++) {
00238 if ($i == 0 && isset($this->_templateVars[$stackVars[$i]['name']])) {
00239
00240 $stackVars[$i]['variable'] =& $this->_templateVars[$stackVars[$i]['name']];
00241 } else if (isset($stackVars[$i-1]['variable'])
00242 && $stackVars[$i-1]['variable'] instanceof Varien_Object) {
00243
00244 if($stackVars[$i]['type'] == 'property') {
00245 $caller = "get" . uc_words($stackVars[$i]['name'], '');
00246 if(is_callable(array($stackVars[$i-1]['variable'], $caller))) {
00247
00248 $stackVars[$i]['variable'] = $stackVars[$i-1]['variable']->$caller();
00249 } else {
00250 $stackVars[$i]['variable'] = $stackVars[$i-1]['variable']
00251 ->getData($stackVars[$i]['name']);
00252 }
00253 } else if ($stackVars[$i]['type'] == 'method') {
00254
00255 if (is_callable(array($stackVars[$i-1]['variable'], $stackVars[$i]['name'])) || substr($stackVars[$i]['name'],0,3) == 'get') {
00256 $stackVars[$i]['variable'] = call_user_func_array(array($stackVars[$i-1]['variable'],
00257 $stackVars[$i]['name']),
00258 $stackVars[$i]['args']);
00259 }
00260 }
00261 $last = $i;
00262 }
00263 }
00264
00265 if(isset($stackVars[$last]['variable'])) {
00266
00267 $result = $stackVars[$last]['variable'];
00268 }
00269 Varien_Profiler::stop("email_template_proccessing_variables");
00270 return $result;
00271 }
00272 }