Timber - Version 0.15.3

Version Description

  • Upgreaded to Twig 1.14.2
  • Added composer integration
  • Bunch of new tests
  • Comments now support gravatrs (thanks @asecondwill)
  • Moved ACF integration into its own file. It now interacts via hooks instead of in-line
  • A few misc. bugs and extra sanity checks
Download this release

Release Info

Developer jarednova
Plugin Icon 128x128 Timber
Version 0.15.3
Comparing to
See all releases

Code changes from version 0.15.2 to 0.15.3

Files changed (187) hide show
  1. Twig/AUTHORS +4 -0
  2. Twig/CHANGELOG +34 -0
  3. Twig/LICENSE +0 -0
  4. Twig/README.markdown +0 -2
  5. Twig/lib/Twig/Autoloader.php +0 -0
  6. Twig/lib/Twig/Compiler.php +5 -2
  7. Twig/lib/Twig/CompilerInterface.php +0 -0
  8. Twig/lib/Twig/Environment.php +57 -19
  9. Twig/lib/Twig/Error.php +10 -1
  10. Twig/lib/Twig/Error/Loader.php +0 -0
  11. Twig/lib/Twig/Error/Runtime.php +0 -0
  12. Twig/lib/Twig/Error/Syntax.php +0 -0
  13. Twig/lib/Twig/ExistsLoaderInterface.php +0 -0
  14. Twig/lib/Twig/ExpressionParser.php +11 -3
  15. Twig/lib/Twig/Extension.php +0 -0
  16. Twig/lib/Twig/Extension/Core.php +131 -66
  17. Twig/lib/Twig/Extension/Debug.php +0 -0
  18. Twig/lib/Twig/Extension/Escaper.php +0 -0
  19. Twig/lib/Twig/Extension/Optimizer.php +0 -0
  20. Twig/lib/Twig/Extension/Sandbox.php +0 -0
  21. Twig/lib/Twig/Extension/Staging.php +0 -0
  22. Twig/lib/Twig/Extension/StringLoader.php +6 -6
  23. Twig/lib/Twig/ExtensionInterface.php +0 -0
  24. Twig/lib/Twig/Filter.php +0 -0
  25. Twig/lib/Twig/Filter/Function.php +0 -0
  26. Twig/lib/Twig/Filter/Method.php +0 -0
  27. Twig/lib/Twig/Filter/Node.php +0 -0
  28. Twig/lib/Twig/FilterCallableInterface.php +0 -0
  29. Twig/lib/Twig/FilterInterface.php +0 -0
  30. Twig/lib/Twig/Function.php +0 -0
  31. Twig/lib/Twig/Function/Function.php +0 -0
  32. Twig/lib/Twig/Function/Method.php +0 -0
  33. Twig/lib/Twig/Function/Node.php +0 -0
  34. Twig/lib/Twig/FunctionCallableInterface.php +0 -0
  35. Twig/lib/Twig/FunctionInterface.php +0 -0
  36. Twig/lib/Twig/Lexer.php +9 -9
  37. Twig/lib/Twig/LexerInterface.php +2 -0
  38. Twig/lib/Twig/Loader/Array.php +2 -5
  39. Twig/lib/Twig/Loader/Chain.php +1 -2
  40. Twig/lib/Twig/Loader/Filesystem.php +15 -12
  41. Twig/lib/Twig/Loader/String.php +0 -0
  42. Twig/lib/Twig/LoaderInterface.php +0 -0
  43. Twig/lib/Twig/Markup.php +0 -0
  44. Twig/lib/Twig/Node.php +0 -0
  45. Twig/lib/Twig/Node/AutoEscape.php +0 -0
  46. Twig/lib/Twig/Node/Block.php +0 -0
  47. Twig/lib/Twig/Node/BlockReference.php +0 -0
  48. Twig/lib/Twig/Node/Body.php +0 -0
  49. Twig/lib/Twig/Node/Do.php +0 -0
  50. Twig/lib/Twig/Node/Embed.php +0 -0
  51. Twig/lib/Twig/Node/Expression.php +0 -0
  52. Twig/lib/Twig/Node/Expression/Array.php +0 -0
  53. Twig/lib/Twig/Node/Expression/AssignName.php +0 -0
  54. Twig/lib/Twig/Node/Expression/Binary.php +0 -0
  55. Twig/lib/Twig/Node/Expression/Binary/Add.php +0 -0
  56. Twig/lib/Twig/Node/Expression/Binary/And.php +0 -0
  57. Twig/lib/Twig/Node/Expression/Binary/BitwiseAnd.php +0 -0
  58. Twig/lib/Twig/Node/Expression/Binary/BitwiseOr.php +0 -0
  59. Twig/lib/Twig/Node/Expression/Binary/BitwiseXor.php +0 -0
  60. Twig/lib/Twig/Node/Expression/Binary/Concat.php +0 -0
  61. Twig/lib/Twig/Node/Expression/Binary/Div.php +0 -0
  62. Twig/lib/Twig/Node/Expression/Binary/EndsWith.php +30 -0
  63. Twig/lib/Twig/Node/Expression/Binary/Equal.php +0 -0
  64. Twig/lib/Twig/Node/Expression/Binary/FloorDiv.php +0 -0
  65. Twig/lib/Twig/Node/Expression/Binary/Greater.php +0 -0
  66. Twig/lib/Twig/Node/Expression/Binary/GreaterEqual.php +0 -0
  67. Twig/lib/Twig/Node/Expression/Binary/In.php +0 -0
  68. Twig/lib/Twig/Node/Expression/Binary/Less.php +0 -0
  69. Twig/lib/Twig/Node/Expression/Binary/LessEqual.php +0 -0
  70. Twig/lib/Twig/Node/Expression/Binary/Matches.php +28 -0
  71. Twig/lib/Twig/Node/Expression/Binary/Mod.php +0 -0
  72. Twig/lib/Twig/Node/Expression/Binary/Mul.php +0 -0
  73. Twig/lib/Twig/Node/Expression/Binary/NotEqual.php +0 -0
  74. Twig/lib/Twig/Node/Expression/Binary/NotIn.php +0 -0
  75. Twig/lib/Twig/Node/Expression/Binary/Or.php +0 -0
  76. Twig/lib/Twig/Node/Expression/Binary/Power.php +0 -0
  77. Twig/lib/Twig/Node/Expression/Binary/Range.php +0 -0
  78. Twig/lib/Twig/Node/Expression/Binary/StartsWith.php +28 -0
  79. Twig/lib/Twig/Node/Expression/Binary/Sub.php +0 -0
  80. Twig/lib/Twig/Node/Expression/BlockReference.php +0 -0
  81. Twig/lib/Twig/Node/Expression/Call.php +3 -3
  82. Twig/lib/Twig/Node/Expression/Conditional.php +0 -0
  83. Twig/lib/Twig/Node/Expression/Constant.php +0 -0
  84. Twig/lib/Twig/Node/Expression/ExtensionReference.php +0 -0
  85. Twig/lib/Twig/Node/Expression/Filter.php +0 -0
  86. Twig/lib/Twig/Node/Expression/Filter/Default.php +0 -0
  87. Twig/lib/Twig/Node/Expression/Function.php +0 -0
  88. Twig/lib/Twig/Node/Expression/GetAttr.php +2 -2
  89. Twig/lib/Twig/Node/Expression/MethodCall.php +0 -0
  90. Twig/lib/Twig/Node/Expression/Name.php +0 -0
  91. Twig/lib/Twig/Node/Expression/Parent.php +0 -0
  92. Twig/lib/Twig/Node/Expression/TempName.php +0 -0
  93. Twig/lib/Twig/Node/Expression/Test.php +0 -0
  94. Twig/lib/Twig/Node/Expression/Test/Constant.php +0 -0
  95. Twig/lib/Twig/Node/Expression/Test/Defined.php +0 -0
  96. Twig/lib/Twig/Node/Expression/Test/Divisibleby.php +0 -0
  97. Twig/lib/Twig/Node/Expression/Test/Even.php +0 -0
  98. Twig/lib/Twig/Node/Expression/Test/Null.php +0 -0
  99. Twig/lib/Twig/Node/Expression/Test/Odd.php +0 -0
  100. Twig/lib/Twig/Node/Expression/Test/Sameas.php +0 -0
  101. Twig/lib/Twig/Node/Expression/Unary.php +0 -0
  102. Twig/lib/Twig/Node/Expression/Unary/Neg.php +0 -0
  103. Twig/lib/Twig/Node/Expression/Unary/Not.php +0 -0
  104. Twig/lib/Twig/Node/Expression/Unary/Pos.php +0 -0
  105. Twig/lib/Twig/Node/Flush.php +0 -0
  106. Twig/lib/Twig/Node/For.php +0 -0
  107. Twig/lib/Twig/Node/ForLoop.php +0 -0
  108. Twig/lib/Twig/Node/If.php +1 -1
  109. Twig/lib/Twig/Node/Import.php +0 -0
  110. Twig/lib/Twig/Node/Include.php +0 -0
  111. Twig/lib/Twig/Node/Macro.php +0 -0
  112. Twig/lib/Twig/Node/Module.php +0 -0
  113. Twig/lib/Twig/Node/Print.php +0 -0
  114. Twig/lib/Twig/Node/Sandbox.php +0 -0
  115. Twig/lib/Twig/Node/SandboxedModule.php +0 -0
  116. Twig/lib/Twig/Node/SandboxedPrint.php +0 -0
  117. Twig/lib/Twig/Node/Set.php +0 -0
  118. Twig/lib/Twig/Node/SetTemp.php +0 -0
  119. Twig/lib/Twig/Node/Spaceless.php +0 -0
  120. Twig/lib/Twig/Node/Text.php +0 -0
  121. Twig/lib/Twig/NodeInterface.php +0 -0
  122. Twig/lib/Twig/NodeOutputInterface.php +0 -0
  123. Twig/lib/Twig/NodeTraverser.php +0 -0
  124. Twig/lib/Twig/NodeVisitor/Escaper.php +0 -0
  125. Twig/lib/Twig/NodeVisitor/Optimizer.php +5 -5
  126. Twig/lib/Twig/NodeVisitor/SafeAnalysis.php +13 -5
  127. Twig/lib/Twig/NodeVisitor/Sandbox.php +0 -0
  128. Twig/lib/Twig/NodeVisitorInterface.php +0 -0
  129. Twig/lib/Twig/Parser.php +3 -7
  130. Twig/lib/Twig/ParserInterface.php +2 -0
  131. Twig/lib/Twig/Sandbox/SecurityError.php +0 -0
  132. Twig/lib/Twig/Sandbox/SecurityPolicy.php +0 -0
  133. Twig/lib/Twig/Sandbox/SecurityPolicyInterface.php +0 -0
  134. Twig/lib/Twig/SimpleFilter.php +0 -0
  135. Twig/lib/Twig/SimpleFunction.php +0 -0
  136. Twig/lib/Twig/SimpleTest.php +0 -0
  137. Twig/lib/Twig/Template.php +23 -11
  138. Twig/lib/Twig/TemplateInterface.php +0 -0
  139. Twig/lib/Twig/Test.php +0 -0
  140. Twig/lib/Twig/Test/Function.php +0 -0
  141. Twig/lib/Twig/Test/IntegrationTestCase.php +0 -0
  142. Twig/lib/Twig/Test/Method.php +0 -0
  143. Twig/lib/Twig/Test/Node.php +0 -0
  144. Twig/lib/Twig/Test/NodeTestCase.php +0 -0
  145. Twig/lib/Twig/TestCallableInterface.php +0 -0
  146. Twig/lib/Twig/TestInterface.php +0 -0
  147. Twig/lib/Twig/Token.php +2 -4
  148. Twig/lib/Twig/TokenParser.php +0 -0
  149. Twig/lib/Twig/TokenParser/AutoEscape.php +0 -0
  150. Twig/lib/Twig/TokenParser/Block.php +0 -0
  151. Twig/lib/Twig/TokenParser/Do.php +0 -0
  152. Twig/lib/Twig/TokenParser/Embed.php +0 -0
  153. Twig/lib/Twig/TokenParser/Extends.php +0 -0
  154. Twig/lib/Twig/TokenParser/Filter.php +0 -0
  155. Twig/lib/Twig/TokenParser/Flush.php +0 -0
  156. Twig/lib/Twig/TokenParser/For.php +0 -0
  157. Twig/lib/Twig/TokenParser/From.php +0 -0
  158. Twig/lib/Twig/TokenParser/If.php +0 -0
  159. Twig/lib/Twig/TokenParser/Import.php +0 -0
  160. Twig/lib/Twig/TokenParser/Include.php +0 -0
  161. Twig/lib/Twig/TokenParser/Macro.php +0 -0
  162. Twig/lib/Twig/TokenParser/Sandbox.php +0 -0
  163. Twig/lib/Twig/TokenParser/Set.php +0 -0
  164. Twig/lib/Twig/TokenParser/Spaceless.php +0 -0
  165. Twig/lib/Twig/TokenParser/Use.php +0 -0
  166. Twig/lib/Twig/TokenParserBroker.php +0 -0
  167. Twig/lib/Twig/TokenParserBrokerInterface.php +0 -0
  168. Twig/lib/Twig/TokenParserInterface.php +2 -0
  169. Twig/lib/Twig/TokenStream.php +0 -0
  170. functions/functions-twig.php +17 -14
  171. functions/integrations/acf-timber.php +55 -0
  172. functions/timber-comment.php +128 -11
  173. functions/timber-core.php +9 -8
  174. functions/{functions-timber-helper.php → timber-helper.php} +13 -32
  175. functions/{functions-timber-image-helper.php → timber-image-helper.php} +22 -0
  176. functions/timber-image.php +9 -2
  177. functions/timber-menu.php +2 -0
  178. functions/timber-post.php +49 -39
  179. functions/timber-term.php +95 -50
  180. functions/timber-user.php +34 -8
  181. readme.txt +10 -2
  182. timber-starter-theme/404.php +2 -1
  183. timber-starter-theme/archive.php +5 -6
  184. timber-starter-theme/index.php +4 -4
  185. timber-starter-theme/search.php +8 -8
  186. timber-starter-theme/single.php +2 -2
  187. timber.php +10 -6
Twig/AUTHORS CHANGED
@@ -4,6 +4,10 @@ Lead Developer:
4
 
5
  - Fabien Potencier <fabien.potencier@symfony-project.org>
6
 
 
 
 
 
7
  Project Founder:
8
 
9
  - Armin Ronacher <armin.ronacher@active-4.com>
4
 
5
  - Fabien Potencier <fabien.potencier@symfony-project.org>
6
 
7
+ C Extension Developer:
8
+
9
+ - Derick Rethans <derick@derickrethans.nl>
10
+
11
  Project Founder:
12
 
13
  - Armin Ronacher <armin.ronacher@active-4.com>
Twig/CHANGELOG CHANGED
@@ -1,3 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  * 1.13.1 (2013-06-06)
2
 
3
  * added the possibility to ignore the filesystem constructor argument in Twig_Loader_Filesystem
1
+ * 1.15.0 (2013-XX-XX)
2
+
3
+ * added a source function to include the content of a template without rendering it
4
+ * fixed the C extension sandbox behavior when get or set is prepend to method name
5
+
6
+ * 1.14.2 (2013-10-30)
7
+
8
+ * fixed error filename/line when an error occurs in an included file
9
+ * allowed operators that contain whitespaces to have more than one whitespace
10
+ * allowed tests to be made of 1 or 2 words (like "same as" or "divisible by")
11
+
12
+ * 1.14.1 (2013-10-15)
13
+
14
+ * made it possible to use named operators as variables
15
+ * fixed the possibility to have a variable named 'matches'
16
+ * added support for PHP 5.5 DateTimeInterface
17
+
18
+ * 1.14.0 (2013-10-03)
19
+
20
+ * fixed usage of the html_attr escaping strategy to avoid double-escaping with the html strategy
21
+ * added new operators: ends with, starts with, and matches
22
+ * fixed some compatibility issues with HHVM
23
+ * added a way to add custom escaping strategies
24
+ * fixed the C extension compilation on Windows
25
+ * fixed the batch filter when using a fill argument with an exact match of elements to batch
26
+ * fixed the filesystem loader cache when a template name exists in several namespaces
27
+ * fixed template_from_string when the template includes or extends other ones
28
+ * fixed a crash of the C extension on an edge case
29
+
30
+ * 1.13.2 (2013-08-03)
31
+
32
+ * fixed the error line number for an error occurs in and embedded template
33
+ * fixed crashes of the C extension on some edge cases
34
+
35
  * 1.13.1 (2013-06-06)
36
 
37
  * added the possibility to ignore the filesystem constructor argument in Twig_Loader_Filesystem
Twig/LICENSE CHANGED
File without changes
Twig/README.markdown CHANGED
@@ -1,8 +1,6 @@
1
  Twig, the flexible, fast, and secure template language for PHP
2
  ==============================================================
3
 
