| [ Index ] |
|
Code source de Symfony 1.0.0 |
1 <?php 2 3 /* 4 * $Id: SmartyTask.php 3076 2006-12-18 08:52:12Z fabien $ 5 * 6 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 7 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 8 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 9 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 10 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 11 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 12 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 13 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 14 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 15 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 16 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 17 * 18 * This software consists of voluntary contributions made by many individuals 19 * and is licensed under the LGPL. For more information please see 20 * <http://phing.info>. 21 */ 22 23 require_once 'phing/Task.php'; 24 include_once 'phing/BuildException.php'; 25 include_once 'phing/util/StringHelper.php'; 26 27 /** 28 * A phing task for generating output by using Smarty. 29 * 30 * This is based on the TexenTask from Apache's Velocity engine. This class 31 * was originally proted in order to provide a template compiling system for 32 * Torque. 33 * 34 * TODO: 35 * - Add Path / useClasspath support? 36 * 37 * @author Hans Lellelid <hans@xmpl.org> (SmartyTask) 38 * @author Jason van Zyl <jvanzyl@apache.org> (TexenTask) 39 * @author Robert Burrell Donkin <robertdonkin@mac.com> 40 * @version $Id: SmartyTask.php 3076 2006-12-18 08:52:12Z fabien $ 41 * @package phing.tasks.ext 42 */ 43 class SmartyTask extends Task { 44 45 /** 46 * Smarty template engine. 47 * @var Smarty 48 */ 49 protected $context; 50 51 /** 52 * Variables that are assigned to the context on parse/compile. 53 * @var array 54 */ 55 protected $properties = array(); 56 57 /** 58 * This is the control template that governs the output. 59 * It may or may not invoke the services of worker 60 * templates. 61 * @var string 62 */ 63 protected $controlTemplate; 64 65 /** 66 * This is where Velocity will look for templates 67 * using the file template loader. 68 * @var string 69 */ 70 protected $templatePath; 71 72 /** 73 * This is where texen will place all the output 74 * that is a product of the generation process. 75 * @var string 76 */ 77 protected $outputDirectory; 78 79 /** 80 * This is the file where the generated text 81 * will be placed. 82 * @var string 83 */ 84 protected $outputFile; 85 86 /** 87 * <p> 88 * These are properties that are fed into the 89 * initial context from a properties file. This 90 * is simply a convenient way to set some values 91 * that you wish to make available in the context. 92 * </p> 93 * <p> 94 * These values are not critical, like the template path 95 * or output path, but allow a convenient way to 96 * set a value that may be specific to a particular 97 * generation task. 98 * </p> 99 * <p> 100 * For example, if you are generating scripts to allow 101 * user to automatically create a database, then 102 * you might want the <code>$databaseName</code> 103 * to be placed 104 * in the initial context so that it is available 105 * in a script that might look something like the 106 * following: 107 * <code><pre> 108 * #!bin/sh 109 * 110 * echo y | mysqladmin create $databaseName 111 * </pre></code> 112 * The value of <code>$databaseName</code> isn't critical to 113 * output, and you obviously don't want to change 114 * the ant task to simply take a database name. 115 * So initial context values can be set with 116 * properties file. 117 * 118 * @var array 119 */ 120 protected $contextProperties; 121 122 /** 123 * Smarty compiles templates before parsing / replacing tokens in them. 124 * By default it will try ./templates_c, but you may wish to override this. 125 * @var string 126 */ 127 protected $compilePath; 128 129 /** 130 * Whether to force Smarty to recompile templates. 131 * Smarty does check file modification time, but you can set this 132 * to be *sure* that the template will be compiled (of course it will 133 * be slower if you do). 134 * @var boolean 135 */ 136 protected $forceCompile = false; 137 138 /** 139 * Smarty can use config files. 140 * This tells Smarty where to look for the config files. 141 * @var string 142 */ 143 protected $configPath; 144 145 /** 146 * Customize the left delimiter for Smarty tags. 147 * @var string 148 */ 149 protected $leftDelimiter; 150 151 /** 152 * Customize the right delimiter for Smarty tags. 153 * @var string 154 */ 155 protected $rightDelimiter; 156 157 // ----------------------------------------------------------------------- 158 // The following getters & setters are used by phing to set properties 159 // specified in the XML for the smarty task. 160 // ----------------------------------------------------------------------- 161 162 public function init() { 163 include_once 'Smarty.class.php'; 164 if (!class_exists('Smarty')) { 165 throw new BuildException("To use SmartyTask, you must have the path to Smarty.class.php on your include_path or your \$PHP_CLASSPATH environment variable."); 166 } 167 } 168 169 /** 170 * [REQUIRED] Set the control template for the 171 * generating process. 172 * @param string $controlTemplate 173 * @return void 174 */ 175 public function setControlTemplate ($controlTemplate) { 176 $this->controlTemplate = $controlTemplate; 177 } 178 179 /** 180 * Get the control template for the 181 * generating process. 182 * @return string 183 */ 184 public function getControlTemplate() { 185 return $this->controlTemplate; 186 } 187 188 /** 189 * [REQUIRED] Set the path where Velocity will look 190 * for templates using the file template 191 * loader. 192 * @return void 193 * @throws Exception 194 */ 195 public function setTemplatePath($templatePath) { 196 $resolvedPath = ""; 197 $tok = strtok($templatePath, ","); 198 while ( $tok ) { 199 // resolve relative path from basedir and leave 200 // absolute path untouched. 201 $fullPath = $this->project->resolveFile($tok); 202 $cpath = $fullPath->getCanonicalPath(); 203 if ($cpath === false) { 204 $this->log("Template directory does not exist: " . $fullPath->getAbsolutePath()); 205 } else { 206 $resolvedPath .= $cpath; 207 } 208 $tok = strtok(","); 209 if ( $tok ) { 210 $resolvedPath .= ","; 211 } 212 } 213 $this->templatePath = $resolvedPath; 214 } 215 216 /** 217 * Get the path where Velocity will look 218 * for templates using the file template 219 * loader. 220 * @return string 221 */ 222 public function getTemplatePath() { 223 return $this->templatePath; 224 } 225 226 /** 227 * [REQUIRED] Set the output directory. It will be 228 * created if it doesn't exist. 229 * @param PhingFile $outputDirectory 230 * @return void 231 * @throws Exception 232 */ 233 public function setOutputDirectory(PhingFile $outputDirectory) { 234 try { 235 if (!$outputDirectory->exists()) { 236 $this->log("Output directory does not exist, creating: " . $outputDirectory->getPath(),PROJECT_MSG_VERBOSE); 237 if (!$outputDirectory->mkdirs()) { 238 throw new IOException("Unable to create Ouptut directory: " . $outputDirectory->getAbsolutePath()); 239 } 240 } 241 $this->outputDirectory = $outputDirectory->getCanonicalPath(); 242 } catch (IOException $ioe) { 243 throw new BuildException($ioe->getMessage()); 244 } 245 } 246 247 /** 248 * Get the output directory. 249 * @return string 250 */ 251 public function getOutputDirectory() { 252 return $this->outputDirectory; 253 } 254 255 /** 256 * [REQUIRED] Set the output file for the 257 * generation process. 258 * @return void 259 */ 260 public function setOutputFile($outputFile) { 261 $this->outputFile = $outputFile; 262 } 263 264 /** 265 * Get the output file for the 266 * generation process. 267 * @return string 268 */ 269 public function getOutputFile() { 270 return $this->outputFile; 271 } 272 273 /** 274 * Set the path Smarty uses as a "cache" for compiled templates. 275 * @param string $compilePath 276 */ 277 public function setCompilePath($compilePath) { 278 $this->compilePath = $compilePath; 279 } 280 281 /** 282 * Get the path Smarty uses for compiling templates. 283 * @return string 284 */ 285 public function getCompilePath() { 286 return $this->compilePath; 287 } 288 289 /** 290 * Set whether Smarty should always recompile tempaltes. 291 * @param boolean $force 292 * @return void 293 */ 294 public function setForceCompile($force) { 295 $this->forceCompile = (boolean) $force; 296 } 297 298 /** 299 * Get whether Smarty should always recompile template. 300 * @return boolean 301 */ 302 public function getForceCompile() { 303 return $this->forceCompile; 304 } 305 306 /** 307 * Set where Smarty looks for config files. 308 * @param string $configPath 309 * @return void 310 */ 311 public function setConfigPath($configPath) { 312 $this->configPath = $configPath; 313 } 314 315 /** 316 * Get the path that Smarty uses for looking for config files. 317 * @return string 318 */ 319 public function getConfigPath() { 320 return $this->configPath; 321 } 322 323 /** 324 * Set Smarty template left delimiter. 325 * @param string $delim 326 * @return void 327 */ 328 public function setLeftDelimiter($delim) { 329 $this->leftDelimiter = $delim; 330 } 331 332 /** 333 * Get Smarty template right delimiter 334 * @return string 335 */ 336 public function getLeftDelimiter() { 337 return $this->leftDelimiter; 338 } 339 340 /** 341 * Set Smarty template right delimiter. 342 * @param string $delim 343 * @return void 344 */ 345 public function setRightDelimiter($delim) { 346 $this->rightDelimiter = $delim; 347 } 348 349 /** 350 * Get Smarty template right delimiter 351 * @return string 352 */ 353 public function getRightDelimiter() { 354 return $this->rightDelimiter; 355 } 356 357 358 /** 359 * Set the context properties that will be 360 * fed into the initial context be the 361 * generating process starts. 362 * @param string $file 363 * @return void 364 */ 365 public function setContextProperties($file) { 366 367 $sources = explode(",", $file); 368 $this->contextProperties = new Properties(); 369 370 // Always try to get the context properties resource 371 // from a file first. Templates may be taken from a JAR 372 // file but the context properties resource may be a 373 // resource in the filesystem. If this fails than attempt 374 // to get the context properties resource from the 375 // classpath. 376 for ($i=0, $sourcesLength=count($sources); $i < $sourcesLength; $i++) { 377 $source = new Properties(); 378 379 try { 380 381 // resolve relative path from basedir and leave 382 // absolute path untouched. 383 $fullPath = $this->project->resolveFile($sources[$i]); 384 $this->log("Using contextProperties file: " . $fullPath->__toString()); 385 $source->load($fullPath); 386 387 } catch (Exception $e) { 388 389 throw new BuildException("Context properties file " . $sources[$i] . 390 " could not be found in the file system!"); 391 392 } 393 394 $keys = $source->keys(); 395 396 foreach ($keys as $key) { 397 $name = $key; 398 $value = $this->project->replaceProperties($source->getProperty($name)); 399 $this->contextProperties->setProperty($name, $value); 400 } 401 } 402 } 403 404 /** 405 * Get the context properties that will be 406 * fed into the initial context be the 407 * generating process starts. 408 * @return Properties 409 */ 410 public function getContextProperties() { 411 return $this->contextProperties; 412 } 413 414 // --------------------------------------------------------------- 415 // End of XML setters & getters 416 // --------------------------------------------------------------- 417 418 419 /** 420 * Creates a Smarty object. 421 * 422 * @return Smarty initialized (cleared) Smarty context. 423 * @throws Exception the execute method will catch 424 * and rethrow as a <code>BuildException</code> 425 */ 426 public function initControlContext() { 427 $this->context->clear_all_assign(); 428 return $this->context; 429 } 430 431 /** 432 * Execute the input script with Velocity 433 * 434 * @throws BuildException 435 * BuildExceptions are thrown when required attributes are missing. 436 * Exceptions thrown by Velocity are rethrown as BuildExceptions. 437 */ 438 public function main() { 439 440 // Make sure the template path is set. 441 if (empty($this->templatePath)) { 442 throw new BuildException("The template path needs to be defined!"); 443 } 444 445 // Make sure the control template is set. 446 if ($this->controlTemplate === null) { 447 throw new BuildException("The control template needs to be defined!"); 448 } 449 450 // Make sure the output directory is set. 451 if ($this->outputDirectory === null) { 452 throw new BuildException("The output directory needs to be defined!"); 453 } 454 455 // Make sure there is an output file. 456 if ($this->outputFile === null) { 457 throw new BuildException("The output file needs to be defined!"); 458 } 459 460 // Setup Smarty runtime. 461 462 // Smarty uses one object to store properties and to store 463 // the context for the template (unlike Velocity). We setup this object, calling it 464 // $this->context, and then initControlContext simply zeros out 465 // any assigned variables. 466 $this->context = new Smarty(); 467 468 if ($this->compilePath !== null) { 469 $this->log("Using compilePath: " . $this->compilePath); 470 $this->context->compile_dir = $this->compilePath; 471 } 472 473 if ($this->configPath !== null) { 474 $this->log("Using configPath: " . $this->configPath); 475 $this->context->config_dir = $this->configPath; 476 } 477 478 if ($this->forceCompile !== null) { 479 $this->context->force_compile = $this->forceCompile; 480 } 481 482 if ($this->leftDelimiter !== null) { 483 $this->context->left_delimiter = $this->leftDelimiter; 484 } 485 486 if ($this->rightDelimiter !== null) { 487 $this->context->right_delimiter = $this->rightDelimiter; 488 } 489 490 if ($this->templatePath !== null) { 491 $this->log("Using templatePath: " . $this->templatePath); 492 $this->context->template_dir = $this->templatePath; 493 } 494 495 $smartyCompilePath = new PhingFile($this->context->compile_dir); 496 if (!$smartyCompilePath->exists()) { 497 $this->log("Compile directory does not exist, creating: " . $smartyCompilePath->getPath(), PROJECT_MSG_VERBOSE); 498 if (!$smartyCompilePath->mkdirs()) { 499 throw new BuildException("Smarty needs a place to compile templates; specify a 'compilePath' or create ".$this->context->compile_dir); 500 } 501 } 502 503 // Make sure the output directory exists, if it doesn't 504 // then create it. 505 $file = new PhingFile($this->outputDirectory); 506 if (!$file->exists()) { 507 $this->log("Output directory does not exist, creating: " . $file->getAbsolutePath()); 508 $file->mkdirs(); 509 } 510 511 $path = $this->outputDirectory . DIRECTORY_SEPARATOR . $this->outputFile; 512 $this->log("Generating to file " . $path); 513 514 $writer = new FileWriter($path); 515 516 // The generator and the output path should 517 // be placed in the init context here and 518 // not in the generator class itself. 519 $c = $this->initControlContext(); 520 521 // Set any variables that need to always 522 // be loaded 523 $this->populateInitialContext($c); 524 525 // Feed all the options into the initial 526 // control context so they are available 527 // in the control/worker templates. 528 if ($this->contextProperties !== null) { 529 530 foreach($this->contextProperties->keys() as $property) { 531 532 $value = $this->contextProperties->getProperty($property); 533 534 // Special exception (from Texen) 535 // for properties ending in file.contents: 536 // in that case we dump the contents of the file 537 // as the "value" for the Property. 538 if (StringHelper::endsWith("file.contents", $property)) { 539 // pull in contents of file specified 540 541 $property = substr($property, 0, strpos($property, "file.contents") - 1); 542 543 // reset value, and then 544 // read in teh contents of the file into that var 545 $value = ""; 546 $f = new PhingFile($project->resolveFile($value)->getCanonicalPath()); 547 if ($f->exists()) { 548 try { 549 $fr = new FileReader($f); 550 $fr->readInto($value); 551 } catch (Exception $e) { 552 throw $e; 553 } 554 } 555 556 } // if ends with file.contents 557 558 if (StringHelper::isBoolean($value)) { 559 $value = StringHelper::booleanValue($value); 560 } 561 562 $c->assign($property, $value); 563 564 } // foreach property 565 566 } // if contextProperties !== null 567 568 try { 569 //$c->display($this->controlTemplate); 570 $writer->write($c->fetch($this->controlTemplate)); 571 $writer->close(); 572 } catch (IOException $ioe) { 573 $writer->close(); 574 throw new BuildException("Cannot write parsed template."); 575 } 576 577 $this->cleanup(); 578 } 579 580 /** 581 * <p>Place useful objects into the initial context.</p> 582 * 583 * <p>TexenTask places <code>Date().toString()</code> into the 584 * context as <code>$now</code>. Subclasses who want to vary the 585 * objects in the context should override this method.</p> 586 * 587 * <p><code>$generator</code> is not put into the context in this 588 * method.</p> 589 * 590 * @param context The context to populate, as retrieved from 591 * {@link #initControlContext()}. 592 * @return void 593 * @throws Exception Error while populating context. The {@link 594 * #execute()} method will catch and rethrow as a 595 * <code>BuildException</code>. 596 */ 597 protected function populateInitialContext(Smarty $context) { 598 } 599 600 /** 601 * A hook method called at the end of {@link #execute()} which can 602 * be overridden to perform any necessary cleanup activities (such 603 * as the release of database connections, etc.). By default, 604 * does nothing. 605 * @return void 606 * @throws Exception Problem cleaning up. 607 */ 608 protected function cleanup() { 609 } 610 }
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Fri Mar 16 22:42:14 2007 | par Balluche grâce à PHPXref 0.7 |