TwigNodeCache.php 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. <?php
  2. /**
  3. * @package Grav\Common\Twig
  4. *
  5. * @copyright Copyright (c) 2015 - 2023 Trilby Media, LLC. All rights reserved.
  6. * @license MIT License; see LICENSE file for details.
  7. */
  8. namespace Grav\Common\Twig\Node;
  9. use Twig\Compiler;
  10. use Twig\Node\Expression\AbstractExpression;
  11. use Twig\Node\Node;
  12. use Twig\Node\NodeOutputInterface;
  13. /**
  14. * Class TwigNodeCache
  15. * @package Grav\Common\Twig\Node
  16. */
  17. class TwigNodeCache extends Node implements NodeOutputInterface
  18. {
  19. /**
  20. * @param string $key unique name for key
  21. * @param int $lifetime in seconds
  22. * @param Node $body
  23. * @param integer $lineno
  24. * @param string|null $tag
  25. */
  26. public function __construct(Node $body, ?AbstractExpression $key, ?AbstractExpression $lifetime, array $defaults, int $lineno, string $tag)
  27. {
  28. $nodes = ['body' => $body];
  29. if ($key !== null) {
  30. $nodes['key'] = $key;
  31. }
  32. if ($lifetime !== null) {
  33. $nodes['lifetime'] = $lifetime;
  34. }
  35. parent::__construct($nodes, $defaults, $lineno, $tag);
  36. }
  37. public function compile(Compiler $compiler): void
  38. {
  39. $compiler->addDebugInfo($this);
  40. // Generate the cache key
  41. if ($this->hasNode('key')) {
  42. $compiler
  43. ->write('$key = "twigcache-" . ')
  44. ->subcompile($this->getNode('key'))
  45. ->raw(";\n");
  46. } else {
  47. $compiler
  48. ->write('$key = ')
  49. ->string($this->getAttribute('key'))
  50. ->raw(";\n");
  51. }
  52. // Set the cache timeout
  53. if ($this->hasNode('lifetime')) {
  54. $compiler
  55. ->write('$lifetime = ')
  56. ->subcompile($this->getNode('lifetime'))
  57. ->raw(";\n");
  58. } else {
  59. $compiler
  60. ->write('$lifetime = ')
  61. ->write($this->getAttribute('lifetime'))
  62. ->raw(";\n");
  63. }
  64. $compiler
  65. ->write("\$cache = \\Grav\\Common\\Grav::instance()['cache'];\n")
  66. ->write("\$cache_body = \$cache->fetch(\$key);\n")
  67. ->write("if (\$cache_body === false) {\n")
  68. ->indent()
  69. ->write("\\Grav\\Common\\Grav::instance()['debugger']->addMessage(\"Cache Key: \$key, Lifetime: \$lifetime\");\n")
  70. ->write("ob_start();\n")
  71. ->indent()
  72. ->subcompile($this->getNode('body'))
  73. ->outdent()
  74. ->write("\n")
  75. ->write("\$cache_body = ob_get_clean();\n")
  76. ->write("\$cache->save(\$key, \$cache_body, \$lifetime);\n")
  77. ->outdent()
  78. ->write("}\n")
  79. ->write("echo '' === \$cache_body ? '' : new Markup(\$cache_body, \$this->env->getCharset());\n");
  80. }
  81. }