4
- [![Build Status](https://secure.travis-ci.org/fabpot/Twig.png?branch=master)](http://travis-ci.org/fabpot/Twig)
5
-
6
  Twig is a template language for PHP, released under the new BSD license (code
7
  and documentation).
8
 
1
  Twig, the flexible, fast, and secure template language for PHP
2
  ==============================================================
3
 
 
 
4
  Twig is a template language for PHP, released under the new BSD license (code
5
  and documentation).
6
 
Twig/lib/Twig/Autoloader.php CHANGED
File without changes
Twig/lib/Twig/Compiler.php CHANGED
@@ -180,11 +180,12 @@ class Twig_Compiler implements Twig_CompilerInterface
180
  $this->raw($value ? 'true' : 'false');
181
  } elseif (is_array($value)) {
182
  $this->raw('array(');
183
- $i = 0;
184
  foreach ($value as $key => $value) {
185
- if ($i++) {
186
  $this->raw(', ');
187
  }
 
188
  $this->repr($key);
189
  $this->raw(' => ');
190
  $this->repr($value);
@@ -252,6 +253,8 @@ class Twig_Compiler implements Twig_CompilerInterface
252
  * @param integer $step The number of indentation to remove
253
  *
254
  * @return Twig_Compiler The current compiler instance
 
 
255
  */
256
  public function outdent($step = 1)
257
  {
180
  $this->raw($value ? 'true' : 'false');
181
  } elseif (is_array($value)) {
182
  $this->raw('array(');
183
+ $first = true;
184
  foreach ($value as $key => $value) {
185
+ if (!$first) {
186
  $this->raw(', ');
187
  }
188
+ $first = false;
189
  $this->repr($key);
190
  $this->raw(' => ');
191
  $this->repr($value);
253
  * @param integer $step The number of indentation to remove
254
  *
255
  * @return Twig_Compiler The current compiler instance
256
+ *
257
+ * @throws LogicException When trying to outdent too much so the indentation would become negative
258
  */
259
  public function outdent($step = 1)
260
  {
Twig/lib/Twig/CompilerInterface.php CHANGED
File without changes
Twig/lib/Twig/Environment.php CHANGED
@@ -16,7 +16,7 @@
16
  */
17
  class Twig_Environment
18
  {
19
- const VERSION = '1.13.1';
20
 
21
  protected $charset;
22
  protected $loader;
@@ -44,6 +44,7 @@ class Twig_Environment
44
  protected $functionCallbacks;
45
  protected $filterCallbacks;
46
  protected $staging;
 
47
 
48
  /**
49
  * Constructor.
@@ -61,9 +62,9 @@ class Twig_Environment
61
  * * cache: An absolute path where to store the compiled templates, or
62
  * false to disable compilation cache (default).
63
  *
64
- * * auto_reload: Whether to reload the template is the original source changed.
65
  * If you don't provide the auto_reload option, it will be
66
- * determined automatically base on the debug value.
67
  *
68
  * * strict_variables: Whether to ignore invalid variables in templates
69
  * (default to false).
@@ -107,6 +108,7 @@ class Twig_Environment
107
  $this->setCache($options['cache']);
108
  $this->functionCallbacks = array();
109
  $this->filterCallbacks = array();
 
110
 
111
  $this->addExtension(new Twig_Extension_Core());
112
  $this->addExtension(new Twig_Extension_Escaper($options['autoescape']));
@@ -239,7 +241,7 @@ class Twig_Environment
239
  *
240
  * @param string $name The template name
241
  *
242
- * @return string The cache file name
243
  */
244
  public function getCacheFilename($name)
245
  {
@@ -262,7 +264,13 @@ class Twig_Environment
262
  */
263
  public function getTemplateClass($name, $index = null)
264
  {
265
- return $this->templateClassPrefix.md5($this->getLoader()->getCacheKey($name)).(null === $index ? '' : '_'.$index);
 
 
 
 
 
 
266
  }
267
 
268
  /**
@@ -282,6 +290,10 @@ class Twig_Environment
282
  * @param array $context An array of parameters to pass to the template
283
  *
284
  * @return string The rendered template
 
 
 
 
285
  */
286
  public function render($name, array $context = array())
287
  {
@@ -293,6 +305,10 @@ class Twig_Environment
293
  *
294
  * @param string $name The template name
295
  * @param array $context An array of parameters to pass to the template
 
 
 
 
296
  */
297
  public function display($name, array $context = array())
298
  {
@@ -306,6 +322,9 @@ class Twig_Environment
306
  * @param integer $index The index if it is an embedded template
307
  *
308
  * @return Twig_TemplateInterface A template instance representing the given template name
 
 
 
309
  */
310
  public function loadTemplate($name, $index = null)
311
  {
@@ -358,6 +377,19 @@ class Twig_Environment
358
  return $this->getLoader()->isFresh($name, $time);
359
  }
360
 
 
 
 
 
 
 
 
 
 
 
 
 
 
361
  public function resolveTemplate($names)
362
  {
363
  if (!is_array($names)) {
@@ -437,6 +469,8 @@ class Twig_Environment
437
  * @param string $name The template name
438
  *
439
  * @return Twig_TokenStream A Twig_TokenStream instance
 
 
440
  */
441
  public function tokenize($source, $name = null)
442
  {
@@ -468,15 +502,17 @@ class Twig_Environment
468
  }
469
 
470
  /**
471
- * Parses a token stream.
 
 
472
  *
473
- * @param Twig_TokenStream $tokens A Twig_TokenStream instance
474
  *
475
- * @return Twig_Node_Module A Node tree
476
  */
477
- public function parse(Twig_TokenStream $tokens)
478
  {
479
- return $this->getParser()->parse($tokens);
480
  }
481
 
482
  /**
@@ -504,7 +540,7 @@ class Twig_Environment
504
  }
505
 
506
  /**
507
- * Compiles a Node.
508
  *
509
  * @param Twig_NodeInterface $node A Twig_NodeInterface instance
510
  *
@@ -522,6 +558,8 @@ class Twig_Environment
522
  * @param string $name The template name
523
  *
524
  * @return string The compiled PHP source code
 
 
525
  */
526
  public function compileSource($source, $name = null)
527
  {
@@ -531,7 +569,7 @@ class Twig_Environment
531
  $e->setTemplateFile($name);
532
  throw $e;
533
  } catch (Exception $e) {
534
- throw new Twig_Error_Runtime(sprintf('An exception has been thrown during the compilation of a template ("%s").', $e->getMessage()), -1, $name, $e);
535
  }
536
  }
537
 
@@ -728,7 +766,7 @@ class Twig_Environment
728
  public function addNodeVisitor(Twig_NodeVisitorInterface $visitor)
729
  {
730
  if ($this->extensionInitialized) {
731
- throw new LogicException('Unable to add a node visitor as extensions have already been initialized.', $extension->getName());
732
  }
733
 
734
  $this->staging->addNodeVisitor($visitor);
@@ -764,11 +802,11 @@ class Twig_Environment
764
  $filter = $name;
765
  $name = $filter->getName();
766
  }
767
-
768
  if ($this->extensionInitialized) {
769
  throw new LogicException(sprintf('Unable to add filter "%s" as extensions have already been initialized.', $name));
770
  }
771
-
772
  $this->staging->addFilter($name, $filter);
773
  }
774
 
@@ -853,7 +891,7 @@ class Twig_Environment
853
  $test = $name;
854
  $name = $test->getName();
855
  }
856
-
857
  if ($this->extensionInitialized) {
858
  throw new LogicException(sprintf('Unable to add test "%s" as extensions have already been initialized.', $name));
859
  }
@@ -911,11 +949,11 @@ class Twig_Environment
911
  $function = $name;
912
  $name = $function->getName();
913
  }
914
-
915
  if ($this->extensionInitialized) {
916
  throw new LogicException(sprintf('Unable to add function "%s" as extensions have already been initialized.', $name));
917
  }
918
-
919
  $this->staging->addFunction($name, $function);
920
  }
921
 
@@ -1209,7 +1247,7 @@ class Twig_Environment
1209
  throw new RuntimeException(sprintf("Unable to write in the cache directory (%s).", $dir));
1210
  }
1211
 
1212
- $tmpFile = tempnam(dirname($file), basename($file));
1213
  if (false !== @file_put_contents($tmpFile, $content)) {
1214
  // rename does not work on Win32 before 5.2.6
1215
  if (@rename($tmpFile, $file) || (@copy($tmpFile, $file) && unlink($tmpFile))) {
16
  */
17
  class Twig_Environment
18
  {
19
+ const VERSION = '1.14.2';
20
 
21
  protected $charset;
22
  protected $loader;
44
  protected $functionCallbacks;
45
  protected $filterCallbacks;
46
  protected $staging;
47
+ protected $templateClasses;
48
 
49
  /**
50
  * Constructor.
62
  * * cache: An absolute path where to store the compiled templates, or
63
  * false to disable compilation cache (default).
64
  *
65
+ * * auto_reload: Whether to reload the template if the original source changed.
66
  * If you don't provide the auto_reload option, it will be
67
+ * determined automatically based on the debug value.
68
  *
69
  * * strict_variables: Whether to ignore invalid variables in templates
70
  * (default to false).
108
  $this->setCache($options['cache']);
109
  $this->functionCallbacks = array();
110
  $this->filterCallbacks = array();
111
+ $this->templateClasses = array();
112
 
113
  $this->addExtension(new Twig_Extension_Core());
114
  $this->addExtension(new Twig_Extension_Escaper($options['autoescape']));
241
  *
242
  * @param string $name The template name
243
  *
244
+ * @return string|false The cache file name or false when caching is disabled
245
  */
246
  public function getCacheFilename($name)
247
  {
264
  */
265
  public function getTemplateClass($name, $index = null)
266
  {
267
+ $suffix = null === $index ? '' : '_'.$index;
268
+ $cls = $name.$suffix;
269
+ if (isset($this->templateClasses[$cls])) {
270
+ return $this->templateClasses[$cls];
271
+ }
272
+
273
+ return $this->templateClasses[$cls] = $this->templateClassPrefix.hash('sha256', $this->getLoader()->getCacheKey($name)).$suffix;
274
  }
275
 
276
  /**
290
  * @param array $context An array of parameters to pass to the template
291
  *
292
  * @return string The rendered template
293
+ *
294
+ * @throws Twig_Error_Loader When the template cannot be found
295
+ * @throws Twig_Error_Syntax When an error occurred during compilation
296
+ * @throws Twig_Error_Runtime When an error occurred during rendering
297
  */
298
  public function render($name, array $context = array())
299
  {
305
  *
306
  * @param string $name The template name
307
  * @param array $context An array of parameters to pass to the template
308
+ *
309
+ * @throws Twig_Error_Loader When the template cannot be found
310
+ * @throws Twig_Error_Syntax When an error occurred during compilation
311
+ * @throws Twig_Error_Runtime When an error occurred during rendering
312
  */
313
  public function display($name, array $context = array())
314
  {
322
  * @param integer $index The index if it is an embedded template
323
  *
324
  * @return Twig_TemplateInterface A template instance representing the given template name
325
+ *
326
+ * @throws Twig_Error_Loader When the template cannot be found
327
+ * @throws Twig_Error_Syntax When an error occurred during compilation
328
  */
329
  public function loadTemplate($name, $index = null)
330
  {
377
  return $this->getLoader()->isFresh($name, $time);
378
  }
379
 
380
+ /**
381
+ * Tries to load a template consecutively from an array.
382
+ *
383
+ * Similar to loadTemplate() but it also accepts Twig_TemplateInterface instances and an array
384
+ * of templates where each is tried to be loaded.
385
+ *
386
+ * @param string|Twig_Template|array $names A template or an array of templates to try consecutively
387
+ *
388
+ * @return Twig_Template
389
+ *
390
+ * @throws Twig_Error_Loader When none of the templates can be found
391
+ * @throws Twig_Error_Syntax When an error occurred during compilation
392
+ */
393
  public function resolveTemplate($names)
394
  {
395
  if (!is_array($names)) {
469
  * @param string $name The template name
470
  *
471
  * @return Twig_TokenStream A Twig_TokenStream instance
472
+ *
473
+ * @throws Twig_Error_Syntax When the code is syntactically wrong
474
  */
475
  public function tokenize($source, $name = null)
476
  {
502
  }
503
 
504
  /**
505
+ * Converts a token stream to a node tree.
506
+ *
507
+ * @param Twig_TokenStream $stream A token stream instance
508
  *
509
+ * @return Twig_Node_Module A node tree
510
  *
511
+ * @throws Twig_Error_Syntax When the token stream is syntactically or semantically wrong
512
  */
513
+ public function parse(Twig_TokenStream $stream)
514
  {
515
+ return $this->getParser()->parse($stream);
516
  }
517
 
518
  /**
540
  }
541
 
542
  /**
543
+ * Compiles a node and returns the PHP code.
544
  *
545
  * @param Twig_NodeInterface $node A Twig_NodeInterface instance
546
  *
558
  * @param string $name The template name
559
  *
560
  * @return string The compiled PHP source code
561
+ *
562
+ * @throws Twig_Error_Syntax When there was an error during tokenizing, parsing or compiling
563
  */
564
  public function compileSource($source, $name = null)
565
  {
569
  $e->setTemplateFile($name);
570
  throw $e;
571
  } catch (Exception $e) {
572
+ throw new Twig_Error_Syntax(sprintf('An exception has been thrown during the compilation of a template ("%s").', $e->getMessage()), -1, $name, $e);
573
  }
574
  }
575
 
766
  public function addNodeVisitor(Twig_NodeVisitorInterface $visitor)
767
  {
768
  if ($this->extensionInitialized) {
769
+ throw new LogicException('Unable to add a node visitor as extensions have already been initialized.');
770
  }
771
 
772
  $this->staging->addNodeVisitor($visitor);
802
  $filter = $name;
803
  $name = $filter->getName();
804
  }
805
+
806
  if ($this->extensionInitialized) {
807
  throw new LogicException(sprintf('Unable to add filter "%s" as extensions have already been initialized.', $name));
808
  }
809
+
810
  $this->staging->addFilter($name, $filter);
811
  }
812
 
891
  $test = $name;
892
  $name = $test->getName();
893
  }
894
+
895
  if ($this->extensionInitialized) {
896
  throw new LogicException(sprintf('Unable to add test "%s" as extensions have already been initialized.', $name));
897
  }
949
  $function = $name;
950
  $name = $function->getName();
951
  }
952
+
953
  if ($this->extensionInitialized) {
954
  throw new LogicException(sprintf('Unable to add function "%s" as extensions have already been initialized.', $name));
955
  }
956
+
957
  $this->staging->addFunction($name, $function);
958
  }
959
 
1247
  throw new RuntimeException(sprintf("Unable to write in the cache directory (%s).", $dir));
1248
  }
1249
 
1250
+ $tmpFile = tempnam($dir, basename($file));
1251
  if (false !== @file_put_contents($tmpFile, $content)) {
1252
  // rename does not work on Win32 before 5.2.6
1253
  if (@rename($tmpFile, $file) || (@copy($tmpFile, $file) && unlink($tmpFile))) {
Twig/lib/Twig/Error.php CHANGED
@@ -186,6 +186,7 @@ class Twig_Error extends Exception
186
  protected function guessTemplateInfo()
187
  {
188
  $template = null;
 
189
 
190
  if (version_compare(phpversion(), '5.3.6', '>=')) {
191
  $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS | DEBUG_BACKTRACE_PROVIDE_OBJECT);
@@ -195,8 +196,11 @@ class Twig_Error extends Exception
195
 
196
  foreach ($backtrace as $trace) {
197
  if (isset($trace['object']) && $trace['object'] instanceof Twig_Template && 'Twig_Template' !== get_class($trace['object'])) {
198
- if (null === $this->filename || $this->filename == $trace['object']->getTemplateName()) {
 
 
199
  $template = $trace['object'];
 
200
  }
201
  }
202
  }
@@ -213,6 +217,11 @@ class Twig_Error extends Exception
213
  $r = new ReflectionObject($template);
214
  $file = $r->getFileName();
215
 
 
 
 
 
 
216
  $exceptions = array($e = $this);
217
  while (($e instanceof self || method_exists($e, 'getPrevious')) && $e = $e->getPrevious()) {
218
  $exceptions[] = $e;
186
  protected function guessTemplateInfo()
187
  {
188
  $template = null;
189
+ $templateClass = null;
190
 
191
  if (version_compare(phpversion(), '5.3.6', '>=')) {
192
  $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS | DEBUG_BACKTRACE_PROVIDE_OBJECT);
196
 
197
  foreach ($backtrace as $trace) {
198
  if (isset($trace['object']) && $trace['object'] instanceof Twig_Template && 'Twig_Template' !== get_class($trace['object'])) {
199
+ $currentClass = get_class($trace['object']);
200
+ $isEmbedContainer = 0 === strpos($templateClass, $currentClass);
201
+ if (null === $this->filename || ($this->filename == $trace['object']->getTemplateName() && !$isEmbedContainer)) {
202
  $template = $trace['object'];
203
+ $templateClass = get_class($trace['object']);
204
  }
205
  }
206
  }
217
  $r = new ReflectionObject($template);
218
  $file = $r->getFileName();
219
 
220
+ // hhvm has a bug where eval'ed files comes out as the current directory
221
+ if (is_dir($file)) {
222
+ $file = '';
223
+ }
224
+
225
  $exceptions = array($e = $this);
226
  while (($e instanceof self || method_exists($e, 'getPrevious')) && $e = $e->getPrevious()) {
227
  $exceptions[] = $e;
Twig/lib/Twig/Error/Loader.php CHANGED
File without changes
Twig/lib/Twig/Error/Runtime.php CHANGED
File without changes
Twig/lib/Twig/Error/Syntax.php CHANGED
File without changes
Twig/lib/Twig/ExistsLoaderInterface.php CHANGED
File without changes
Twig/lib/Twig/ExpressionParser.php CHANGED
@@ -161,6 +161,14 @@ class Twig_ExpressionParser
161
  $node = $this->parseStringExpression();
162
  break;
163
 
 
 
 
 
 
 
 
 
164
  default:
165
  if ($token->test(Twig_Token::PUNCTUATION_TYPE, '[')) {
166
  $node = $this->parseArrayExpression();
@@ -316,7 +324,7 @@ class Twig_ExpressionParser
316
  throw new Twig_Error_Syntax('The "attribute" function takes at least two arguments (the variable and the attributes)', $line, $this->parser->getFilename());
317
  }
318
 
319
- return new Twig_Node_Expression_GetAttr($args->getNode(0), $args->getNode(1), count($args) > 2 ? $args->getNode(2) : new Twig_Node_Expression_Array(array(), $line), Twig_TemplateInterface::ANY_CALL, $line);
320
  default:
321
  if (null !== $alias = $this->parser->getImportedSymbol('function', $name)) {
322
  $arguments = new Twig_Node_Expression_Array(array(), $line);
@@ -343,7 +351,7 @@ class Twig_ExpressionParser
343
  $token = $stream->next();
344
  $lineno = $token->getLine();
345
  $arguments = new Twig_Node_Expression_Array(array(), $lineno);
346
- $type = Twig_TemplateInterface::ANY_CALL;
347
  if ($token->getValue() == '.') {
348
  $token = $stream->next();
349
  if (
@@ -376,7 +384,7 @@ class Twig_ExpressionParser
376
  return $node;
377
  }
378
  } else {
379
- $type = Twig_TemplateInterface::ARRAY_CALL;
380
 
381
  // slice?
382
  $slice = false;
161
  $node = $this->parseStringExpression();
162
  break;
163
 
164
+ case Twig_Token::OPERATOR_TYPE:
165
+ if (preg_match(Twig_Lexer::REGEX_NAME, $token->getValue(), $matches) && $matches[0] == $token->getValue()) {
166
+ // in this context, string operators are variable names
167
+ $this->parser->getStream()->next();
168
+ $node = new Twig_Node_Expression_Name($token->getValue(), $token->getLine());
169
+ break;
170
+ }
171
+
172
  default:
173
  if ($token->test(Twig_Token::PUNCTUATION_TYPE, '[')) {
174
  $node = $this->parseArrayExpression();
324
  throw new Twig_Error_Syntax('The "attribute" function takes at least two arguments (the variable and the attributes)', $line, $this->parser->getFilename());
325
  }
326
 
327
+ return new Twig_Node_Expression_GetAttr($args->getNode(0), $args->getNode(1), count($args) > 2 ? $args->getNode(2) : new Twig_Node_Expression_Array(array(), $line), Twig_Template::ANY_CALL, $line);
328
  default:
329
  if (null !== $alias = $this->parser->getImportedSymbol('function', $name)) {
330
  $arguments = new Twig_Node_Expression_Array(array(), $line);
351
  $token = $stream->next();
352
  $lineno = $token->getLine();
353
  $arguments = new Twig_Node_Expression_Array(array(), $lineno);
354
+ $type = Twig_Template::ANY_CALL;
355
  if ($token->getValue() == '.') {
356
  $token = $stream->next();
357
  if (
384
  return $node;
385
  }
386
  } else {
387
+ $type = Twig_Template::ARRAY_CALL;
388
 
389
  // slice?
390
  $slice = false;
Twig/lib/Twig/Extension.php CHANGED
File without changes
Twig/lib/Twig/Extension/Core.php CHANGED
@@ -1,7 +1,8 @@
1
  <?php
2
 
3
  if (!defined('ENT_SUBSTITUTE')) {
4
- define('ENT_SUBSTITUTE', 8);
 
5
  }
6
 
7
  /*
@@ -17,6 +18,28 @@ class Twig_Extension_Core extends Twig_Extension
17
  protected $dateFormats = array('F j, Y H:i', '%d days');
18
  protected $numberFormat = array(0, '.', ',');
19
  protected $timezone = null;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
 
21
  /**
22
  * Sets the default format to be used by the date filter.
@@ -207,9 +230,11 @@ class Twig_Extension_Core extends Twig_Extension
207
  new Twig_SimpleTest('odd', null, array('node_class' => 'Twig_Node_Expression_Test_Odd')),
208
  new Twig_SimpleTest('defined', null, array('node_class' => 'Twig_Node_Expression_Test_Defined')),
209
  new Twig_SimpleTest('sameas', null, array('node_class' => 'Twig_Node_Expression_Test_Sameas')),
 
210
  new Twig_SimpleTest('none', null, array('node_class' => 'Twig_Node_Expression_Test_Null')),
211
  new Twig_SimpleTest('null', null, array('node_class' => 'Twig_Node_Expression_Test_Null')),
212
  new Twig_SimpleTest('divisibleby', null, array('node_class' => 'Twig_Node_Expression_Test_Divisibleby')),
 
213
  new Twig_SimpleTest('constant', null, array('node_class' => 'Twig_Node_Expression_Test_Constant')),
214
  new Twig_SimpleTest('empty', 'twig_test_empty'),
215
  new Twig_SimpleTest('iterable', 'twig_test_iterable'),
@@ -230,50 +255,52 @@ class Twig_Extension_Core extends Twig_Extension
230
  '+' => array('precedence' => 500, 'class' => 'Twig_Node_Expression_Unary_Pos'),
231
  ),
232
  array(
233
- 'or' => array('precedence' => 10, 'class' => 'Twig_Node_Expression_Binary_Or', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
234
- 'and' => array('precedence' => 15, 'class' => 'Twig_Node_Expression_Binary_And', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
235
- 'b-or' => array('precedence' => 16, 'class' => 'Twig_Node_Expression_Binary_BitwiseOr', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
236
- 'b-xor' => array('precedence' => 17, 'class' => 'Twig_Node_Expression_Binary_BitwiseXor', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
237
- 'b-and' => array('precedence' => 18, 'class' => 'Twig_Node_Expression_Binary_BitwiseAnd', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
238
- '==' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Equal', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
239
- '!=' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
240
- '<' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Less', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
241
- '>' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Greater', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
242
- '>=' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_GreaterEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
243
- '<=' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_LessEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
244
- 'not in' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotIn', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
245
- 'in' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_In', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
246
- '..' => array('precedence' => 25, 'class' => 'Twig_Node_Expression_Binary_Range', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
247
- '+' => array('precedence' => 30, 'class' => 'Twig_Node_Expression_Binary_Add', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
248
- '-' => array('precedence' => 30, 'class' => 'Twig_Node_Expression_Binary_Sub', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
249
- '~' => array('precedence' => 40, 'class' => 'Twig_Node_Expression_Binary_Concat', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
250
- '*' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mul', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
251
- '/' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Div', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
252
- '//' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_FloorDiv', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
253
- '%' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mod', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
254
- 'is' => array('precedence' => 100, 'callable' => array($this, 'parseTestExpression'), 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
255
- 'is not' => array('precedence' => 100, 'callable' => array($this, 'parseNotTestExpression'), 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
256
- '**' => array('precedence' => 200, 'class' => 'Twig_Node_Expression_Binary_Power', 'associativity' => Twig_ExpressionParser::OPERATOR_RIGHT),
 
 
 
257
  ),
258
  );
259
  }
260
 
261
- public function parseNotTestExpression(Twig_Parser $parser, $node)
262
  {
263
  return new Twig_Node_Expression_Unary_Not($this->parseTestExpression($parser, $node), $parser->getCurrentToken()->getLine());
264
  }
265
 
266
- public function parseTestExpression(Twig_Parser $parser, $node)
267
  {
268
  $stream = $parser->getStream();
269
  $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
 
270
  $arguments = null;
271
  if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
272
  $arguments = $parser->getExpressionParser()->parseArguments(true);
273
  }
274
 
275
- $class = $this->getTestNodeClass($parser, $name, $node->getLine());
276
-
277
  return new $class($node, $name, $arguments, $parser->getCurrentToken()->getLine());
278
  }
279
 
@@ -281,7 +308,21 @@ class Twig_Extension_Core extends Twig_Extension
281
  {
282
  $env = $parser->getEnvironment();
283
  $testMap = $env->getTests();
284
- if (!isset($testMap[$name])) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
285
  $message = sprintf('The test "%s" does not exist', $name);
286
  if ($alternatives = $env->computeAlternatives($name, array_keys($env->getTests()))) {
287
  $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives));
@@ -348,7 +389,7 @@ function twig_random(Twig_Environment $env, $values = null)
348
  return $values < 0 ? mt_rand($values, 0) : mt_rand(0, $values);
349
  }
350
 
351
- if ($values instanceof Traversable) {
352
  $values = iterator_to_array($values);
353
  } elseif (is_string($values)) {
354
  if ('' === $values) {
@@ -459,13 +500,15 @@ function twig_date_converter(Twig_Environment $env, $date = null, $timezone = nu
459
  $defaultTimezone = $timezone;
460
  }
461
 
462
- if ($date instanceof DateTime) {
463
- $date = clone $date;
464
  if (false !== $timezone) {
465
- $date->setTimezone($defaultTimezone);
 
 
466
  }
467
 
468
- return $date;
469
  }
470
 
471
  $asString = (string) $date;
@@ -620,7 +663,7 @@ function twig_array_merge($arr1, $arr2)
620
  */
621
  function twig_slice(Twig_Environment $env, $item, $start, $length = null, $preserveKeys = false)
622
  {
623
- if ($item instanceof Traversable) {
624
  $item = iterator_to_array($item, false);
625
  }
626
 
@@ -687,7 +730,7 @@ function twig_last(Twig_Environment $env, $item)
687
  */
688
  function twig_join_filter($value, $glue = '')
689
  {
690
- if ($value instanceof Traversable) {
691
  $value = iterator_to_array($value, false);
692
  }
693
 
@@ -829,7 +872,7 @@ function twig_in_filter($value, $compare)
829
  }
830
 
831
  return false !== strpos($compare, (string) $value);
832
- } elseif ($compare instanceof Traversable) {
833
  return in_array($value, iterator_to_array($compare, false), is_object($value));
834
  }
835
 
@@ -870,22 +913,30 @@ function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html',
870
  // Using a static variable to avoid initializing the array
871
  // each time the function is called. Moving the declaration on the
872
  // top of the function slow downs other escaping strategies.
873
- static $htmlspecialcharsCharsets = array(
874
- 'ISO-8859-1' => true, 'ISO8859-1' => true,
875
- 'ISO-8859-15' => true, 'ISO8859-15' => true,
876
- 'utf-8' => true, 'UTF-8' => true,
877
- 'CP866' => true, 'IBM866' => true, '866' => true,
878
- 'CP1251' => true, 'WINDOWS-1251' => true, 'WIN-1251' => true,
879
- '1251' => true,
880
- 'CP1252' => true, 'WINDOWS-1252' => true, '1252' => true,
881
- 'KOI8-R' => true, 'KOI8-RU' => true, 'KOI8R' => true,
882
- 'BIG5' => true, '950' => true,
883
- 'GB2312' => true, '936' => true,
884
- 'BIG5-HKSCS' => true,
885
- 'SHIFT_JIS' => true, 'SJIS' => true, '932' => true,
886
- 'EUC-JP' => true, 'EUCJP' => true,
887
- 'ISO8859-5' => true, 'ISO-8859-5' => true, 'MACROMAN' => true,
888
- );
 
 
 
 
 
 
 
 
889
 
890
  if (isset($htmlspecialcharsCharsets[$charset])) {
891
  return htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE, $charset);
@@ -966,7 +1017,19 @@ function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html',
966
  return rawurlencode($string);
967
 
968
  default:
969
- throw new Twig_Error_Runtime(sprintf('Invalid escaping strategy "%s" (valid ones: html, js, url, css, and html_attr).', $strategy));
 
 
 
 
 
 
 
 
 
 
 
 
970
  }
971
  }
972
 
@@ -1273,11 +1336,11 @@ function twig_test_iterable($value)
1273
  /**
1274
  * Renders a template.
1275
  *
1276
- * @param string $template The template to render
1277
- * @param array $variables The variables to pass to the template
1278
- * @param Boolean $with_context Whether to pass the current context variables or not
1279
- * @param Boolean $ignore_missing Whether to ignore missing templates or not
1280
- * @param Boolean $sandboxed Whether to sandbox the template or not
1281
  *
1282
  * @return string The rendered template
1283
  */
@@ -1329,13 +1392,13 @@ function twig_constant($constant, $object = null)
1329
  *
1330
  * @param array $items An array of items
1331
  * @param integer $size The size of the batch
1332
- * @param string $fill A string to fill missing items
1333
  *
1334
  * @return array
1335
  */
1336
  function twig_array_batch($items, $size, $fill = null)
1337
  {
1338
- if ($items instanceof Traversable) {
1339
  $items = iterator_to_array($items, false);
1340
  }
1341
 
@@ -1345,10 +1408,12 @@ function twig_array_batch($items, $size, $fill = null)
1345
 
1346
  if (null !== $fill) {
1347
  $last = count($result) - 1;
1348
- $result[$last] = array_merge(
1349
- $result[$last],
1350
- array_fill(0, $size - count($result[$last]), $fill)
1351
- );
 
 
1352
  }
1353
 
1354
  return $result;
1
  <?php
2
 
3
  if (!defined('ENT_SUBSTITUTE')) {
4
+ // use 0 as hhvm does not support several flags yet
5
+ define('ENT_SUBSTITUTE', 0);
6
  }
7
 
8
  /*
18
  protected $dateFormats = array('F j, Y H:i', '%d days');
19
  protected $numberFormat = array(0, '.', ',');
20
  protected $timezone = null;
21
+ protected $escapers = array();
22
+
23
+ /**
24
+ * Defines a new escaper to be used via the escape filter.
25
+ *
26
+ * @param string $strategy The strategy name that should be used as a strategy in the escape call
27
+ * @param callable $callable A valid PHP callable
28
+ */
29
+ public function setEscaper($strategy, $callable)
30
+ {
31
+ $this->escapers[$strategy] = $callable;
32
+ }
33
+
34
+ /**
35
+ * Gets all defined escapers.
36
+ *
37
+ * @return array An array of escapers
38
+ */
39
+ public function getEscapers()
40
+ {
41
+ return $this->escapers;
42
+ }
43
 
44
  /**
45
  * Sets the default format to be used by the date filter.
230
  new Twig_SimpleTest('odd', null, array('node_class' => 'Twig_Node_Expression_Test_Odd')),
231
  new Twig_SimpleTest('defined', null, array('node_class' => 'Twig_Node_Expression_Test_Defined')),
232
  new Twig_SimpleTest('sameas', null, array('node_class' => 'Twig_Node_Expression_Test_Sameas')),
233
+ new Twig_SimpleTest('same as', null, array('node_class' => 'Twig_Node_Expression_Test_Sameas')),
234
  new Twig_SimpleTest('none', null, array('node_class' => 'Twig_Node_Expression_Test_Null')),
235
  new Twig_SimpleTest('null', null, array('node_class' => 'Twig_Node_Expression_Test_Null')),
236
  new Twig_SimpleTest('divisibleby', null, array('node_class' => 'Twig_Node_Expression_Test_Divisibleby')),
237
+ new Twig_SimpleTest('divisible by', null, array('node_class' => 'Twig_Node_Expression_Test_Divisibleby')),
238
  new Twig_SimpleTest('constant', null, array('node_class' => 'Twig_Node_Expression_Test_Constant')),
239
  new Twig_SimpleTest('empty', 'twig_test_empty'),
240
  new Twig_SimpleTest('iterable', 'twig_test_iterable'),
255
  '+' => array('precedence' => 500, 'class' => 'Twig_Node_Expression_Unary_Pos'),
256
  ),
257
  array(
258
+ 'or' => array('precedence' => 10, 'class' => 'Twig_Node_Expression_Binary_Or', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
259
+ 'and' => array('precedence' => 15, 'class' => 'Twig_Node_Expression_Binary_And', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
260
+ 'b-or' => array('precedence' => 16, 'class' => 'Twig_Node_Expression_Binary_BitwiseOr', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
261
+ 'b-xor' => array('precedence' => 17, 'class' => 'Twig_Node_Expression_Binary_BitwiseXor', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
262
+ 'b-and' => array('precedence' => 18, 'class' => 'Twig_Node_Expression_Binary_BitwiseAnd', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
263
+ '==' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Equal', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
264
+ '!=' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
265
+ '<' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Less', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
266
+ '>' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Greater', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
267
+ '>=' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_GreaterEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
268
+ '<=' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_LessEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
269
+ 'not in' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotIn', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
270
+ 'in' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_In', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
271
+ 'matches' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Matches', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
272
+ 'starts with' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_StartsWith', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
273
+ 'ends with' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_EndsWith', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
274
+ '..' => array('precedence' => 25, 'class' => 'Twig_Node_Expression_Binary_Range', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
275
+ '+' => array('precedence' => 30, 'class' => 'Twig_Node_Expression_Binary_Add', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
276
+ '-' => array('precedence' => 30, 'class' => 'Twig_Node_Expression_Binary_Sub', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
277
+ '~' => array('precedence' => 40, 'class' => 'Twig_Node_Expression_Binary_Concat', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
278
+ '*' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mul', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
279
+ '/' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Div', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
280
+ '//' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_FloorDiv', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
281
+ '%' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mod', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
282
+ 'is' => array('precedence' => 100, 'callable' => array($this, 'parseTestExpression'), 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
283
+ 'is not' => array('precedence' => 100, 'callable' => array($this, 'parseNotTestExpression'), 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
284
+ '**' => array('precedence' => 200, 'class' => 'Twig_Node_Expression_Binary_Power', 'associativity' => Twig_ExpressionParser::OPERATOR_RIGHT),
285
  ),
286
  );
287
  }
288
 
289
+ public function parseNotTestExpression(Twig_Parser $parser, Twig_NodeInterface $node)
290
  {
291
  return new Twig_Node_Expression_Unary_Not($this->parseTestExpression($parser, $node), $parser->getCurrentToken()->getLine());
292
  }
293
 
294
+ public function parseTestExpression(Twig_Parser $parser, Twig_NodeInterface $node)
295
  {
296
  $stream = $parser->getStream();
297
  $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
298
+ $class = $this->getTestNodeClass($parser, $name, $node->getLine());
299
  $arguments = null;
300
  if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
301
  $arguments = $parser->getExpressionParser()->parseArguments(true);
302
  }
303
 
 
 
304
  return new $class($node, $name, $arguments, $parser->getCurrentToken()->getLine());
305
  }
306
 
308
  {
309
  $env = $parser->getEnvironment();
310
  $testMap = $env->getTests();
311
+ $testName = null;
312
+ if (isset($testMap[$name])) {
313
+ $testName = $name;
314
+ } elseif ($parser->getStream()->test(Twig_Token::NAME_TYPE)) {
315
+ // try 2-words tests
316
+ $name = $name.' '.$parser->getCurrentToken()->getValue();
317
+
318
+ if (isset($testMap[$name])) {
319
+ $parser->getStream()->next();
320
+
321
+ $testName = $name;
322
+ }
323
+ }
324
+
325
+ if (null === $testName) {
326
  $message = sprintf('The test "%s" does not exist', $name);
327
  if ($alternatives = $env->computeAlternatives($name, array_keys($env->getTests()))) {
328
  $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives));
389
  return $values < 0 ? mt_rand($values, 0) : mt_rand(0, $values);
390
  }
391
 
392
+ if (is_object($values) && $values instanceof Traversable) {
393
  $values = iterator_to_array($values);
394
  } elseif (is_string($values)) {
395
  if ('' === $values) {
500
  $defaultTimezone = $timezone;
501
  }
502
 
503
+ if ($date instanceof DateTime || $date instanceof DateTimeInterface) {
504
+ $returningDate = new DateTime($date->format('c'));
505
  if (false !== $timezone) {
506
+ $returningDate->setTimezone($defaultTimezone);
507
+ } else {
508
+ $returningDate->setTimezone($date->getTimezone());
509
  }
510
 
511
+ return $returningDate;
512
  }
513
 
514
  $asString = (string) $date;
663
  */
664
  function twig_slice(Twig_Environment $env, $item, $start, $length = null, $preserveKeys = false)
665
  {
666
+ if (is_object($item) && $item instanceof Traversable) {
667
  $item = iterator_to_array($item, false);
668
  }
669
 
730
  */
731
  function twig_join_filter($value, $glue = '')
732
  {
733
+ if (is_object($value) && $value instanceof Traversable) {
734
  $value = iterator_to_array($value, false);
735
  }
736
 
872
  }
873
 
874
  return false !== strpos($compare, (string) $value);
875
+ } elseif (is_object($compare) && $compare instanceof Traversable) {
876
  return in_array($value, iterator_to_array($compare, false), is_object($value));
877
  }
878
 
913
  // Using a static variable to avoid initializing the array
914
  // each time the function is called. Moving the declaration on the
915
  // top of the function slow downs other escaping strategies.
916
+ static $htmlspecialcharsCharsets;
917
+
918
+ if (null === $htmlspecialcharsCharsets) {
919
+ if ('hiphop' === substr(PHP_VERSION, -6)) {
920
+ $htmlspecialcharsCharsets = array('utf-8' => true, 'UTF-8' => true);
921
+ } else {
922
+ $htmlspecialcharsCharsets = array(
923
+ 'ISO-8859-1' => true, 'ISO8859-1' => true,
924
+ 'ISO-8859-15' => true, 'ISO8859-15' => true,
925
+ 'utf-8' => true, 'UTF-8' => true,
926
+ 'CP866' => true, 'IBM866' => true, '866' => true,
927
+ 'CP1251' => true, 'WINDOWS-1251' => true, 'WIN-1251' => true,
928
+ '1251' => true,
929
+ 'CP1252' => true, 'WINDOWS-1252' => true, '1252' => true,
930
+ 'KOI8-R' => true, 'KOI8-RU' => true, 'KOI8R' => true,
931
+ 'BIG5' => true, '950' => true,
932
+ 'GB2312' => true, '936' => true,
933
+ 'BIG5-HKSCS' => true,
934
+ 'SHIFT_JIS' => true, 'SJIS' => true, '932' => true,
935
+ 'EUC-JP' => true, 'EUCJP' => true,
936
+ 'ISO8859-5' => true, 'ISO-8859-5' => true, 'MACROMAN' => true,
937
+ );
938
+ }
939
+ }
940
 
941
  if (isset($htmlspecialcharsCharsets[$charset])) {
942
  return htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE, $charset);
1017
  return rawurlencode($string);
1018
 
1019
  default:
1020
+ static $escapers;
1021
+
1022
+ if (null === $escapers) {
1023
+ $escapers = $env->getExtension('core')->getEscapers();
1024
+ }
1025
+
1026
+ if (isset($escapers[$strategy])) {
1027
+ return call_user_func($escapers[$strategy], $env, $string, $charset);
1028
+ }
1029
+
1030
+ $validStrategies = implode(', ', array_merge(array('html', 'js', 'url', 'css', 'html_attr'), array_keys($escapers)));
1031
+
1032
+ throw new Twig_Error_Runtime(sprintf('Invalid escaping strategy "%s" (valid ones: %s).', $strategy, $validStrategies));
1033
  }
1034
  }
1035
 
1336
  /**
1337
  * Renders a template.
1338
  *
1339
+ * @param string|array $template The template to render or an array of templates to try consecutively
1340
+ * @param array $variables The variables to pass to the template
1341
+ * @param Boolean $with_context Whether to pass the current context variables or not
1342
+ * @param Boolean $ignore_missing Whether to ignore missing templates or not
1343
+ * @param Boolean $sandboxed Whether to sandbox the template or not
1344
  *
1345
  * @return string The rendered template
1346
  */
1392
  *
1393
  * @param array $items An array of items
1394
  * @param integer $size The size of the batch
1395
+ * @param mixed $fill A value used to fill missing items
1396
  *
1397
  * @return array
1398
  */
1399
  function twig_array_batch($items, $size, $fill = null)
1400
  {
1401
+ if (is_object($items) && $items instanceof Traversable) {
1402
  $items = iterator_to_array($items, false);
1403
  }
1404
 
1408
 
1409
  if (null !== $fill) {
1410
  $last = count($result) - 1;
1411
+ if ($fillCount = $size - count($result[$last])) {
1412
+ $result[$last] = array_merge(
1413
+ $result[$last],
1414
+ array_fill(0, $fillCount, $fill)
1415
+ );
1416
+ }
1417
  }
1418
 
1419
  return $result;
Twig/lib/Twig/Extension/Debug.php CHANGED
File without changes
Twig/lib/Twig/Extension/Escaper.php CHANGED
File without changes
Twig/lib/Twig/Extension/Optimizer.php CHANGED
File without changes
Twig/lib/Twig/Extension/Sandbox.php CHANGED
File without changes
Twig/lib/Twig/Extension/Staging.php CHANGED
File without changes
Twig/lib/Twig/Extension/StringLoader.php CHANGED
@@ -43,16 +43,16 @@ class Twig_Extension_StringLoader extends Twig_Extension
43
  */
44
  function twig_template_from_string(Twig_Environment $env, $template)
45
  {
46
- static $loader;
47
 
48
- if (null === $loader) {
49
- $loader = new Twig_Loader_String();
50
- }
 
51
 
52
- $current = $env->getLoader();
53
  $env->setLoader($loader);
54
  try {
55
- $template = $env->loadTemplate($template);
56
  } catch (Exception $e) {
57
  $env->setLoader($current);
58
 
43
  */
44
  function twig_template_from_string(Twig_Environment $env, $template)
45
  {
46
+ $name = sprintf('__string_template__%s', hash('sha256', uniqid(mt_rand(), true), false));
47
 
48
+ $loader = new Twig_Loader_Chain(array(
49
+ new Twig_Loader_Array(array($name => $template)),
50
+ $current = $env->getLoader(),
51
+ ));
52
 
 
53
  $env->setLoader($loader);
54
  try {
55
+ $template = $env->loadTemplate($name);
56
  } catch (Exception $e) {
57
  $env->setLoader($current);
58
 
Twig/lib/Twig/ExtensionInterface.php CHANGED
File without changes
Twig/lib/Twig/Filter.php CHANGED
File without changes
Twig/lib/Twig/Filter/Function.php CHANGED
File without changes
Twig/lib/Twig/Filter/Method.php CHANGED
File without changes
Twig/lib/Twig/Filter/Node.php CHANGED
File without changes
Twig/lib/Twig/FilterCallableInterface.php CHANGED
File without changes
Twig/lib/Twig/FilterInterface.php CHANGED
File without changes
Twig/lib/Twig/Function.php CHANGED
File without changes
Twig/lib/Twig/Function/Function.php CHANGED
File without changes
Twig/lib/Twig/Function/Method.php CHANGED
File without changes
Twig/lib/Twig/Function/Node.php CHANGED
File without changes
Twig/lib/Twig/FunctionCallableInterface.php CHANGED
File without changes
Twig/lib/Twig/FunctionInterface.php CHANGED
File without changes
Twig/lib/Twig/Lexer.php CHANGED
@@ -73,12 +73,7 @@ class Twig_Lexer implements Twig_LexerInterface
73
  }
74
 
75
  /**
76
- * Tokenizes a source code.
77
- *
78
- * @param string $code The source code
79
- * @param string $filename A unique identifier for the source code
80
- *
81
- * @return Twig_TokenStream A token stream instance
82
  */
83
  public function tokenize($code, $filename = null)
84
  {
@@ -233,7 +228,7 @@ class Twig_Lexer implements Twig_LexerInterface
233
 
234
  // operators
235
  if (preg_match($this->regexes['operator'], $this->code, $match, null, $this->cursor)) {
236
- $this->pushToken(Twig_Token::OPERATOR_TYPE, $match[0]);
237
  $this->moveCursor($match[0]);
238
  }
239
  // names
@@ -382,10 +377,15 @@ class Twig_Lexer implements Twig_LexerInterface
382
  // an operator that ends with a character must be followed by
383
  // a whitespace or a parenthesis
384
  if (ctype_alpha($operator[$length - 1])) {
385
- $regex[] = preg_quote($operator, '/').'(?=[\s()])';
386
  } else {
387
- $regex[] = preg_quote($operator, '/');
388
  }
 
 
 
 
 
389
  }
390
 
391
  return '/'.implode('|', $regex).'/A';
73
  }
74
 
75
  /**
76
+ * {@inheritdoc}
 
 
 
 
 
77
  */
78
  public function tokenize($code, $filename = null)
79
  {
228
 
229
  // operators
230
  if (preg_match($this->regexes['operator'], $this->code, $match, null, $this->cursor)) {
231
+ $this->pushToken(Twig_Token::OPERATOR_TYPE, preg_replace('/\s+/', ' ', $match[0]));
232
  $this->moveCursor($match[0]);
233
  }
234
  // names
377
  // an operator that ends with a character must be followed by
378
  // a whitespace or a parenthesis
379
  if (ctype_alpha($operator[$length - 1])) {
380
+ $r = preg_quote($operator, '/').'(?=[\s()])';
381
  } else {
382
+ $r = preg_quote($operator, '/');
383
  }
384
+
385
+ // an operator with a space can be any amount of whitespaces
386
+ $r = preg_replace('/\s+/', '\s+', $r);
387
+
388
+ $regex[] = $r;
389
  }
390
 
391
  return '/'.implode('|', $regex).'/A';
Twig/lib/Twig/LexerInterface.php CHANGED
@@ -24,6 +24,8 @@ interface Twig_LexerInterface
24
  * @param string $filename A unique identifier for the source code
25
  *
26
  * @return Twig_TokenStream A token stream instance
 
 
27
  */
28
  public function tokenize($code, $filename = null);
29
  }
24
  * @param string $filename A unique identifier for the source code
25
  *
26
  * @return Twig_TokenStream A token stream instance
27
+ *
28
+ * @throws Twig_Error_Syntax When the code is syntactically wrong
29
  */
30
  public function tokenize($code, $filename = null);
31
  }
Twig/lib/Twig/Loader/Array.php CHANGED
@@ -21,7 +21,7 @@
21
  */
22
  class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterface
23
  {
24
- protected $templates;
25
 
26
  /**
27
  * Constructor.
@@ -32,10 +32,7 @@ class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
32
  */
33
  public function __construct(array $templates)
34
  {
35
- $this->templates = array();
36
- foreach ($templates as $name => $template) {
37
- $this->templates[$name] = $template;
38
- }
39
  }
40
 
41
  /**
21
  */
22
  class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterface
23
  {
24
+ protected $templates = array();
25
 
26
  /**
27
  * Constructor.
32
  */
33
  public function __construct(array $templates)
34
  {
35
+ $this->templates = $templates;
 
 
 
36
  }
37
 
38
  /**
Twig/lib/Twig/Loader/Chain.php CHANGED
@@ -17,7 +17,7 @@
17
  class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterface
18
  {
19
  private $hasSourceCache = array();
20
- protected $loaders;
21
 
22
  /**
23
  * Constructor.
@@ -26,7 +26,6 @@ class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
26
  */
27
  public function __construct(array $loaders = array())
28
  {
29
- $this->loaders = array();
30
  foreach ($loaders as $loader) {
31
  $this->addLoader($loader);
32
  }
17
  class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterface
18
  {
19
  private $hasSourceCache = array();
20
+ protected $loaders = array();
21
 
22
  /**
23
  * Constructor.
26
  */
27
  public function __construct(array $loaders = array())
28
  {
 
29
  foreach ($loaders as $loader) {
30
  $this->addLoader($loader);
31
  }
Twig/lib/Twig/Loader/Filesystem.php CHANGED
@@ -16,8 +16,11 @@
16
  */
17
  class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderInterface
18
  {
19
- protected $paths;
20
- protected $cache;
 
 
 
21
 
22
  /**
23
  * Constructor.
@@ -38,7 +41,7 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
38
  *
39
  * @return array The array of paths where to look for templates
40
  */
41
- public function getPaths($namespace = '__main__')
42
  {
43
  return isset($this->paths[$namespace]) ? $this->paths[$namespace] : array();
44
  }
@@ -46,7 +49,7 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
46
  /**
47
  * Returns the path namespaces.
48
  *
49
- * The "__main__" namespace is always defined.
50
  *
51
  * @return array The array of defined namespaces
52
  */
@@ -61,7 +64,7 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
61
  * @param string|array $paths A path or an array of paths where to look for templates
62
  * @param string $namespace A path namespace
63
  */
64
- public function setPaths($paths, $namespace = '__main__')
65
  {
66
  if (!is_array($paths)) {
67
  $paths = array($paths);
@@ -81,7 +84,7 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
81
  *
82
  * @throws Twig_Error_Loader
83
  */
84
- public function addPath($path, $namespace = '__main__')
85
  {
86
  // invalidate the cache
87
  $this->cache = array();
@@ -101,7 +104,7 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
101
  *
102
  * @throws Twig_Error_Loader
103
  */
104
- public function prependPath($path, $namespace = '__main__')
105
  {
106
  // invalidate the cache
107
  $this->cache = array();
@@ -175,15 +178,15 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
175
 
176
  $this->validateName($name);
177
 
178
- $namespace = '__main__';
 
179
  if (isset($name[0]) && '@' == $name[0]) {
180
  if (false === $pos = strpos($name, '/')) {
181
  throw new Twig_Error_Loader(sprintf('Malformed namespaced template name "%s" (expecting "@namespace/template_name").', $name));
182
  }
183
 
184
  $namespace = substr($name, 1, $pos - 1);
185
-
186
- $name = substr($name, $pos + 1);
187
  }
188
 
189
  if (!isset($this->paths[$namespace])) {
@@ -191,8 +194,8 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
191
  }
192
 
193
  foreach ($this->paths[$namespace] as $path) {
194
- if (is_file($path.'/'.$name)) {
195
- return $this->cache[$name] = $path.'/'.$name;
196
  }
197
  }
198
 
16
  */
17
  class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderInterface
18
  {
19
+ /** Identifier of the main namespace. */
20
+ const MAIN_NAMESPACE = '__main__';
21
+
22
+ protected $paths = array();
23
+ protected $cache = array();
24
 
25
  /**
26
  * Constructor.
41
  *
42
  * @return array The array of paths where to look for templates
43
  */
44
+ public function getPaths($namespace = self::MAIN_NAMESPACE)
45
  {
46
  return isset($this->paths[$namespace]) ? $this->paths[$namespace] : array();
47
  }
49
  /**
50
  * Returns the path namespaces.
51
  *
52
+ * The main namespace is always defined.
53
  *
54
  * @return array The array of defined namespaces
55
  */
64
  * @param string|array $paths A path or an array of paths where to look for templates
65
  * @param string $namespace A path namespace
66
  */
67
+ public function setPaths($paths, $namespace = self::MAIN_NAMESPACE)
68
  {
69
  if (!is_array($paths)) {
70
  $paths = array($paths);
84
  *
85
  * @throws Twig_Error_Loader
86
  */
87
+ public function addPath($path, $namespace = self::MAIN_NAMESPACE)
88
  {
89
  // invalidate the cache
90
  $this->cache = array();
104
  *
105
  * @throws Twig_Error_Loader
106
  */
107
+ public function prependPath($path, $namespace = self::MAIN_NAMESPACE)
108
  {
109
  // invalidate the cache
110
  $this->cache = array();
178
 
179
  $this->validateName($name);
180
 
181
+ $namespace = self::MAIN_NAMESPACE;
182
+ $shortname = $name;
183
  if (isset($name[0]) && '@' == $name[0]) {
184
  if (false === $pos = strpos($name, '/')) {
185
  throw new Twig_Error_Loader(sprintf('Malformed namespaced template name "%s" (expecting "@namespace/template_name").', $name));
186
  }
187
 
188
  $namespace = substr($name, 1, $pos - 1);
189
+ $shortname = substr($name, $pos + 1);
 
190
  }
191
 
192
  if (!isset($this->paths[$namespace])) {
194
  }
195
 
196
  foreach ($this->paths[$namespace] as $path) {
197
+ if (is_file($path.'/'.$shortname)) {
198
+ return $this->cache[$name] = $path.'/'.$shortname;
199
  }
200
  }
201
 
Twig/lib/Twig/Loader/String.php CHANGED
File without changes
Twig/lib/Twig/LoaderInterface.php CHANGED
File without changes
Twig/lib/Twig/Markup.php CHANGED
File without changes
Twig/lib/Twig/Node.php CHANGED
File without changes
Twig/lib/Twig/Node/AutoEscape.php CHANGED
File without changes
Twig/lib/Twig/Node/Block.php CHANGED
File without changes
Twig/lib/Twig/Node/BlockReference.php CHANGED
File without changes
Twig/lib/Twig/Node/Body.php CHANGED
File without changes
Twig/lib/Twig/Node/Do.php CHANGED
File without changes
Twig/lib/Twig/Node/Embed.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Array.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/AssignName.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Binary.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Binary/Add.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Binary/And.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Binary/BitwiseAnd.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Binary/BitwiseOr.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Binary/BitwiseXor.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Binary/Concat.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Binary/Div.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Binary/EndsWith.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Twig.
5
+ *
6
+ * (c) 2013 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
+ class Twig_Node_Expression_Binary_EndsWith extends Twig_Node_Expression_Binary
12
+ {
13
+ public function compile(Twig_Compiler $compiler)
14
+ {
15
+ $compiler
16
+ ->raw('(0 === substr_compare(')
17
+ ->subcompile($this->getNode('left'))
18
+ ->raw(', ')
19
+ ->subcompile($this->getNode('right'))
20
+ ->raw(', -strlen(')
21
+ ->subcompile($this->getNode('right'))
22
+ ->raw(')))')
23
+ ;
24
+ }
25
+
26
+ public function operator(Twig_Compiler $compiler)
27
+ {
28
+ return $compiler->raw('');
29
+ }
30
+ }
Twig/lib/Twig/Node/Expression/Binary/Equal.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Binary/FloorDiv.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Binary/Greater.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Binary/GreaterEqual.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Binary/In.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Binary/Less.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Binary/LessEqual.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Binary/Matches.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Twig.
5
+ *
6
+ * (c) 2013 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
+ class Twig_Node_Expression_Binary_Matches extends Twig_Node_Expression_Binary
12
+ {
13
+ public function compile(Twig_Compiler $compiler)
14
+ {
15
+ $compiler
16
+ ->raw('preg_match(')
17
+ ->subcompile($this->getNode('right'))
18
+ ->raw(', ')
19
+ ->subcompile($this->getNode('left'))
20
+ ->raw(')')
21
+ ;
22
+ }
23
+
24
+ public function operator(Twig_Compiler $compiler)
25
+ {
26
+ return $compiler->raw('');
27
+ }
28
+ }
Twig/lib/Twig/Node/Expression/Binary/Mod.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Binary/Mul.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Binary/NotEqual.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Binary/NotIn.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Binary/Or.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Binary/Power.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Binary/Range.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Binary/StartsWith.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Twig.
5
+ *
6
+ * (c) 2013 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
+ class Twig_Node_Expression_Binary_StartsWith extends Twig_Node_Expression_Binary
12
+ {
13
+ public function compile(Twig_Compiler $compiler)
14
+ {
15
+ $compiler
16
+ ->raw('(0 === strpos(')
17
+ ->subcompile($this->getNode('left'))
18
+ ->raw(', ')
19
+ ->subcompile($this->getNode('right'))
20
+ ->raw('))')
21
+ ;
22
+ }
23
+
24
+ public function operator(Twig_Compiler $compiler)
25
+ {
26
+ return $compiler->raw('');
27
+ }
28
+ }
Twig/lib/Twig/Node/Expression/Binary/Sub.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/BlockReference.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Call.php CHANGED
@@ -146,7 +146,7 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
146
 
147
  if (array_key_exists($name, $parameters)) {
148
  if (array_key_exists($pos, $parameters)) {
149
- throw new Twig_Error_Syntax(sprintf('Arguments "%s" is defined twice for %s "%s".', $name, $this->getAttribute('type'), $this->getAttribute('name')));
150
  }
151
 
152
  $arguments[] = $parameters[$name];
@@ -164,8 +164,8 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
164
  }
165
  }
166
 
167
- foreach (array_keys($parameters) as $name) {
168
- throw new Twig_Error_Syntax(sprintf('Unknown argument "%s" for %s "%s".', $name, $this->getAttribute('type'), $this->getAttribute('name')));
169
  }
170
 
171
  return $arguments;
146
 
147
  if (array_key_exists($name, $parameters)) {
148
  if (array_key_exists($pos, $parameters)) {
149
+ throw new Twig_Error_Syntax(sprintf('Argument "%s" is defined twice for %s "%s".', $name, $this->getAttribute('type'), $this->getAttribute('name')));
150
  }
151
 
152
  $arguments[] = $parameters[$name];
164
  }
165
  }
166
 
167
+ if (!empty($parameters)) {
168
+ throw new Twig_Error_Syntax(sprintf('Unknown argument%s "%s" for %s "%s".', count($parameters) > 1 ? 's' : '' , implode('", "', array_keys($parameters)), $this->getAttribute('type'), $this->getAttribute('name')));
169
  }
170
 
171
  return $arguments;
Twig/lib/Twig/Node/Expression/Conditional.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Constant.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/ExtensionReference.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Filter.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Filter/Default.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Function.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/GetAttr.php CHANGED
@@ -32,10 +32,10 @@ class Twig_Node_Expression_GetAttr extends Twig_Node_Expression
32
 
33
  $compiler->raw(', ')->subcompile($this->getNode('attribute'));
34
 
35
- if (count($this->getNode('arguments')) || Twig_TemplateInterface::ANY_CALL !== $this->getAttribute('type') || $this->getAttribute('is_defined_test') || $this->getAttribute('ignore_strict_check')) {
36
  $compiler->raw(', ')->subcompile($this->getNode('arguments'));
37
 
38
- if (Twig_TemplateInterface::ANY_CALL !== $this->getAttribute('type') || $this->getAttribute('is_defined_test') || $this->getAttribute('ignore_strict_check')) {
39
  $compiler->raw(', ')->repr($this->getAttribute('type'));
40
  }
41
 
32
 
33
  $compiler->raw(', ')->subcompile($this->getNode('attribute'));
34
 
35
+ if (count($this->getNode('arguments')) || Twig_Template::ANY_CALL !== $this->getAttribute('type') || $this->getAttribute('is_defined_test') || $this->getAttribute('ignore_strict_check')) {
36
  $compiler->raw(', ')->subcompile($this->getNode('arguments'));
37
 
38
+ if (Twig_Template::ANY_CALL !== $this->getAttribute('type') || $this->getAttribute('is_defined_test') || $this->getAttribute('ignore_strict_check')) {
39
  $compiler->raw(', ')->repr($this->getAttribute('type'));
40
  }
41
 
Twig/lib/Twig/Node/Expression/MethodCall.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Name.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Parent.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/TempName.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Test.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Test/Constant.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Test/Defined.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Test/Divisibleby.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Test/Even.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Test/Null.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Test/Odd.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Test/Sameas.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Unary.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Unary/Neg.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Unary/Not.php CHANGED
File without changes
Twig/lib/Twig/Node/Expression/Unary/Pos.php CHANGED
File without changes
Twig/lib/Twig/Node/Flush.php CHANGED
File without changes
Twig/lib/Twig/Node/For.php CHANGED
File without changes
Twig/lib/Twig/Node/ForLoop.php CHANGED
File without changes
Twig/lib/Twig/Node/If.php CHANGED
@@ -30,7 +30,7 @@ class Twig_Node_If extends Twig_Node
30
  public function compile(Twig_Compiler $compiler)
31
  {
32
  $compiler->addDebugInfo($this);
33
- for ($i = 0; $i < count($this->getNode('tests')); $i += 2) {
34
  if ($i > 0) {
35
  $compiler
36
  ->outdent()
30
  public function compile(Twig_Compiler $compiler)
31
  {
32
  $compiler->addDebugInfo($this);
33
+ for ($i = 0, $count = count($this->getNode('tests')); $i < $count; $i += 2) {
34
  if ($i > 0) {
35
  $compiler
36
  ->outdent()
Twig/lib/Twig/Node/Import.php CHANGED
File without changes
Twig/lib/Twig/Node/Include.php CHANGED
File without changes
Twig/lib/Twig/Node/Macro.php CHANGED
File without changes
Twig/lib/Twig/Node/Module.php CHANGED
File without changes
Twig/lib/Twig/Node/Print.php CHANGED
File without changes
Twig/lib/Twig/Node/Sandbox.php CHANGED
File without changes
Twig/lib/Twig/Node/SandboxedModule.php CHANGED
File without changes
Twig/lib/Twig/Node/SandboxedPrint.php CHANGED
File without changes
Twig/lib/Twig/Node/Set.php CHANGED
File without changes
Twig/lib/Twig/Node/SetTemp.php CHANGED
File without changes
Twig/lib/Twig/Node/Spaceless.php CHANGED
File without changes
Twig/lib/Twig/Node/Text.php CHANGED
File without changes
Twig/lib/Twig/NodeInterface.php CHANGED
File without changes
Twig/lib/Twig/NodeOutputInterface.php CHANGED
File without changes
Twig/lib/Twig/NodeTraverser.php CHANGED
File without changes
Twig/lib/Twig/NodeVisitor/Escaper.php CHANGED
File without changes
Twig/lib/Twig/NodeVisitor/Optimizer.php CHANGED
@@ -108,7 +108,7 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface
108
  return $node;
109
  }
110
 
111
- protected function optimizeVariables($node, $env)
112
  {
113
  if ('Twig_Node_Expression_Name' === get_class($node) && $node->isSimple()) {
114
  $this->prependedNodes[0][] = $node->getAttribute('name');
@@ -129,7 +129,7 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface
129
  * @param Twig_NodeInterface $node A Node
130
  * @param Twig_Environment $env The current Twig environment
131
  */
132
- protected function optimizePrintNode($node, $env)
133
  {
134
  if (!$node instanceof Twig_Node_Print) {
135
  return $node;
@@ -153,7 +153,7 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface
153
  * @param Twig_NodeInterface $node A Node
154
  * @param Twig_Environment $env The current Twig environment
155
  */
156
- protected function optimizeRawFilter($node, $env)
157
  {
158
  if ($node instanceof Twig_Node_Expression_Filter && 'raw' == $node->getNode('filter')->getAttribute('value')) {
159
  return $node->getNode('node');
@@ -168,7 +168,7 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface
168
  * @param Twig_NodeInterface $node A Node
169
  * @param Twig_Environment $env The current Twig environment
170
  */
171
- protected function enterOptimizeFor($node, $env)
172
  {
173
  if ($node instanceof Twig_Node_For) {
174
  // disable the loop variable by default
@@ -217,7 +217,7 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface
217
  * @param Twig_NodeInterface $node A Node
218
  * @param Twig_Environment $env The current Twig environment
219
  */
220
- protected function leaveOptimizeFor($node, $env)
221
  {
222
  if ($node instanceof Twig_Node_For) {
223
  array_shift($this->loops);
108
  return $node;
109
  }
110
 
111
+ protected function optimizeVariables(Twig_NodeInterface $node, Twig_Environment $env)
112
  {
113
  if ('Twig_Node_Expression_Name' === get_class($node) && $node->isSimple()) {
114
  $this->prependedNodes[0][] = $node->getAttribute('name');
129
  * @param Twig_NodeInterface $node A Node
130
  * @param Twig_Environment $env The current Twig environment
131
  */
132
+ protected function optimizePrintNode(Twig_NodeInterface $node, Twig_Environment $env)
133
  {
134
  if (!$node instanceof Twig_Node_Print) {
135
  return $node;
153
  * @param Twig_NodeInterface $node A Node
154
  * @param Twig_Environment $env The current Twig environment
155
  */
156
+ protected function optimizeRawFilter(Twig_NodeInterface $node, Twig_Environment $env)
157
  {
158
  if ($node instanceof Twig_Node_Expression_Filter && 'raw' == $node->getNode('filter')->getAttribute('value')) {
159
  return $node->getNode('node');
168
  * @param Twig_NodeInterface $node A Node
169
  * @param Twig_Environment $env The current Twig environment
170
  */
171
+ protected function enterOptimizeFor(Twig_NodeInterface $node, Twig_Environment $env)
172
  {
173
  if ($node instanceof Twig_Node_For) {
174
  // disable the loop variable by default
217
  * @param Twig_NodeInterface $node A Node
218
  * @param Twig_Environment $env The current Twig environment
219
  */
220
+ protected function leaveOptimizeFor(Twig_NodeInterface $node, Twig_Environment $env)
221
  {
222
  if ($node instanceof Twig_Node_For) {
223
  array_shift($this->loops);
Twig/lib/Twig/NodeVisitor/SafeAnalysis.php CHANGED
@@ -13,12 +13,20 @@ class Twig_NodeVisitor_SafeAnalysis implements Twig_NodeVisitorInterface
13
  public function getSafe(Twig_NodeInterface $node)
14
  {
15
  $hash = spl_object_hash($node);
16
- if (isset($this->data[$hash])) {
17
- foreach ($this->data[$hash] as $bucket) {
18
- if ($bucket['key'] === $node) {
19
- return $bucket['value'];
20
- }
 
 
 
 
 
 
21
  }
 
 
22
  }
23
  }
24
 
13
  public function getSafe(Twig_NodeInterface $node)
14
  {
15
  $hash = spl_object_hash($node);
16
+ if (!isset($this->data[$hash])) {
17
+ return;
18
+ }
19
+
20
+ foreach ($this->data[$hash] as $bucket) {
21
+ if ($bucket['key'] !== $node) {
22
+ continue;
23
+ }
24
+
25
+ if (in_array('html_attr', $bucket['value'])) {
26
+ $bucket['value'][] = 'html';
27
  }
28
+
29
+ return $bucket['value'];
30
  }
31
  }
32
 
Twig/lib/Twig/NodeVisitor/Sandbox.php CHANGED
File without changes
Twig/lib/Twig/NodeVisitorInterface.php CHANGED
File without changes
Twig/lib/Twig/Parser.php CHANGED
@@ -49,7 +49,7 @@ class Twig_Parser implements Twig_ParserInterface
49
 
50
  public function getVarName()
51
  {
52
- return sprintf('__internal_%s', hash('sha1', uniqid(mt_rand(), true), false));
53
  }
54
 
55
  public function getFilename()
@@ -58,11 +58,7 @@ class Twig_Parser implements Twig_ParserInterface
58
  }
59
 
60
  /**
61
- * Converts a token stream to a node tree.
62
- *
63
- * @param Twig_TokenStream $stream A token stream instance
64
- *
65
- * @return Twig_Node_Module A node tree
66
  */
67
  public function parse(Twig_TokenStream $stream, $test = null, $dropNeedle = false)
68
  {
@@ -246,7 +242,7 @@ class Twig_Parser implements Twig_ParserInterface
246
  return $this->blocks[$name];
247
  }
248
 
249
- public function setBlock($name, $value)
250
  {
251
  $this->blocks[$name] = new Twig_Node_Body(array($value), array(), $value->getLine());
252
  }
49
 
50
  public function getVarName()
51
  {
52
+ return sprintf('__internal_%s', hash('sha256', uniqid(mt_rand(), true), false));
53
  }
54
 
55
  public function getFilename()
58
  }
59
 
60
  /**
61
+ * {@inheritdoc}
 
 
 
 
62
  */
63
  public function parse(Twig_TokenStream $stream, $test = null, $dropNeedle = false)
64
  {
242
  return $this->blocks[$name];
243
  }
244
 
245
+ public function setBlock($name, Twig_Node_Block $value)
246
  {
247
  $this->blocks[$name] = new Twig_Node_Body(array($value), array(), $value->getLine());
248
  }
Twig/lib/Twig/ParserInterface.php CHANGED
@@ -23,6 +23,8 @@ interface Twig_ParserInterface
23
  * @param Twig_TokenStream $stream A token stream instance
24
  *
25
  * @return Twig_Node_Module A node tree
 
 
26
  */
27
  public function parse(Twig_TokenStream $stream);
28
  }
23
  * @param Twig_TokenStream $stream A token stream instance
24
  *
25
  * @return Twig_Node_Module A node tree
26
+ *
27
+ * @throws Twig_Error_Syntax When the token stream is syntactically or semantically wrong
28
  */
29
  public function parse(Twig_TokenStream $stream);
30
  }
Twig/lib/Twig/Sandbox/SecurityError.php CHANGED
File without changes
Twig/lib/Twig/Sandbox/SecurityPolicy.php CHANGED
File without changes
Twig/lib/Twig/Sandbox/SecurityPolicyInterface.php CHANGED
File without changes
Twig/lib/Twig/SimpleFilter.php CHANGED
File without changes
Twig/lib/Twig/SimpleFunction.php CHANGED
File without changes
Twig/lib/Twig/SimpleTest.php CHANGED
File without changes
Twig/lib/Twig/Template.php CHANGED
@@ -127,12 +127,24 @@ abstract class Twig_Template implements Twig_TemplateInterface
127
  {
128
  $name = (string) $name;
129
 
 
130
  if (isset($blocks[$name])) {
131
- $b = $blocks;
132
- unset($b[$name]);
133
- call_user_func($blocks[$name], $context, $b);
134
  } elseif (isset($this->blocks[$name])) {
135
- call_user_func($this->blocks[$name], $context, $blocks);
 
 
 
 
 
 
 
 
 
 
 
136
  } elseif (false !== $parent = $this->getParent($context)) {
137
  $parent->displayBlock($name, $context, array_merge($this->blocks, $blocks));
138
  }
@@ -276,7 +288,7 @@ abstract class Twig_Template implements Twig_TemplateInterface
276
 
277
  throw $e;
278
  } catch (Exception $e) {
279
- throw new Twig_Error_Runtime(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, null, $e);
280
  }
281
  }
282
 
@@ -326,7 +338,7 @@ abstract class Twig_Template implements Twig_TemplateInterface
326
  * @param mixed $object The object or array from where to get the item
327
  * @param mixed $item The item to get from the array or object
328
  * @param array $arguments An array of arguments to pass if the item is an object method
329
- * @param string $type The type of attribute (@see Twig_TemplateInterface)
330
  * @param Boolean $isDefinedTest Whether this is only a defined check
331
  * @param Boolean $ignoreStrictCheck Whether to ignore the strict attribute check or not
332
  *
@@ -334,10 +346,10 @@ abstract class Twig_Template implements Twig_TemplateInterface
334
  *
335
  * @throws Twig_Error_Runtime if the attribute does not exist and Twig is running in strict mode and $isDefinedTest is false
336
  */
337
- protected function getAttribute($object, $item, array $arguments = array(), $type = Twig_TemplateInterface::ANY_CALL, $isDefinedTest = false, $ignoreStrictCheck = false)
338
  {
339
  // array
340
- if (Twig_TemplateInterface::METHOD_CALL !== $type) {
341
  $arrayItem = is_bool($item) || is_float($item) ? (int) $item : $item;
342
 
343
  if ((is_array($object) && array_key_exists($arrayItem, $object))
@@ -350,7 +362,7 @@ abstract class Twig_Template implements Twig_TemplateInterface
350
  return $object[$arrayItem];
351
  }
352
 
353
- if (Twig_TemplateInterface::ARRAY_CALL === $type || !is_object($object)) {
354
  if ($isDefinedTest) {
355
  return false;
356
  }
@@ -363,7 +375,7 @@ abstract class Twig_Template implements Twig_TemplateInterface
363
  throw new Twig_Error_Runtime(sprintf('Key "%s" in object (with ArrayAccess) of type "%s" does not exist', $arrayItem, get_class($object)), -1, $this->getTemplateName());
364
  } elseif (is_array($object)) {
365
  throw new Twig_Error_Runtime(sprintf('Key "%s" for array with keys "%s" does not exist', $arrayItem, implode(', ', array_keys($object))), -1, $this->getTemplateName());
366
- } elseif (Twig_TemplateInterface::ARRAY_CALL === $type) {
367
  throw new Twig_Error_Runtime(sprintf('Impossible to access a key ("%s") on a %s variable ("%s")', $item, gettype($object), $object), -1, $this->getTemplateName());
368
  } else {
369
  throw new Twig_Error_Runtime(sprintf('Impossible to access an attribute ("%s") on a %s variable ("%s")', $item, gettype($object), $object), -1, $this->getTemplateName());
@@ -386,7 +398,7 @@ abstract class Twig_Template implements Twig_TemplateInterface
386
  $class = get_class($object);
387
 
388
  // object property
389
- if (Twig_TemplateInterface::METHOD_CALL !== $type) {
390
  if (isset($object->$item) || array_key_exists((string) $item, $object)) {
391
  if ($isDefinedTest) {
392
  return true;
127
  {
128
  $name = (string) $name;
129
 
130
+ $template = null;
131
  if (isset($blocks[$name])) {
132
+ $template = $blocks[$name][0];
133
+ $block = $blocks[$name][1];
134
+ unset($blocks[$name]);
135
  } elseif (isset($this->blocks[$name])) {
136
+ $template = $this->blocks[$name][0];
137
+ $block = $this->blocks[$name][1];
138
+ }
139
+
140
+ if (null !== $template) {
141
+ try {
142
+ $template->$block($context, $blocks);
143
+ } catch (Twig_Error $e) {
144
+ throw $e;
145
+ } catch (Exception $e) {
146
+ throw new Twig_Error_Runtime(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $template->getTemplateName(), $e);
147
+ }
148
  } elseif (false !== $parent = $this->getParent($context)) {
149
  $parent->displayBlock($name, $context, array_merge($this->blocks, $blocks));
150
  }
288
 
289
  throw $e;
290
  } catch (Exception $e) {
291
+ throw new Twig_Error_Runtime(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $this->getTemplateName(), $e);
292
  }
293
  }
294
 
338
  * @param mixed $object The object or array from where to get the item
339
  * @param mixed $item The item to get from the array or object
340
  * @param array $arguments An array of arguments to pass if the item is an object method
341
+ * @param string $type The type of attribute (@see Twig_Template constants)
342
  * @param Boolean $isDefinedTest Whether this is only a defined check
343
  * @param Boolean $ignoreStrictCheck Whether to ignore the strict attribute check or not
344
  *
346
  *
347
  * @throws Twig_Error_Runtime if the attribute does not exist and Twig is running in strict mode and $isDefinedTest is false
348
  */
349
+ protected function getAttribute($object, $item, array $arguments = array(), $type = Twig_Template::ANY_CALL, $isDefinedTest = false, $ignoreStrictCheck = false)
350
  {
351
  // array
352
+ if (Twig_Template::METHOD_CALL !== $type) {
353
  $arrayItem = is_bool($item) || is_float($item) ? (int) $item : $item;
354
 
355
  if ((is_array($object) && array_key_exists($arrayItem, $object))
362
  return $object[$arrayItem];
363
  }
364
 
365
+ if (Twig_Template::ARRAY_CALL === $type || !is_object($object)) {
366
  if ($isDefinedTest) {
367
  return false;
368
  }
375
  throw new Twig_Error_Runtime(sprintf('Key "%s" in object (with ArrayAccess) of type "%s" does not exist', $arrayItem, get_class($object)), -1, $this->getTemplateName());
376
  } elseif (is_array($object)) {
377
  throw new Twig_Error_Runtime(sprintf('Key "%s" for array with keys "%s" does not exist', $arrayItem, implode(', ', array_keys($object))), -1, $this->getTemplateName());
378
+ } elseif (Twig_Template::ARRAY_CALL === $type) {
379
  throw new Twig_Error_Runtime(sprintf('Impossible to access a key ("%s") on a %s variable ("%s")', $item, gettype($object), $object), -1, $this->getTemplateName());
380
  } else {
381
  throw new Twig_Error_Runtime(sprintf('Impossible to access an attribute ("%s") on a %s variable ("%s")', $item, gettype($object), $object), -1, $this->getTemplateName());
398
  $class = get_class($object);
399
 
400
  // object property
401
+ if (Twig_Template::METHOD_CALL !== $type) {
402
  if (isset($object->$item) || array_key_exists((string) $item, $object)) {
403
  if ($isDefinedTest) {
404
  return true;
Twig/lib/Twig/TemplateInterface.php CHANGED
File without changes
Twig/lib/Twig/Test.php CHANGED
File without changes
Twig/lib/Twig/Test/Function.php CHANGED
File without changes
Twig/lib/Twig/Test/IntegrationTestCase.php CHANGED
File without changes
Twig/lib/Twig/Test/Method.php CHANGED
File without changes
Twig/lib/Twig/Test/Node.php CHANGED
File without changes
Twig/lib/Twig/Test/NodeTestCase.php CHANGED
File without changes
Twig/lib/Twig/TestCallableInterface.php CHANGED
File without changes
Twig/lib/Twig/TestInterface.php CHANGED
File without changes
Twig/lib/Twig/Token.php CHANGED
@@ -121,11 +121,10 @@ class Twig_Token
121
  *
122
  * @param integer $type The type as an integer
123
  * @param Boolean $short Whether to return a short representation or not
124
- * @param integer $line The code line
125
  *
126
  * @return string The string representation
127
  */
128
- public static function typeToString($type, $short = false, $line = -1)
129
  {
130
  switch ($type) {
131
  case self::EOF_TYPE:
@@ -178,11 +177,10 @@ class Twig_Token
178
  * Returns the english representation of a given type.
179
  *
180
  * @param integer $type The type as an integer
181
- * @param integer $line The code line
182
  *
183
  * @return string The string representation
184
  */
185
- public static function typeToEnglish($type, $line = -1)
186
  {
187
  switch ($type) {
188
  case self::EOF_TYPE:
121
  *
122
  * @param integer $type The type as an integer
123
  * @param Boolean $short Whether to return a short representation or not
 
124
  *
125
  * @return string The string representation
126
  */
127
+ public static function typeToString($type, $short = false)
128
  {
129
  switch ($type) {
130
  case self::EOF_TYPE:
177
  * Returns the english representation of a given type.
178
  *
179
  * @param integer $type The type as an integer
 
180
  *
181
  * @return string The string representation
182
  */
183
+ public static function typeToEnglish($type)
184
  {
185
  switch ($type) {
186
  case self::EOF_TYPE:
Twig/lib/Twig/TokenParser.php CHANGED
File without changes
Twig/lib/Twig/TokenParser/AutoEscape.php CHANGED
File without changes
Twig/lib/Twig/TokenParser/Block.php CHANGED
File without changes
Twig/lib/Twig/TokenParser/Do.php CHANGED
File without changes
Twig/lib/Twig/TokenParser/Embed.php CHANGED
File without changes
Twig/lib/Twig/TokenParser/Extends.php CHANGED
File without changes
Twig/lib/Twig/TokenParser/Filter.php CHANGED
File without changes
Twig/lib/Twig/TokenParser/Flush.php CHANGED
File without changes
Twig/lib/Twig/TokenParser/For.php CHANGED
File without changes
Twig/lib/Twig/TokenParser/From.php CHANGED
File without changes
Twig/lib/Twig/TokenParser/If.php CHANGED
File without changes
Twig/lib/Twig/TokenParser/Import.php CHANGED
File without changes
Twig/lib/Twig/TokenParser/Include.php CHANGED
File without changes
Twig/lib/Twig/TokenParser/Macro.php CHANGED
File without changes
Twig/lib/Twig/TokenParser/Sandbox.php CHANGED
File without changes
Twig/lib/Twig/TokenParser/Set.php CHANGED
File without changes
Twig/lib/Twig/TokenParser/Spaceless.php CHANGED
File without changes
Twig/lib/Twig/TokenParser/Use.php CHANGED
File without changes
Twig/lib/Twig/TokenParserBroker.php CHANGED
File without changes
Twig/lib/Twig/TokenParserBrokerInterface.php CHANGED
File without changes
Twig/lib/Twig/TokenParserInterface.php CHANGED
@@ -29,6 +29,8 @@ interface Twig_TokenParserInterface
29
  * @param Twig_Token $token A Twig_Token instance
30
  *
31
  * @return Twig_NodeInterface A Twig_NodeInterface instance
 
 
32
  */
33
  public function parse(Twig_Token $token);
34
 
29
  * @param Twig_Token $token A Twig_Token instance
30
  *
31
  * @return Twig_NodeInterface A Twig_NodeInterface instance
32
+ *
33
+ * @throws Twig_Error_Syntax
34
  */
35
  public function parse(Twig_Token $token);
36
 
Twig/lib/Twig/TokenStream.php CHANGED
File without changes
functions/functions-twig.php CHANGED
@@ -36,6 +36,9 @@ class TimberTwig {
36
  $twig->addFilter('twitterfy', new Twig_Filter_Function(array('TimberHelper', 'twitterify')));
37
  $twig->addFilter('wp_body_class', new Twig_Filter_Function('twig_body_class'));
38
  $twig->addFilter('wpautop', new Twig_Filter_Function('wpautop'));
 
 
 
39
 
40
  /* actions and filters */
41
  $twig->addFunction(new Twig_SimpleFunction('action', function(){
@@ -51,32 +54,32 @@ class TimberTwig {
51
  $twig->addFunction(new Twig_SimpleFunction('fn', array(&$this, 'exec_function')));
52
 
53
  /* TimberObjects */
54
- $twig->addFunction(new Twig_SimpleFunction('TimberPost', function($pid){
55
- if (is_array($pid)){
56
  foreach($pid as &$p){
57
- $p = new TimberPost($p);
58
  }
59
  return $pid;
60
  }
61
- return new TimberPost($pid);
62
  }));
63
- $twig->addFunction(new Twig_SimpleFunction('TimberImage', function($pid){
64
- if (is_array($pid)){
65
  foreach($pid as &$p){
66
- $p = new TimberImage($p);
67
  }
68
  return $pid;
69
  }
70
- return new TimberImage($pid);
71
  }));
72
- $twig->addFunction(new Twig_SimpleFunction('TimberTerm', function($pid){
73
- if (is_array($pid)){
74
  foreach($pid as &$p){
75
- $p = new TimberTerm($p);
76
  }
77
  return $pid;
78
  }
79
- return new TimberTerm($pid);
80
  }));
81
 
82
  /* bloginfo and translate */
@@ -151,8 +154,8 @@ function wp_resize_letterbox($src, $w, $h, $color = '#000000') {
151
  //$old_file = TimberHelper::get_full_path($src);
152
  $urlinfo = parse_url($src);
153
  $old_file = ABSPATH.$urlinfo['path'];
154
- $new_file = TimberHelper::get_letterbox_file_path($urlinfo['path'], $w, $h);
155
- $new_file_rel = TimberHelper::get_letterbox_file_rel($urlinfo['path'], $w, $h);
156
  $new_file_boxed = str_replace('-lb-', '-lbox-', $new_file);
157
  if (file_exists($new_file_boxed)) {
158
  $new_file_rel = str_replace('-lb-', '-lbox-', $new_file_rel);
36
  $twig->addFilter('twitterfy', new Twig_Filter_Function(array('TimberHelper', 'twitterify')));
37
  $twig->addFilter('wp_body_class', new Twig_Filter_Function('twig_body_class'));
38
  $twig->addFilter('wpautop', new Twig_Filter_Function('wpautop'));
39
+ $twig->addFilter('relative', new Twig_Filter_Function(function($link){
40
+ return TimberHelper::get_rel_url($link, true);
41
+ }));
42
 
43
  /* actions and filters */
44
  $twig->addFunction(new Twig_SimpleFunction('action', function(){
54
  $twig->addFunction(new Twig_SimpleFunction('fn', array(&$this, 'exec_function')));
55
 
56
  /* TimberObjects */
57
+ $twig->addFunction(new Twig_SimpleFunction('TimberPost', function($pid, $PostClass = 'TimberPost'){
58
+ if (is_array($pid) && !TimberHelper::is_array_assoc($pid)){
59
  foreach($pid as &$p){
60
+ $p = new $PostClass($p);
61
  }
62
  return $pid;
63
  }
64
+ return new $PostClass($pid);
65
  }));
66
+ $twig->addFunction(new Twig_SimpleFunction('TimberImage', function($pid, $ImageClass = 'TimberImage'){
67
+ if (is_array($pid) && !TimberHelper::is_array_assoc($pid)){
68
  foreach($pid as &$p){
69
+ $p = new $ImageClass($p);
70
  }
71
  return $pid;
72
  }
73
+ return new $ImageClass($pid);
74
  }));
75
+ $twig->addFunction(new Twig_SimpleFunction('TimberTerm', function($pid, $TermClass = 'TimberTerm'){
76
+ if (is_array($pid) && !TimberHelper::is_array_assoc($pid)){
77
  foreach($pid as &$p){
78
+ $p = new $TermClass($p);
79
  }
80
  return $pid;
81
  }
82
+ return new $TermClass($pid);
83
  }));
84
 
85
  /* bloginfo and translate */
154
  //$old_file = TimberHelper::get_full_path($src);
155
  $urlinfo = parse_url($src);
156
  $old_file = ABSPATH.$urlinfo['path'];
157
+ $new_file = TimberImageHelper::get_letterbox_file_path($urlinfo['path'], $w, $h);
158
+ $new_file_rel = TimberImageHelper::get_letterbox_file_rel($urlinfo['path'], $w, $h);
159
  $new_file_boxed = str_replace('-lb-', '-lbox-', $new_file);
160
  if (file_exists($new_file_boxed)) {
161
  $new_file_rel = str_replace('-lb-', '-lbox-', $new_file_rel);
functions/integrations/acf-timber.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class ACFTimber {
3
+
4
+ function __construct(){
5
+ add_filter('timber_post_get_meta', array($this, 'post_get_meta'), 10, 2);
6
+ add_filter('timber_post_get_meta_field', array($this, 'post_get_meta_field'), 10, 3);
7
+ add_filter('timber_term_get_meta', array($this, 'term_get_meta'), 10, 3);
8
+ add_filter('timber_term_get_meta_field', array($this, 'term_get_meta_field'), 10, 3);
9
+ add_filter('timber_user_get_meta_field_pre', array($this, 'user_get_meta_field'), 10, 3);
10
+ }
11
+
12
+ function post_get_meta($customs, $post_id){
13
+ return $customs;
14
+ }
15
+
16
+ function post_get_meta_field($value, $post_id, $field_name){
17
+ return get_field($field_name, $post_id);
18
+ }
19
+
20
+ function term_get_meta_field($value, $field_name, $term){
21
+ $searcher = $term->taxonomy . "_" . $term->ID . "_" .$field_name;
22
+ $field = get_field($searcher, $term->ID);
23
+ return $field;
24
+ }
25
+
26
+ function term_get_meta($fields, $term_id, $term){
27
+ $searcher = $term->taxonomy . "_" . $term->ID; // save to a specific category
28
+ $fds = get_fields($searcher);
29
+ if (is_array($fds)) {
30
+ foreach ($fds as $key => $value) {
31
+ $key = preg_replace('/_/', '', $key, 1);
32
+ $key = str_replace($searcher, '', $key);
33
+ $key = preg_replace('/_/', '', $key, 1);
34
+ $field = get_field($key, $searcher);
35
+ $fields[$key] = $field;
36
+ }
37
+ $fields = array_merge($fields, $fds);
38
+ }
39
+ return $fields;
40
+ }
41
+
42
+ function user_get_meta($fields, $user_id){
43
+ return $fields;
44
+ }
45
+
46
+ function user_get_meta_field($value, $field, $uid){
47
+ return get_field($field, 'user_'.$uid);
48
+ }
49
+ }
50
+ add_action( 'plugins_loaded', function(){
51
+ if (class_exists('ACF')){
52
+ new ACFTimber();
53
+ }
54
+ });
55
+
functions/timber-comment.php CHANGED
@@ -10,7 +10,18 @@ class TimberComment extends TimberCore {
10
  $this->init($cid);
11
  }
12
 
13
- function author() {
 
 
 
 
 
 
 
 
 
 
 
14
  if ($this->user_id) {
15
  return new TimberUser($this->user_id);
16
  } else {
@@ -24,21 +35,127 @@ class TimberComment extends TimberCore {
24
  return $author;
25
  }
26
 
27
- function date() {
28
- return $this->comment_date;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  }
30
 
31
- function content() {
32
  return $this->comment_content;
33
  }
34
 
35
- function init($cid) {
36
- $comment_data = $cid;
37
- if (is_integer($cid)) {
38
- $comment_data = get_comment($cid);
 
 
 
 
 
 
 
39
  }
40
- $this->import($comment_data);
41
- $this->ID = $this->comment_ID;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  }
43
 
44
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  $this->init($cid);
11
  }
12
 
13
+ function init($cid) {
14
+ $comment_data = $cid;
15
+ if (is_integer($cid)) {
16
+ $comment_data = get_comment($cid);
17
+ }
18
+ $this->import($comment_data);
19
+ $this->ID = $this->comment_ID;
20
+ $comment_meta_data = $this->get_meta_fields($this->ID);
21
+ $this->import($comment_meta_data);
22
+ }
23
+
24
+ public function author() {
25
  if ($this->user_id) {
26
  return new TimberUser($this->user_id);
27
  } else {
35
  return $author;
36
  }
37
 
38
+ public function avatar($size=92, $default=''){
39
+ // Fetches the Gravatar
40
+ // use it like this
41
+ // {{comment.avatar(36,template_uri~"/img/dude.jpg")}}
42
+
43
+ if ( ! get_option('show_avatars') ) return false;
44
+ if ( !is_numeric($size) ) $size = '92';
45
+
46
+ $email = $this->avatar_email();
47
+ $email_hash = '';
48
+ if ( !empty($email) ){
49
+ $email_hash = md5( strtolower( trim( $email ) ) );
50
+ }
51
+ $host = $this->avatar_host($email_hash);
52
+ $default = $this->avatar_default($default, $email, $size, $host);
53
+ if( !empty($email) ) {
54
+ $avatar = $this->avatar_out($email, $default, $host, $email_hash, $size);
55
+ } else {
56
+ $avatar = $default;
57
+ }
58
+ return $avatar;
59
  }
60
 
61
+ public function content() {
62
  return $this->comment_content;
63
  }
64
 
65
+ public function date() {
66
+ return $this->comment_date;
67
+ }
68
+
69
+ public function meta($field_name){
70
+ return $this->get_meta_field($field_name);
71
+ }
72
+
73
+ private function get_meta_fields($comment_id = null){
74
+ if ($comment_id === null){
75
+ $comment_id = $this->ID;
76
  }
77
+ //Could not find a WP function to fetch all comment meta data, so I made one.
78
+ global $wpdb;
79
+ $query = $wpdb->prepare("SELECT * FROM $wpdb->commentmeta WHERE comment_id = %d", $comment_id);
80
+ $metas = $wpdb->get_results($query);
81
+ $customs = array();
82
+ foreach($metas as $meta_row){
83
+ $customs[$meta_row->meta_key] = maybe_unserialize($meta_row->meta_value);
84
+ }
85
+ return $customs;
86
+ }
87
+
88
+ private function get_meta_field($field_name){
89
+
90
+ }
91
+
92
+ /* AVATAR Stuff
93
+ ======================= */
94
+
95
+ private function avatar_email(){
96
+ $email = '';
97
+ $id = (int) $this->user_id;
98
+ $user = get_userdata($id);
99
+ if ($user){
100
+ $email = $user->user_email;
101
+ } else {
102
+ $email = $this->comment_author_email;
103
+ }
104
+ return $email;
105
  }
106
 
107
+ private function avatar_host($email_hash){
108
+ if ( is_ssl() ) {
109
+ $host = 'https://secure.gravatar.com';
110
+ } else {
111
+ if ( !empty($email_hash) ){
112
+ $host = sprintf( "http://%d.gravatar.com", ( hexdec( $email_hash[0] ) % 2 ) );
113
+ } else {
114
+ $host = 'http://0.gravatar.com';
115
+ }
116
+ }
117
+ return $host;
118
+ }
119
+
120
+ private function avatar_default($default, $email, $size, $host){
121
+ # what if its relative.
122
+ if(substr ( $default , 0, 1 ) == "/" ){
123
+ $default = home_url() . $default;
124
+ }
125
+
126
+ if (empty($default) ){
127
+ $avatar_default = get_option('avatar_default');
128
+ if ( empty($avatar_default) ){
129
+ $default = 'mystery';
130
+ } else {
131
+ $default = $avatar_default;
132
+ }
133
+ }
134
+ if ( 'mystery' == $default ) {
135
+ $default = "$host/avatar/ad516503a11cd5ca435acc9bb6523536?s={$size}";
136
+ // ad516503a11cd5ca435acc9bb6523536 == md5('unknown@gravatar.com')
137
+ } elseif ( 'blank' == $default ) {
138
+ $default = $email ? 'blank' : includes_url( 'images/blank.gif' );
139
+ } elseif ( !empty($email) && 'gravatar_default' == $default ) {
140
+ $default = '';
141
+ } elseif ( 'gravatar_default' == $default ) {
142
+ $default = "$host/avatar/?s={$size}";
143
+ } elseif ( empty($email) && !strstr($default, 'http://') ) {
144
+ $default = "$host/avatar/?d=$default&amp;s={$size}";
145
+ } elseif ( strpos($default, 'http://') === 0 ) {
146
+ //theyre just linking to an image so don't do anything else
147
+ //$default = add_query_arg( 's', $size, $default );
148
+ }
149
+ return $default;
150
+ }
151
+
152
+ private function avatar_out($email, $default, $host, $email_hash, $size){
153
+ $out = "$host/avatar/";
154
+ $out .= $email_hash;
155
+ $out .= '?s='.$size;
156
+ $out .= '&amp;d=' . urlencode( $default );
157
+ $rating = get_option('avatar_rating');
158
+ if ( !empty( $rating ) ) $out .= "&amp;r={$rating}";
159
+ return str_replace( '&#038;', '&amp;', esc_url( $out ) );
160
+ }
161
+ }
functions/timber-core.php CHANGED
@@ -13,14 +13,6 @@ class TimberCore {
13
  }
14
  }
15
 
16
- function url_to_path($url = '') {
17
- if (!strlen($url) && $this->url) {
18
- $url = $this->url;
19
- }
20
- $url_info = parse_url($url);
21
- return $url_info['path'];
22
- }
23
-
24
  function can_edit() {
25
  if (isset($this->_can_edit)) {
26
  return $this->_can_edit;
@@ -34,4 +26,13 @@ class TimberCore {
34
  }
35
  return $this->_can_edit;
36
  }
 
 
 
 
 
 
 
 
 
37
  }
13
  }
14
  }
15
 
 
 
 
 
 
 
 
 
16
  function can_edit() {
17
  if (isset($this->_can_edit)) {
18
  return $this->_can_edit;
26
  }
27
  return $this->_can_edit;
28
  }
29
+
30
+ //deprecated
31
+ function url_to_path($url = '') {
32
+ if (!strlen($url) && $this->url) {
33
+ $url = $this->url;
34
+ }
35
+ $url_info = parse_url($url);
36
+ return $url_info['path'];
37
+ }
38
  }
functions/{functions-timber-helper.php → timber-helper.php} RENAMED
@@ -82,43 +82,23 @@ class TimberHelper {
82
  return $old_root_path;
83
  }
84
 
85
- public static function get_rel_url($url){
86
- if (!strstr($url, $_SERVER['HTTP_HOST'])){
87
  return $url;
88
  }
89
- $url = str_replace('http://', '', $url);
90
- $url = str_replace('https://', '', $url);
91
- return str_replace($_SERVER['HTTP_HOST'], '', $url);
 
 
 
92
  }
93
 
94
  public static function get_rel_path($src) {
95
  return str_replace(ABSPATH, '', $src);
96
  }
97
 
98
- public static function get_letterbox_file_rel($src, $w, $h) {
99
- $path_parts = pathinfo($src);
100
- $basename = $path_parts['filename'];
101
- $ext = $path_parts['extension'];
102
- $dir = $path_parts['dirname'];
103
- $newbase = $basename . '-lb-' . $w . 'x' . $h;
104
- $new_path = $dir . '/' . $newbase . '.' . $ext;
105
- return $new_path;
106
- }
107
-
108
- public static function get_letterbox_file_path($src, $w, $h) {
109
- $path_parts = pathinfo($src);
110
- $basename = $path_parts['filename'];
111
- $ext = $path_parts['extension'];
112
- $dir = $path_parts['dirname'];
113
- $newbase = $basename . '-lb-' . $w . 'x' . $h;
114
- $new_path = $dir . '/' . $newbase . '.' . $ext;
115
- $new_root_path = ABSPATH . $new_path;
116
- $new_root_path = str_replace('//', '/', $new_root_path);
117
- return $new_root_path;
118
- }
119
-
120
  public static function download_url($url, $timeout = 300) {
121
- //WARNING: The file is not automatically deleted, The script must unlink() the file.
122
  if (!$url) {
123
  return new WP_Error('http_no_url', __('Invalid URL Provided.'));
124
  }
@@ -134,12 +114,10 @@ class TimberHelper {
134
  unlink($tmpfname);
135
  return $response;
136
  }
137
-
138
  if (200 != wp_remote_retrieve_response_code($response)) {
139
  unlink($tmpfname);
140
  return new WP_Error('http_404', trim(wp_remote_retrieve_response_message($response)));
141
  }
142
-
143
  return $tmpfname;
144
  }
145
 
@@ -200,7 +178,10 @@ class TimberHelper {
200
  }
201
 
202
  public static function get_current_url() {
203
- $pageURL = (@$_SERVER["HTTPS"] == "on") ? "https://" : "http://";
 
 
 
204
  if ($_SERVER["SERVER_PORT"] != "80") {
205
  $pageURL .= $_SERVER["SERVER_NAME"] . ":" . $_SERVER["SERVER_PORT"] . $_SERVER["REQUEST_URI"];
206
  } else {
@@ -360,7 +341,7 @@ class TimberHelper {
360
  $size = 'full';
361
  $src = wp_get_attachment_image_src($iid, $size);
362
  $src = $src[0];
363
- return self::get_path($src);
364
  }
365
 
366
  public static function array_truncate($array, $len) {
82
  return $old_root_path;
83
  }
84
 
85
+ public static function get_rel_url($url, $force = false){
86
+ if (!strstr($url, $_SERVER['HTTP_HOST']) && !$force){
87
  return $url;
88
  }
89
+ $url_info = parse_url($url);
90
+ $link = $url_info['path'];
91
+ if (isset($url_info['query']) && strlen($url_info['query'])){
92
+ $link .= '?'.$url_info['query'];
93
+ }
94
+ return $link;
95
  }
96
 
97
  public static function get_rel_path($src) {
98
  return str_replace(ABSPATH, '', $src);
99
  }
100
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  public static function download_url($url, $timeout = 300) {
 
102
  if (!$url) {
103
  return new WP_Error('http_no_url', __('Invalid URL Provided.'));
104
  }
114
  unlink($tmpfname);
115
  return $response;
116
  }
 
117
  if (200 != wp_remote_retrieve_response_code($response)) {
118
  unlink($tmpfname);
119
  return new WP_Error('http_404', trim(wp_remote_retrieve_response_message($response)));
120
  }
 
121
  return $tmpfname;
122
  }
123
 
178
  }
179
 
180
  public static function get_current_url() {
181
+ $pageURL = "http://";
182
+ if (isset($_SERVER['HTTPS']) && $_SERVER["HTTPS"] == "on"){
183
+ $pageURL = "https://";;
184
+ }
185
  if ($_SERVER["SERVER_PORT"] != "80") {
186
  $pageURL .= $_SERVER["SERVER_NAME"] . ":" . $_SERVER["SERVER_PORT"] . $_SERVER["REQUEST_URI"];
187
  } else {
341
  $size = 'full';
342
  $src = wp_get_attachment_image_src($iid, $size);
343
  $src = $src[0];
344
+ return self::get_rel_path($src);
345
  }
346
 
347
  public static function array_truncate($array, $len) {
functions/{functions-timber-image-helper.php → timber-image-helper.php} RENAMED
@@ -7,6 +7,28 @@
7
  return array("red" => 0xFF & ($int >> 0x10), "green" => 0xFF & ($int >> 0x8), "blue" => 0xFF & $int);
8
  }
9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  function img_to_jpg($src, $bghex = '#FFFFFF'){
11
  $src = str_replace(site_url(), '', $src);
12
  $output = str_replace('.png', '.jpg', $src);
7
  return array("red" => 0xFF & ($int >> 0x10), "green" => 0xFF & ($int >> 0x8), "blue" => 0xFF & $int);
8
  }
9
 
10
+ public static function get_letterbox_file_rel($src, $w, $h) {
11
+ $path_parts = pathinfo($src);
12
+ $basename = $path_parts['filename'];
13
+ $ext = $path_parts['extension'];
14
+ $dir = $path_parts['dirname'];
15
+ $newbase = $basename . '-lb-' . $w . 'x' . $h;
16
+ $new_path = $dir . '/' . $newbase . '.' . $ext;
17
+ return $new_path;
18
+ }
19
+
20
+ public static function get_letterbox_file_path($src, $w, $h) {
21
+ $path_parts = pathinfo($src);
22
+ $basename = $path_parts['filename'];
23
+ $ext = $path_parts['extension'];
24
+ $dir = $path_parts['dirname'];
25
+ $newbase = $basename . '-lb-' . $w . 'x' . $h;
26
+ $new_path = $dir . '/' . $newbase . '.' . $ext;
27
+ $new_root_path = ABSPATH . $new_path;
28
+ $new_root_path = str_replace('//', '/', $new_root_path);
29
+ return $new_root_path;
30
+ }
31
+
32
  function img_to_jpg($src, $bghex = '#FFFFFF'){
33
  $src = str_replace(site_url(), '', $src);
34
  $output = str_replace('.png', '.jpg', $src);
functions/timber-image.php CHANGED
@@ -76,8 +76,10 @@ class TimberImage extends TimberCore {
76
  }
77
  $image_custom = get_post_custom($iid);
78
  $basic = get_post($iid);
79
- $this->caption = $basic->post_excerpt;
80
  if ($basic){
 
 
 
81
  $image_custom = array_merge($image_custom, get_object_vars($basic));
82
  }
83
  $image_info = array_merge($image_info, $image_custom);
@@ -98,7 +100,12 @@ class TimberImage extends TimberCore {
98
  $this->$key = $value[0];
99
  }
100
  } else {
101
- TimberHelper::error_log('Not able to init in TimberImage with iid=' . $iid);
 
 
 
 
 
102
  }
103
  }
104
 
76
  }
77
  $image_custom = get_post_custom($iid);
78
  $basic = get_post($iid);
 
79
  if ($basic){
80
+ if (isset($basic->post_excerpt)){
81
+ $this->caption = $basic->post_excerpt;
82
+ }
83
  $image_custom = array_merge($image_custom, get_object_vars($basic));
84
  }
85
  $image_info = array_merge($image_info, $image_custom);
100
  $this->$key = $value[0];
101
  }
102
  } else {
103
+ if (is_array($iid)){
104
+ TimberHelper::error_log('Not able to init in TimberImage with iid=');
105
+ TimberHelper::error_log($iid);
106
+ } else {
107
+ TimberHelper::error_log('Not able to init in TimberImage with iid=' . $iid);
108
+ }
109
  }
110
  }
111
 
functions/timber-menu.php CHANGED
@@ -12,6 +12,8 @@ class TimberMenu extends TimberCore {
12
  $menu_id = $slug;
13
  } else if (count($locations)){
14
  $menu_id = $this->get_menu_id_from_locations($slug, $locations);
 
 
15
  } else {
16
  $menu_id = $this->get_menu_id_from_terms($slug);
17
  }
12
  $menu_id = $slug;
13
  } else if (count($locations)){
14
  $menu_id = $this->get_menu_id_from_locations($slug, $locations);
15
+ } else if ($slug === false){
16
+ $menu_id = false;
17
  } else {
18
  $menu_id = $this->get_menu_id_from_terms($slug);
19
  }
functions/timber-post.php CHANGED
@@ -115,7 +115,7 @@ class TimberPost extends TimberCore {
115
  * @nodoc
116
  */
117
 
118
- function get_post_id_by_name($post_name) {
119
  global $wpdb;
120
  $query = $wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE post_name = %s LIMIT 1", $post_name);
121
  $result = $wpdb->get_row($query);
@@ -196,6 +196,7 @@ class TimberPost extends TimberCore {
196
  $v = $value[0];
197
  $customs[$key] = maybe_unserialize($v);
198
  }
 
199
  return $customs;
200
  }
201
 
@@ -233,6 +234,10 @@ class TimberPost extends TimberCore {
233
  return $this->next;
234
  }
235
 
 
 
 
 
236
  function get_prev() {
237
  if (!isset($this->prev)){
238
  $this->prev = new $this->PostClass(get_adjacent_post( false, "", true ));
@@ -357,13 +362,19 @@ class TimberPost extends TimberCore {
357
  $tax = 'category';
358
  }
359
  $terms = wp_get_post_terms($this->ID, $tax);
360
- foreach ($terms as &$term) {
361
- $term = new $TermClass($term->term_id);
362
- }
363
- if ($merge && is_array($terms)) {
364
- $ret = array_merge($ret, $terms);
365
- } else if (count($terms)) {
366
- $ret[$tax] = $terms;
 
 
 
 
 
 
367
  }
368
  }
369
  if (!isset($this->_get_terms)){
@@ -420,11 +431,11 @@ class TimberPost extends TimberCore {
420
  return apply_filters('the_content', ($content));
421
  }
422
 
423
- function get_post_type() {
424
  return get_post_type_object($this->post_type);
425
  }
426
 
427
- function get_comment_count() {
428
  if (isset($this->ID)) {
429
  return get_comments_number($this->ID);
430
  } else {
@@ -432,12 +443,13 @@ class TimberPost extends TimberCore {
432
  }
433
  }
434
 
435
- //This is for integration with Elliot Condon's wonderful ACF
436
- function get_field($field_name) {
437
- if (function_exists('get_field')){
438
- return get_field($field_name, $this->ID);
 
439
  }
440
- return get_post_meta($this->ID, $field, true);
441
  }
442
 
443
  function import_field($field_name) {
@@ -445,78 +457,76 @@ class TimberPost extends TimberCore {
445
  }
446
 
447
  //Aliases
448
- function author() {
449
  return $this->get_author();
450
  }
451
 
452
- function categories() {
453
  return $this->get_terms('category');
454
  }
455
 
456
- function category() {
457
  return $this->get_category();
458
  }
459
 
460
- function children() {
461
  return $this->get_children();
462
  }
463
 
464
- function comments(){
465
  return $this->get_comments();
466
  }
467
 
468
- function content() {
469
  return $this->get_content();
470
  }
471
 
472
- function display_date(){
473
  return date(get_option('date_format'), strtotime($this->post_date));
474
  }
475
 
476
- function edit_link(){
477
  return $this->get_edit_url();
478
  }
479
 
480
- function link() {
481
  return $this->get_permalink();
482
  }
483
 
484
- function next() {
 
 
 
 
485
  return $this->get_next();
486
  }
487
 
488
- function path() {
489
- $path = TimberHelper::get_rel_url($this->get_permalink());
490
- return TimberHelper::preslashit($path);
491
  }
492
 
493
- function permalink() {
494
  return $this->get_permalink();
495
  }
496
 
497
- function prev() {
498
  return $this->get_prev();
499
  }
500
 
501
- function terms($tax = '') {
502
  return $this->get_terms($tax);
503
  }
504
 
505
- function tags() {
506
  return $this->get_tags();
507
  }
508
 
509
- function thumbnail() {
510
  return $this->get_thumbnail();
511
  }
512
 
513
- function title() {
514
  return $this->get_title();
515
  }
516
 
517
- //Deprecated
518
- function get_path() {
519
- return TimberHelper::get_rel_url($this->get_link());
520
- }
521
-
522
  }
115
  * @nodoc
116
  */
117
 
118
+ public static function get_post_id_by_name($post_name) {
119
  global $wpdb;
120
  $query = $wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE post_name = %s LIMIT 1", $post_name);
121
  $result = $wpdb->get_row($query);
196
  $v = $value[0];
197
  $customs[$key] = maybe_unserialize($v);
198
  }
199
+ $customs = apply_filters('post_get_meta', $customs, $pid);
200
  return $customs;
201
  }
202
 
234
  return $this->next;
235
  }
236
 
237
+ public function get_path() {
238
+ return TimberHelper::get_rel_url($this->get_link());
239
+ }
240
+
241
  function get_prev() {
242
  if (!isset($this->prev)){
243
  $this->prev = new $this->PostClass(get_adjacent_post( false, "", true ));
362
  $tax = 'category';
363
  }
364
  $terms = wp_get_post_terms($this->ID, $tax);
365
+ if (!is_array($terms) && is_object($terms) && get_class($terms) == 'WP_Error'){
366
+ //something is very wrong
367
+ TimberHelper::error_log('You have an error retrieving terms on a post in timber-post.php:367');
368
+ TimberHelper::error_log($terms);
369
+ } else {
370
+ foreach ($terms as &$term) {
371
+ $term = new $TermClass($term->term_id);
372
+ }
373
+ if ($merge && is_array($terms)) {
374
+ $ret = array_merge($ret, $terms);
375
+ } else if (count($terms)) {
376
+ $ret[$tax] = $terms;
377
+ }
378
  }
379
  }
380
  if (!isset($this->_get_terms)){
431
  return apply_filters('the_content', ($content));
432
  }
433
 
434
+ public function get_post_type() {
435
  return get_post_type_object($this->post_type);
436
  }
437
 
438
+ public function get_comment_count() {
439
  if (isset($this->ID)) {
440
  return get_comments_number($this->ID);
441
  } else {
443
  }
444
  }
445
 
446
+ public function get_field($field_name) {
447
+ $value = null;
448
+ $value = apply_filters('timber_post_get_meta_field', $value, $this->ID, $field_name);
449
+ if ($value === null){
450
+ $value = get_post_meta($this->ID, $field, true);
451
  }
452
+ return $value;
453
  }
454
 
455
  function import_field($field_name) {
457
  }
458
 
459
  //Aliases
460
+ public function author() {
461
  return $this->get_author();
462
  }
463
 
464
+ public function categories() {
465
  return $this->get_terms('category');
466
  }
467
 
468
+ public function category() {
469
  return $this->get_category();
470
  }
471
 
472
+ public function children() {
473
  return $this->get_children();
474
  }
475
 
476
+ public function comments(){
477
  return $this->get_comments();
478
  }
479
 
480
+ public function content() {
481
  return $this->get_content();
482
  }
483
 
484
+ public function display_date(){
485
  return date(get_option('date_format'), strtotime($this->post_date));
486
  }
487
 
488
+ public function edit_link(){
489
  return $this->get_edit_url();
490
  }
491
 
492
+ public function link() {
493
  return $this->get_permalink();
494
  }
495
 
496
+ public function meta($field_name){
497
+ return $this->get_field($field_name);
498
+ }
499
+
500
+ public function next() {
501
  return $this->get_next();
502
  }
503
 
504
+ public function path() {
505
+ return $this->get_path();
 
506
  }
507
 
508
+ public function permalink() {
509
  return $this->get_permalink();
510
  }
511
 
512
+ public function prev() {
513
  return $this->get_prev();
514
  }
515
 
516
+ public function terms($tax = '') {
517
  return $this->get_terms($tax);
518
  }
519
 
520
+ public function tags() {
521
  return $this->get_tags();
522
  }
523
 
524
+ public function thumbnail() {
525
  return $this->get_thumbnail();
526
  }
527
 
528
+ public function title() {
529
  return $this->get_title();
530
  }
531
 
 
 
 
 
 
532
  }
functions/timber-term.php CHANGED
@@ -20,17 +20,16 @@ class TimberTerm extends TimberCore {
20
  return $this->name;
21
  }
22
 
23
- function get_term_from_query() {
 
 
 
24
  global $wp_query;
25
  $qo = $wp_query->queried_object;
26
  return $qo->term_id;
27
  }
28
 
29
- function get_page($i) {
30
- return $this->get_path() . '/page/' . $i;
31
- }
32
-
33
- function init($tid) {
34
  global $wpdb;
35
  $term = $this->get_term($tid);
36
  if (isset($term->id)) {
@@ -41,44 +40,37 @@ class TimberTerm extends TimberCore {
41
  //echo 'bad call using '.$tid;
42
  //TimberHelper::error_log(debug_backtrace());
43
  }
44
- if (function_exists('get_fields')) {
45
- //lets get whatever we can from advanced custom fields;
46
- //IF you have the wonderful ACF installed
47
- $searcher = $term->taxonomy . "_" . $term->ID; // save to a specific category
48
- $fields = array();
49
- $fds = get_fields($searcher);
50
- if (is_array($fds)) {
51
- foreach ($fds as $key => $value) {
52
- $key = preg_replace('/_/', '', $key, 1);
53
- $key = str_replace($searcher, '', $key);
54
- $key = preg_replace('/_/', '', $key, 1);
55
- $field = get_field($key, $searcher);
56
- $fields[$key] = $field;
57
- }
58
- }
59
- $this->import($fields);
60
- }
61
  $this->import($term);
 
 
 
 
 
 
62
  }
63
 
64
- function get_term($tid) {
 
 
 
 
 
 
65
  if (is_object($tid) || is_array($tid)) {
66
  return $tid;
67
  }
68
  $tid = self::get_tid($tid);
69
  global $wpdb;
70
- $query = $wpdb->prepare("SELECT * FROM $wpdb->term_taxonomy WHERE term_id = %d LIMIT 1", $tid);
71
- $tax = $wpdb->get_row($query);
72
- if (isset($tax) && isset($tax->taxonomy)) {
73
- if ($tax->taxonomy) {
74
- $term = get_term($tid, $tax->taxonomy);
75
- return $term;
76
- }
77
  }
78
  return null;
79
  }
80
 
81
- function get_tid($tid) {
82
  global $wpdb;
83
  if (is_numeric($tid)) {
84
  return $tid;
@@ -91,7 +83,6 @@ class TimberTerm extends TimberCore {
91
  } else {
92
  $query = $wpdb->prepare("SELECT * FROM $wpdb->terms WHERE slug = %s", $tid);
93
  }
94
-
95
  $result = $wpdb->get_row($query);
96
  if (isset($result->term_id)) {
97
  $result->ID = $result->term_id;
@@ -100,32 +91,69 @@ class TimberTerm extends TimberCore {
100
  return 0;
101
  }
102
 
103
- function get_path() {
104
- $link = $this->get_link();
105
- return TimberHelper::get_rel_url($link);
 
 
 
 
 
 
 
106
  }
107
 
108
- function get_link() {
109
- return get_term_link($this);
 
 
110
  }
111
 
112
- function get_url() {
113
- return $this->get_link();
 
114
  }
115
 
116
  public function get_posts($numberposts = 10, $post_type = 'any', $PostClass = '') {
117
  if (!strlen($PostClass)) {
118
  $PostClass = $this->PostClass;
119
  }
120
- $args = array(
121
- 'numberposts' => $numberposts,
122
- 'tax_query' => array(array(
123
- 'field' => 'id',
124
- 'terms' => $this->ID,
125
- 'taxonomy' => $this->taxonomy,
126
- )),
127
- 'post_type' => $post_type
128
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  return Timber::get_posts($args, $PostClass);
130
  }
131
 
@@ -147,18 +175,35 @@ class TimberTerm extends TimberCore {
147
  return $this->get_children();
148
  }
149
 
 
 
 
 
150
  public function link(){
151
  return $this->get_link();
152
  }
153
 
 
 
 
 
154
  public function path(){
155
  return $this->get_path();
156
  }
157
 
 
 
 
 
158
  public function url(){
159
  return $this->get_url();
160
  }
161
 
162
-
 
 
 
 
 
163
 
164
  }
20
  return $this->name;
21
  }
22
 
23
+ /* Setup
24
+ ===================== */
25
+
26
+ private function get_term_from_query() {
27
  global $wp_query;
28
  $qo = $wp_query->queried_object;
29
  return $qo->term_id;
30
  }
31
 
32
+ private function init($tid) {
 
 
 
 
33
  global $wpdb;
34
  $term = $this->get_term($tid);
35
  if (isset($term->id)) {
40
  //echo 'bad call using '.$tid;
41
  //TimberHelper::error_log(debug_backtrace());
42
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  $this->import($term);
44
+ if (isset($term->term_id)){
45
+ $custom = $this->get_term_meta($term->term_id);
46
+ $this->import($custom);
47
+ } else {
48
+ //print_r($term);
49
+ }
50
  }
51
 
52
+ private function get_term_meta($tid){
53
+ $customs = array();
54
+ $customs = apply_filters('timber_term_get_meta', $customs, $tid, $this);
55
+ return $customs;
56
+ }
57
+
58
+ private function get_term($tid) {
59
  if (is_object($tid) || is_array($tid)) {
60
  return $tid;
61
  }
62
  $tid = self::get_tid($tid);
63
  global $wpdb;
64
+ $query = $wpdb->prepare("SELECT taxonomy FROM $wpdb->term_taxonomy WHERE term_id = %d LIMIT 1", $tid);
65
+ $tax = $wpdb->get_var($query);
66
+ if (isset($tax) && strlen($tax)) {
67
+ $term = get_term($tid, $tax);
68
+ return $term;
 
 
69
  }
70
  return null;
71
  }
72
 
73
+ private function get_tid($tid) {
74
  global $wpdb;
75
  if (is_numeric($tid)) {
76
  return $tid;
83
  } else {
84
  $query = $wpdb->prepare("SELECT * FROM $wpdb->terms WHERE slug = %s", $tid);
85
  }
 
86
  $result = $wpdb->get_row($query);
87
  if (isset($result->term_id)) {
88
  $result->ID = $result->term_id;
91
  return 0;
92
  }
93
 
94
+ /* Public methods
95
+ ===================== */
96
+
97
+ public function get_meta_field($field_name){
98
+ if (!isset($this->$field_name)){
99
+ $field = '';
100
+ $field = apply_filters('timber_term_get_meta_field', $field, $field_name, $this);
101
+ $this->$field_name = $field;
102
+ }
103
+ return $this->$field_name;
104
  }
105
 
106
+ public function get_path() {
107
+ $link = $this->get_link();
108
+ $rel = TimberHelper::get_rel_url($link, true);
109
+ return apply_filters('timber_term_path', $rel, $this);
110
  }
111
 
112
+ public function get_link() {
113
+ $link = get_term_link($this);
114
+ return apply_filters('timber_term_link', $link, $this);
115
  }
116
 
117
  public function get_posts($numberposts = 10, $post_type = 'any', $PostClass = '') {
118
  if (!strlen($PostClass)) {
119
  $PostClass = $this->PostClass;
120
  }
121
+ $default_tax_query = array(array(
122
+ 'field' => 'id',
123
+ 'terms' => $this->ID,
124
+ 'taxonomy' => $this->taxonomy,
125
+ ));
126
+ if (is_string($numberposts) && strstr($numberposts, '=')){
127
+ $args = $numberposts;
128
+ $new_args = array();
129
+ parse_str($args, $new_args);
130
+ $args = $new_args;
131
+ $args['tax_query'] = $default_tax_query;
132
+ if (!isset($args['post_type'])){
133
+ $args['post_type'] = 'any';
134
+ }
135
+ if (class_exists($post_type)){
136
+ $PostClass = $post_type;
137
+ }
138
+ } else if (is_array($numberposts)) {
139
+ //they sent us an array already baked
140
+ $args = $numberposts;
141
+ if (!isset($args['tax_query'])){
142
+ $args['tax_query'] = $default_tax_query;
143
+ }
144
+ if (class_exists($post_type)){
145
+ $PostClass = $post_type;
146
+ }
147
+ if (!isset($args['post_type'])){
148
+ $args['post_type'] = 'any';
149
+ }
150
+ } else {
151
+ $args = array(
152
+ 'numberposts' => $numberposts,
153
+ 'tax_query' => $default_tax_query,
154
+ 'post_type' => $post_type
155
+ );
156
+ }
157
  return Timber::get_posts($args, $PostClass);
158
  }
159
 
175
  return $this->get_children();
176
  }
177
 
178
+ public function get_url() {
179
+ return $this->get_link();
180
+ }
181
+
182
  public function link(){
183
  return $this->get_link();
184
  }
185
 
186
+ public function meta($field_name){
187
+ return $this->get_meta_field($field_name);
188
+ }
189
+
190
  public function path(){
191
  return $this->get_path();
192
  }
193
 
194
+ public function posts($numberposts_or_args = 10, $post_type_or_class = 'any', $post_class = ''){
195
+ return $this->get_posts($numberposts_or_args, $post_type_or_class, $post_class);
196
+ }
197
+
198
  public function url(){
199
  return $this->get_url();
200
  }
201
 
202
+ /* Deprecated
203
+ ===================== */
204
+
205
+ function get_page($i) {
206
+ return $this->get_path() . '/page/' . $i;
207
+ }
208
 
209
  }
functions/timber-user.php CHANGED
@@ -21,6 +21,16 @@ class TimberUser extends TimberCore {
21
  return '';
22
  }
23
 
 
 
 
 
 
 
 
 
 
 
24
  function __set($field, $value){
25
  if ($field == 'name'){
26
  $this->display_name = $value;
@@ -49,19 +59,31 @@ class TimberUser extends TimberCore {
49
  }
50
  }
51
 
 
 
 
 
 
 
 
 
 
 
52
  function get_custom() {
53
  if ($this->ID) {
54
- $um = get_user_meta($this->ID);
55
- $custom = new stdClass();
 
 
 
 
56
  foreach ($um as $key => $value) {
57
- $v = $value[0];
58
- $custom->$key = $v;
59
- if (is_serialized($v)) {
60
- if (gettype(unserialize($v)) == 'array') {
61
- $custom->$key = unserialize($v);
62
- }
63
  }
 
64
  }
 
65
  return $custom;
66
  }
67
  return null;
@@ -88,6 +110,10 @@ class TimberUser extends TimberCore {
88
  return $this->get_link();
89
  }
90
 
 
 
 
 
91
  function path() {
92
  return $this->get_path();
93
  }
21
  return '';
22
  }
23
 
24
+ function get_meta($field_name){
25
+ $value = null;
26
+ $value = apply_filters('timber_user_get_meta_field_pre', $value, $this->ID, $field_name);
27
+ if ($value === null){
28
+ $value = get_post_meta($this->ID, $field, true);
29
+ }
30
+ $value = apply_filters('timber_user_get_meta_field', $value, $this->ID, $field_name);
31
+ return $value;
32
+ }
33
+
34
  function __set($field, $value){
35
  if ($field == 'name'){
36
  $this->display_name = $value;
59
  }
60
  }
61
 
62
+ function get_meta_field($field_name){
63
+ $value = null;
64
+ $value = apply_filters('timber_user_get_meta_field_pre', $value, $field_name, $this->ID);
65
+ if ($value === null){
66
+ $value = get_post_meta($this->ID, $field, true);
67
+ }
68
+ $value = apply_filters('timber_user_get_meta_field', $value, $field_name, $this->ID);
69
+ return $value;
70
+ }
71
+
72
  function get_custom() {
73
  if ($this->ID) {
74
+ $um = array();
75
+ $um = apply_filters('timber_user_get_meta_pre', $um, $this->ID);
76
+ if (empty($um)){
77
+ $um = get_user_meta($this->ID);
78
+ }
79
+ $custom = array();
80
  foreach ($um as $key => $value) {
81
+ if (is_array($value) && count($value) == 1){
82
+ $value = $value[0];
 
 
 
 
83
  }
84
+ $custom[$key] = maybe_unserialize($value);
85
  }
86
+ $custom = apply_filters('timber_user_get_meta', $custom, $this->ID);
87
  return $custom;
88
  }
89
  return null;
110
  return $this->get_link();
111
  }
112
 
113
+ function meta($field_name){
114
+ return $this->get_meta_field($field_name);
115
+ }
116
+
117
  function path() {
118
  return $this->get_path();
119
  }
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  Contributors: jarednova
3
  Tags: template engine, templates, twig
4
  Requires at least: 3.5
5
- Stable tag: 0.15.2
6
- Tested up to: 3.6.1
7
  PHP version: 5.3.0 or greater
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
@@ -41,6 +41,14 @@ Timber is great for any WordPress developer who cares about writing good, mainta
41
 
42
  == Changelog ==
43
 
 
 
 
 
 
 
 
 
44
  = 0.15.2 =
45
  * TimberImages now support alternate sizes
46
 
2
  Contributors: jarednova
3
  Tags: template engine, templates, twig
4
  Requires at least: 3.5
5
+ Stable tag: 0.15.3
6
+ Tested up to: 3.7.1
7
  PHP version: 5.3.0 or greater
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
41
 
42
  == Changelog ==
43
 
44
+ = 0.15.3 =
45
+ * Upgreaded to Twig 1.14.2
46
+ * Added composer integration
47
+ * Bunch of new tests
48
+ * Comments now support gravatrs (thanks @asecondwill)
49
+ * Moved ACF integration into its own file. It now interacts via hooks instead of in-line
50
+ * A few misc. bugs and extra sanity checks
51
+
52
  = 0.15.2 =
53
  * TimberImages now support alternate sizes
54
 
timber-starter-theme/404.php CHANGED
@@ -9,4 +9,5 @@
9
  * @since Timber 0.1
10
  */
11
 
12
- Timber::render('404.twig');
 
9
  * @since Timber 0.1
10
  */
11
 
12
+ $context = Timber::get_context();
13
+ Timber::render('404.twig', $context);
timber-starter-theme/archive.php CHANGED
@@ -13,7 +13,6 @@
13
  * @subpackage Timber
14
  * @since Timber 0.2
15
  */
16
-
17
 
18
  $templates = array('archive.twig', 'index.twig');
19
 
@@ -21,11 +20,11 @@
21
 
22
  $data['title'] = 'Archive';
23
  if (is_day()){
24
- $data['title'] = 'Archive: '.get_the_date( 'D M Y' );
25
  } else if (is_month()){
26
- $data['title'] = 'Archive: '.get_the_date( 'M Y' );
27
  } else if (is_year()){
28
- $data['title'] = 'Archive: '.get_the_date( 'Y' );
29
  } else if (is_tag()){
30
  $data['title'] = single_tag_title('', false);
31
  } else if (is_category()){
@@ -35,7 +34,7 @@
35
  $data['title'] = post_type_archive_title('', false);
36
  array_unshift($templates, 'archive-'.get_post_type().'.twig');
37
  }
38
-
39
  $data['posts'] = Timber::get_posts();
40
-
41
  Timber::render($templates, $data);
13
  * @subpackage Timber
14
  * @since Timber 0.2
15
  */
 
16
 
17
  $templates = array('archive.twig', 'index.twig');
18
 
20
 
21
  $data['title'] = 'Archive';
22
  if (is_day()){
23
+ $data['title'] = 'Archive: '.get_the_date( 'D M Y' );
24
  } else if (is_month()){
25
+ $data['title'] = 'Archive: '.get_the_date( 'M Y' );
26
  } else if (is_year()){
27
+ $data['title'] = 'Archive: '.get_the_date( 'Y' );
28
  } else if (is_tag()){
29
  $data['title'] = single_tag_title('', false);
30
  } else if (is_category()){
34
  $data['title'] = post_type_archive_title('', false);
35
  array_unshift($templates, 'archive-'.get_post_type().'.twig');
36
  }
37
+
38
  $data['posts'] = Timber::get_posts();
39
+
40
  Timber::render($templates, $data);
timber-starter-theme/index.php CHANGED
@@ -16,13 +16,13 @@
16
  if (!class_exists('Timber')){
17
  echo 'Timber not activated. Make sure you activate the plugin in <a href="/wp-admin/plugins.php#timber">/wp-admin/plugins.php</a>';
18
  }
19
- $data = Timber::get_context();
20
- $data['posts'] = Timber::get_posts();
21
- $data['foo'] = 'bar';
22
  $templates = array('index.twig');
23
  if (is_home()){
24
  array_unshift($templates, 'home.twig');
25
  }
26
- Timber::render('index.twig', $data);
27
 
28
 
16
  if (!class_exists('Timber')){
17
  echo 'Timber not activated. Make sure you activate the plugin in <a href="/wp-admin/plugins.php#timber">/wp-admin/plugins.php</a>';
18
  }
19
+ $context = Timber::get_context();
20
+ $context['posts'] = Timber::get_posts();
21
+ $context['foo'] = 'bar';
22
  $templates = array('index.twig');
23
  if (is_home()){
24
  array_unshift($templates, 'home.twig');
25
  }
26
+ Timber::render('index.twig', $context);
27
 
28
 
timber-starter-theme/search.php CHANGED
@@ -1,19 +1,19 @@
1
  <?php
2
  /**
3
  * Search results page
4
- *
5
  * Methods for TimberHelper can be found in the /functions sub-directory
6
  *
7
  * @package WordPress
8
  * @subpackage Timber
9
  * @since Timber 0.1
10
  */
11
-
12
 
13
- $templates = array('archive.twig', 'index.twig');
14
- $data = Timber::get_context();
15
 
16
- $data['title'] = 'Search results for '. get_search_query();
17
- $data['posts'] = Timber::get_posts();
18
-
19
- Timber::render($templates, $data);
 
 
 
1
  <?php
2
  /**
3
  * Search results page
4
+ *
5
  * Methods for TimberHelper can be found in the /functions sub-directory
6
  *
7
  * @package WordPress
8
  * @subpackage Timber
9
  * @since Timber 0.1
10
  */
 
11
 
 
 
12
 
13
+ $templates = array('search.twig', 'archive.twig', 'index.twig');
14
+ $context = Timber::get_context();
15
+
16
+ $context['title'] = 'Search results for '. get_search_query();
17
+ $context['posts'] = Timber::get_posts();
18
+
19
+ Timber::render($templates, $context);
timber-starter-theme/single.php CHANGED
@@ -12,7 +12,7 @@
12
  $context = Timber::get_context();
13
  $post = new TimberPost();
14
  $context['post'] = $post;
15
- $context['wp_title'] .= ' - ' . $post->post_title;
16
  $context['comment_form'] = TimberHelper::get_comment_form();
17
 
18
- Timber::render(array('single-' . $post->post_type . '.twig', 'single.twig'), $context);
12
  $context = Timber::get_context();
13
  $post = new TimberPost();
14
  $context['post'] = $post;
15
+ $context['wp_title'] .= ' - ' . $post->title();
16
  $context['comment_form'] = TimberHelper::get_comment_form();
17
 
18
+ Timber::render(array('single-' . $post->ID . '.twig', 'single-' . $post->post_type . '.twig', 'single.twig'), $context);
timber.php CHANGED
@@ -4,7 +4,7 @@ Plugin Name: Timber
4
  Plugin URI: http://timber.upstatement.com
5
  Description: The WordPress Timber Library allows you to write themes using the power Twig templates
6
  Author: Jared Novack + Upstatement
7
- Version: 0.15.2
8
  Author URI: http://upstatement.com/
9
  */
10
 
@@ -12,8 +12,8 @@ global $wp_version;
12
  global $timber;
13
 
14
  require_once(__DIR__ . '/functions/functions-twig.php');
15
- require_once(__DIR__ . '/functions/functions-timber-helper.php');
16
- require_once(__DIR__ . '/functions/functions-timber-image-helper.php');
17
 
18
  require_once(__DIR__ . '/functions/timber-core.php');
19
  require_once(__DIR__ . '/functions/timber-post.php');
@@ -28,6 +28,7 @@ require_once(__DIR__ . '/functions/timber-site.php');
28
 
29
  require_once(__DIR__ . '/functions/timber-loader.php');
30
  require_once(__DIR__ . '/functions/timber-function-wrapper.php');
 
31
 
32
  require_once(__DIR__ . '/admin/timber-admin.php');
33
 
@@ -131,7 +132,7 @@ class Timber {
131
  return $query;
132
  }
133
 
134
- public function get_pids($query = null) {
135
  $posts = get_posts($query);
136
  $pids = array();
137
  foreach ($posts as $post) {
@@ -446,9 +447,12 @@ class Timber {
446
  }
447
 
448
 
449
- public static function load_template($template, $query = false, $force_header = 0) {
450
  $template = locate_template($template);
451
-
 
 
 
452
  if ($force_header) {
453
  add_filter('status_header', function($status_header, $header, $text, $protocol) use ($force_header) {
454
  $text = get_status_header_desc($force_header);
4
  Plugin URI: http://timber.upstatement.com
5
  Description: The WordPress Timber Library allows you to write themes using the power Twig templates
6
  Author: Jared Novack + Upstatement
7
+ Version: 0.15.3
8
  Author URI: http://upstatement.com/
9
  */
10
 
12
  global $timber;
13
 
14
  require_once(__DIR__ . '/functions/functions-twig.php');
15
+ require_once(__DIR__ . '/functions/timber-helper.php');
16
+ require_once(__DIR__ . '/functions/timber-image-helper.php');
17
 
18
  require_once(__DIR__ . '/functions/timber-core.php');
19
  require_once(__DIR__ . '/functions/timber-post.php');
28
 
29
  require_once(__DIR__ . '/functions/timber-loader.php');
30
  require_once(__DIR__ . '/functions/timber-function-wrapper.php');
31
+ require_once(__DIR__ . '/functions/integrations/acf-timber.php');
32
 
33
  require_once(__DIR__ . '/admin/timber-admin.php');
34
 
132
  return $query;
133
  }
134
 
135
+ public static function get_pids($query = null) {
136
  $posts = get_posts($query);
137
  $pids = array();
138
  foreach ($posts as $post) {
447
  }
448
 
449
 
450
+ public static function load_template($template, $query = false, $force_header = 0, $tparams = false) {
451
  $template = locate_template($template);
452
+ if ($tparams){
453
+ global $params;
454
+ $params = $tparams;
455
+ }
456
  if ($force_header) {
457
  add_filter('status_header', function($status_header, $header, $text, $protocol) use ($force_header) {
458
  $text = get_status_header_desc($force_header);