1<?php 2 3/** 4 * Runtime Extension Capture 5 * 6 * @package Smarty 7 * @subpackage PluginsInternal 8 * @author Uwe Tews 9 */ 10class Smarty_Internal_Runtime_Capture 11{ 12 /** 13 * Flag that this instance will not be cached 14 * 15 * @var bool 16 */ 17 public $isPrivateExtension = true; 18 19 /** 20 * Stack of capture parameter 21 * 22 * @var array 23 */ 24 private $captureStack = array(); 25 26 /** 27 * Current open capture sections 28 * 29 * @var int 30 */ 31 private $captureCount = 0; 32 33 /** 34 * Count stack 35 * 36 * @var int[] 37 */ 38 private $countStack = array(); 39 40 /** 41 * Named buffer 42 * 43 * @var string[] 44 */ 45 private $namedBuffer = array(); 46 47 /** 48 * Flag if callbacks are registered 49 * 50 * @var bool 51 */ 52 private $isRegistered = false; 53 54 /** 55 * Open capture section 56 * 57 * @param \Smarty_Internal_Template $_template 58 * @param string $buffer capture name 59 * @param string $assign variable name 60 * @param string $append variable name 61 */ 62 public function open(Smarty_Internal_Template $_template, $buffer, $assign, $append) 63 { 64 if (!$this->isRegistered) { 65 $this->register($_template); 66 } 67 $this->captureStack[] = array( 68 $buffer, 69 $assign, 70 $append 71 ); 72 $this->captureCount++; 73 ob_start(); 74 } 75 76 /** 77 * Register callbacks in template class 78 * 79 * @param \Smarty_Internal_Template $_template 80 */ 81 private function register(Smarty_Internal_Template $_template) 82 { 83 $_template->startRenderCallbacks[] = array( 84 $this, 85 'startRender' 86 ); 87 $_template->endRenderCallbacks[] = array( 88 $this, 89 'endRender' 90 ); 91 $this->startRender($_template); 92 $this->isRegistered = true; 93 } 94 95 /** 96 * Start render callback 97 * 98 * @param \Smarty_Internal_Template $_template 99 */ 100 public function startRender(Smarty_Internal_Template $_template) 101 { 102 $this->countStack[] = $this->captureCount; 103 $this->captureCount = 0; 104 } 105 106 /** 107 * Close capture section 108 * 109 * @param \Smarty_Internal_Template $_template 110 * 111 * @throws \SmartyException 112 */ 113 public function close(Smarty_Internal_Template $_template) 114 { 115 if ($this->captureCount) { 116 list($buffer, $assign, $append) = array_pop($this->captureStack); 117 $this->captureCount--; 118 if (isset($assign)) { 119 $_template->assign($assign, ob_get_contents()); 120 } 121 if (isset($append)) { 122 $_template->append($append, ob_get_contents()); 123 } 124 $this->namedBuffer[ $buffer ] = ob_get_clean(); 125 } else { 126 $this->error($_template); 127 } 128 } 129 130 /** 131 * Error exception on not matching {capture}{/capture} 132 * 133 * @param \Smarty_Internal_Template $_template 134 * 135 * @throws \SmartyException 136 */ 137 public function error(Smarty_Internal_Template $_template) 138 { 139 throw new SmartyException("Not matching {capture}{/capture} in '{$_template->template_resource}'"); 140 } 141 142 /** 143 * Return content of named capture buffer by key or as array 144 * 145 * @param \Smarty_Internal_Template $_template 146 * @param string|null $name 147 * 148 * @return string|string[]|null 149 */ 150 public function getBuffer(Smarty_Internal_Template $_template, $name = null) 151 { 152 if (isset($name)) { 153 return isset($this->namedBuffer[ $name ]) ? $this->namedBuffer[ $name ] : null; 154 } else { 155 return $this->namedBuffer; 156 } 157 } 158 159 /** 160 * End render callback 161 * 162 * @param \Smarty_Internal_Template $_template 163 * 164 * @throws \SmartyException 165 */ 166 public function endRender(Smarty_Internal_Template $_template) 167 { 168 if ($this->captureCount) { 169 $this->error($_template); 170 } else { 171 $this->captureCount = array_pop($this->countStack); 172 } 173 } 174} 175