1  <?php
  2  /* Copyright (c)
  3   * - 2011, Michali Sarris (michali@yardinternet.nl)
  4   * - 2013, Geert Bergman (geert@scrivo.nl)
  5   * All rights reserved.
  6   *
  7   * Redistribution and use in source and binary forms, with or without
  8   * modification, are permitted provided that the following conditions are met:
  9   *
 10   * 1. Redistributions of source code must retain the above copyright notice,
 11   *    this list of conditions and the following disclaimer.
 12   * 2. Redistributions in binary form must reproduce the above copyright notice,
 13   *    this list of conditions and the following disclaimer in the documentation
 14   *    and/or other materials provided with the distribution.
 15   * 3. Neither the name of "Scrivo" nor the names of its contributors may be
 16   *    used to endorse or promote products derived from this software without
 17   *    specific prior written permission.
 18   *
 19   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 20   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 21   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 22   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 23   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 24   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 25   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 26   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 27   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 28   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 29   * POSSIBILITY OF SUCH DAMAGE.
 30   *
 31   * $Id: LayoutAction.php 841 2013-08-19 22:19:47Z geert $
 32   */
 33  
 34  /**
 35   * Implementation of the \Scrivo\Layout class.
 36   */
 37  
 38  namespace Scrivo;
 39  
 40  /**
 41   * The layout class provides a template system.
 42   *
 43   * By unsing this layout class you can break down a larger template
 44   * into smaller and manageble sections. These sections are named an can
 45   * be used in other sections.
 46   *
 47   * Consider the following data:
 48   *
 49   * <pre class="sh_php">
 50   * $data = new \stdClass;
 51   * $data->content = "Scrivo hello";
 52   * $data->menu = array("News", "Events", "Contact");
 53   * </pre>
 54   *
 55   * To display this data we first create a master template "master.tpl.php":
 56   *
 57   * <pre class="sh_php">
 58   * &lt;html lang="en_EN"&gt;
 59   *   &lt;body&gt;
 60   *     &lt;div class="menu"&gt;
 61   *       &lt;?php echo $this->getSection("menu"); ?&gt;
 62   *     &lt;/div&gt;
 63   *     &lt;div class="content"&gt;
 64   *       &lt;?php echo $this->getSection("content"); ?&gt;
 65   *     &lt;/div&gt;
 66   *   &lt;/body&gt;
 67   * &lt;/html&gt;
 68   * </pre>
 69   *
 70   * And another template file "sections.tpl.php" in which we define the sections:
 71   *
 72   * <pre class="sh_php">
 73   * &lt;?php
 74   * $this->beginSection("menu", true);
 75   * ?&gt;
 76   *     &lt;ul&gt;
 77   *     &lt;?php foreach ($data->menu as $m) { ?&gt;
 78   *         &lt;li&gt;&lt;?php echo $m?&gt;&lt;/li&gt;
 79   *     &lt;?php } ?&gt;
 80   *     &lt;/ul&gt;
 81   * ?&gt;
 82   * $this->endSection();
 83   *
 84   * $this->beginSection("content");
 85   * ?&gt;
 86   *     &lt;p&gt;&lt;?php echo $data->content?&gt;&lt;/p&gt;
 87   * &lt;?php
 88   * $this->endSection("content", true);
 89   * ?&gt;
 90   * </pre>
 91   *
 92   * Now we can apply the templates on the data using the following:
 93   *
 94   * <pre class="sh_php">
 95   * class MyLayout extends Layout {
 96   *     function apply($data) {
 97   *         include "sections.tpl.php";
 98   *         $this->useLayout("master.tpl.php");
 99   *         include $this->getLayout();
100   *     }
101   * }
102   * $l = new MyLayout();
103   * $l->apply($data);
104   * </pre>
105   */
106  class LayoutAction extends Action {
107  
108      /**
109       * Stack of section options.
110       * @var array
111       */
112      private $stored = array();
113  
114      /**
115       * An array containing the all the sections defined.
116       * @var array
117       */
118      private $sections = array();
119  
120      /**
121       * The layout used for rendering.
122       * @var array
123       */
124      private $layout "";
125  
126      /**
127       * Define the layout to use for rendering.
128       *
129       * If no layout is provided the previously defined layout will be returned.
130       *
131       * @param string $layout
132       *    The layout to use.
133       *
134       * @return string
135       */
136      function useLayout($layout null) {
137          if (is_null($layout)) {
138              return $this->layout;
139          }
140          else {
141              $this->layout $layout;
142          }
143      }
144  
145      /**
146       * Gets the currently defined layout to use for rendering.
147       *
148       * @return string
149       */
150      function getLayout() {
151          return $this->useLayout();
152      }
153  
154      /**
155       * Gets or sets options for defining a section.
156       *
157       * @param null|string $name
158       * @param null|bool $overwrite
159       * @return array
160       */
161      private function sectionOptions($name null$overwrite null) {
162          if (is_null($name)) {
163              return array_pop($this->stored);
164          } else {
165              array_push($this->stored, array($name$overwrite));
166          }
167      }
168  
169      /**
170       * Mark the beginning of a layout section.
171       *
172       * Buffers all output until the end of the section is marked.
173       *
174       * @param string $name
175       *    The name of the section (currently only present for readability of
176       *  the code where used).
177       * @param boolean $overwrite
178       *    Overwrite previous content if existing? Default will append it to
179       *  existing.
180       */
181      function beginSection($name$overwrite false) {
182          ob_start();
183          $this->sectionOptions($name$overwrite);
184  
185      }
186  
187      /**
188       * Mark the end of a layout section.
189       *
190       * Assigns all buffered output to the section with the provided name.
191       */
192      function endSection() {
193          list($name$overwrite) = $this->sectionOptions();
194          $this->setSection($nameob_get_clean(), $overwrite);
195      }
196  
197      /**
198       * Assigns provided content to a specific section.
199       *
200       * If no content is provided the stored content of the section will be
201       * returned.
202       *
203       * @param string $name
204       *    The section to set the content of.
205       * @param string $content
206       *    The content to assign to the section.
207       * @param boolean $overwrite
208       *    Overwrite previous content if existing? Default will append it to
209       *  existing.
210       *
211       * @return string
212       */
213      function setSection($name$content null$overwrite false) {
214          if (isset($this->sections[$name]) && !$overwrite) {
215              $this->sections[$name] .= $content;
216          } else {
217              $this->sections[$name] = $content;
218          }
219      }
220  
221      /**
222       * Retrieve the content of section with the provided name.
223       *
224       * @param string $name
225       *    The name of the section to get the content of.
226       *
227       * @return string
228       */
229      function getSection($name) {
230          return isset($this->sections[$name]) ? $this->sections[$name] : null;
231  
232      }
233  
234      /**
235       * Retrieves all sections.
236       *
237       * @return array
238       */
239      function getAllSections() {
240          return $this->sections;
241      }
242  
243      /**
244       * Uses a function to render the content of a section.
245       *
246       * @param string $name
247       *    The name of the section to render the content of.
248       * @param callable $function
249       *     The function which renders the content.
250       * @param array $parameters
251       *     Optional array of parameters which will be passed to the function.
252       */
253      function renderSection($name$function$parameters = array()) {
254          $this->beginSection($name);
255          call_user_func_array($function$parameters);
256          $this->endSection($name);
257      }
258  
259  }
260  
261  ?>

Documentation generated by phpDocumentor 2.0.0a12 and ScrivoDocumentor on August 29, 2013