Selaa lähdekoodia

Initial work adding pragma detection to Mustache.php

Currently stores pragmas and options, but does nothing with them. Also throws exceptions when it encounters unknown pragmas.
Test coverage only for exceptions and pragma tag removal.
Justin Hileman 15 vuotta sitten
vanhempi
sitoutus
537ebc44c8
2 muutettua tiedostoa jossa 104 lisäystä ja 2 poistoa
  1. 64 2
      Mustache.php
  2. 40 0
      test/MustachePragmaTest.php

+ 64 - 2
Mustache.php

@@ -30,6 +30,9 @@ class Mustache {
 	protected $template = '';
 	protected $context  = array();
 	protected $partials = array();
+	protected $pragmas  = array();
+
+	protected $pragmasImplemented = array('DOT-NOTATION');
 
 	/**
 	 * Mustache class constructor.
@@ -101,6 +104,7 @@ class Mustache {
 	 * @return string Rendered Mustache template.
 	 */
 	protected function _render($template, &$context) {
+		$template = $this->renderPragmas($template, $context);
 		$template = $this->renderSection($template, $context);
 		return $this->renderTags($template, $context);
 	}
@@ -162,6 +166,60 @@ class Mustache {
 		return $template;
 	}
 
+	/**
+	 * Initialize pragmas and remove all pragma tags.
+	 * 
+	 * @access protected
+	 * @param string $template
+	 * @param array &$context
+	 * @return string
+	 */
+	protected function renderPragmas($template, &$context) {
+		// no pragmas
+		if (strpos($template, $this->otag . '%') === false) {
+			return $template;
+		}
+
+		$otag = $this->prepareRegEx($this->otag);
+		$ctag = $this->prepareRegEx($this->ctag);
+		$regex = '/' . $otag . '%([\\w_-]+)((?: [\\w]+=[\\w]+)*)' . $ctag . '\\n?/';
+		return preg_replace_callback($regex, array($this, 'renderPragma'), $template);
+	}
+
+	/**
+	 * A preg_replace helper to remove {{%PRAGMA}} tags and enable requested pragma.
+	 *
+	 * @access protected
+	 * @param mixed $matches
+	 * @return void
+	 * @throws MustacheException unknown pragma
+	 */
+	protected function renderPragma($matches) {
+		$pragma         = $matches[0];
+		$pragma_name    = $matches[1];
+		$options_string = $matches[2];
+
+		if (!in_array($pragma_name, $this->pragmasImplemented)) {
+			throw new MustacheException('Unknown pragma: ' . $pragma_name, MustacheException::UNKNOWN_PRAGMA);
+		}
+
+		$options = array();
+		foreach (explode(' ', trim($options_string)) as $o) {
+			if ($p = trim($o)) {
+				$p = explode('=', trim($p));
+				$options[$p[0]] = $p[1];
+			}
+		}
+
+		if (empty($options)) {
+			$this->pragmas[$pragma_name] = true;
+		} else {
+			$this->pragmas[$pragma_name] = $options;
+		}
+
+		return '';
+	}
+
 	/**
 	 * Loop through and render individual Mustache tags.
 	 *
@@ -175,8 +233,8 @@ class Mustache {
 			return $template;
 		}
 
-		$otag  = $this->prepareRegEx($this->otag);
-		$ctag  = $this->prepareRegEx($this->ctag);
+		$otag = $this->prepareRegEx($this->otag);
+		$ctag = $this->prepareRegEx($this->ctag);
 		$this->tagRegEx = '/' . $otag . "(#|\/|=|!|>|\\{|&)?([^\/#]+?)\\1?" . $ctag . "+/";
 		$html = '';
 		$matches = array();
@@ -442,4 +500,8 @@ class MustacheException extends Exception {
 	// with no associated partial.
 	const UNKNOWN_PARTIAL          = 3;
 
+	// An UNKNOWN_PRAGMA exception is thrown whenever a {{%PRAGMA}} tag appears
+	// which can't be handled by this Mustache instance.
+	const UNKNOWN_PRAGMA           = 4;
+
 }

+ 40 - 0
test/MustachePragmaTest.php

@@ -0,0 +1,40 @@
+<?php
+
+require_once '../Mustache.php';
+require_once 'PHPUnit/Framework.php';
+
+class MustachePragmaTest extends PHPUnit_Framework_TestCase {
+
+	public function testUnknownPragmaException() {
+		$m = new Mustache();
+		$caught_exception = null;
+
+		try {
+			$m->render('{{%I-HAVE-THE-GREATEST-MUSTACHE}}');
+		} catch (Exception $e) {
+			$caught_exception = $e;
+		}
+
+		$this->assertNotNull($caught_exception, 'No exception caught');
+		$this->assertType('MustacheException', $caught_exception);
+		$this->assertEquals($caught_exception->getCode(), MustacheException::UNKNOWN_PRAGMA, 'Caught exception code was not MustacheException::UNKNOWN_PRAGMA');
+	}
+
+	public function testPragmaReplace() {
+		$m = new Mustache();
+		$this->assertEquals($m->render('{{%DOT-NOTATION}}'), '', 'Pragma tag not removed');
+	}
+
+	public function testPragmaReplaceMultiple() {
+		$m = new Mustache();
+		$this->assertEquals($m->render("{{%DOT-NOTATION}}\n{{%DOT-NOTATION}}"), '', 'Multiple pragma tags not removed');
+		$this->assertEquals($m->render('{{%DOT-NOTATION}} {{%DOT-NOTATION}}'), ' ', 'Multiple pragma tags not removed');
+	}
+
+	public function testPragmaReplaceNewline() {
+		$m = new Mustache();
+		$this->assertEquals($m->render("{{%DOT-NOTATION}}\n"), '', 'Trailing newline after pragma tag not removed');
+		$this->assertEquals($m->render("\n{{%DOT-NOTATION}}\n"), "\n", 'Too many newlines removed with pragma tag');
+		$this->assertEquals($m->render("1\n2{{%DOT-NOTATION}}\n3"), "1\n23", 'Wrong newline removed with pragma tag');
+	}
+}