/Template/src/source_code.php

https://github.com/F5/zetacomponents · PHP · 317 lines · 111 code · 16 blank · 190 comment · 13 complexity · 03cad2ed8cac611e4bfe24e27f8eb569 MD5 · raw file

  1. <?php
  2. /**
  3. * File containing the ezcTemplateSourceCode class
  4. *
  5. * Licensed to the Apache Software Foundation (ASF) under one
  6. * or more contributor license agreements. See the NOTICE file
  7. * distributed with this work for additional information
  8. * regarding copyright ownership. The ASF licenses this file
  9. * to you under the Apache License, Version 2.0 (the
  10. * "License"); you may not use this file except in compliance
  11. * with the License. You may obtain a copy of the License at
  12. *
  13. * http://www.apache.org/licenses/LICENSE-2.0
  14. *
  15. * Unless required by applicable law or agreed to in writing,
  16. * software distributed under the License is distributed on an
  17. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  18. * KIND, either express or implied. See the License for the
  19. * specific language governing permissions and limitations
  20. * under the License.
  21. *
  22. * @package Template
  23. * @version //autogen//
  24. * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
  25. * @access private
  26. */
  27. /**
  28. * Encapsulates information on a template file containing source code.
  29. *
  30. * This class is used by the manager when it parses template code and can be
  31. * used by code to read and write template code or remove template files in
  32. * a convenient way.
  33. *
  34. * Instantiate this class with the stream string and the optional arguments,
  35. * then call either load(), save() or delete() to perform the requested action.
  36. * The class will throw exceptions for failures so it is a good idea to call
  37. * isReadable(), isWriteable() or isAvailable() before any of these actions.
  38. *
  39. * For instance to display the content of a template file one can do:
  40. * <code>
  41. * $source = new ezcTemplateSourceCode( "templates/main.tpl" );
  42. * if ( $source->isReadable() )
  43. * {
  44. * $source->load();
  45. * echo $source->code;
  46. * }
  47. * else
  48. * {
  49. * echo "Cannot load template ", $source->stream, "\n";
  50. * }
  51. * </code>
  52. *
  53. * Similarly one can create template files with:
  54. * <code>
  55. * $source = new ezcTemplateSourceCode( "templates/left.tpl" );
  56. * $source->code = '{$left|str_capitalize}';
  57. * if ( !$source->isAvailable() )
  58. * {
  59. * $source->save();
  60. * }
  61. * else if ( $source->isWriteable() )
  62. * {
  63. * $source->save();
  64. * }
  65. * else
  66. * {
  67. * echo "Cannot save template ", $source->stream, "\n";
  68. * }
  69. * </code>
  70. *
  71. * To check if any source code has been loaded or set use hasCode().
  72. *
  73. * @property string $stream
  74. * The PHP stream path for the template source file.
  75. * @property string $resource
  76. * The resource string which requested this template.
  77. * @property string $code
  78. * The original template code taken from the template file or
  79. * other resource. Contains a string with the source code or
  80. * false if no code is read yet.
  81. * @property ezcTemplateOutputContext $context
  82. * The current context for the template code. Will be used for
  83. * parsing and run-time behaviour.
  84. *
  85. * @package Template
  86. * @version //autogen//
  87. * @access private
  88. */
  89. class ezcTemplateSourceCode
  90. {
  91. /**
  92. * Array that stores the property values.
  93. *
  94. * @var array(string=>mixed)
  95. */
  96. private $properties = array();
  97. /**
  98. * Property get
  99. *
  100. * @param string $name
  101. * @return mixed
  102. */
  103. public function __get( $name )
  104. {
  105. switch ( $name )
  106. {
  107. case 'stream':
  108. case 'resource':
  109. case 'code':
  110. case 'context':
  111. return $this->properties[$name];
  112. default:
  113. throw new ezcBasePropertyNotFoundException( $name );
  114. }
  115. }
  116. /**
  117. * Property set
  118. *
  119. * @param string $name
  120. * @param mixed $value
  121. * @return void
  122. */
  123. public function __set( $name, $value )
  124. {
  125. switch ( $name )
  126. {
  127. case 'stream':
  128. case 'resource':
  129. case 'code':
  130. case 'context':
  131. $this->properties[$name] = $value;
  132. break;
  133. default:
  134. throw new ezcBasePropertyNotFoundException( $name );
  135. }
  136. }
  137. /**
  138. * Property isset
  139. *
  140. * @param string $name
  141. * @return bool
  142. */
  143. public function __isset( $name )
  144. {
  145. switch ( $name )
  146. {
  147. case 'stream':
  148. case 'resource':
  149. case 'code':
  150. case 'context':
  151. return true;
  152. default:
  153. return false;
  154. }
  155. }
  156. /**
  157. * Initialises the source object with the code and output context.
  158. *
  159. * @param string $stream The actual PHP stream path for the template source
  160. * file.
  161. * @param string $resource The requested resource string, if false $stream
  162. * is used as value.
  163. * @param string $code The source code for the template.
  164. * @param ezcTemplateOutputContext $context The context for the parsing and
  165. * run-time behaviour, a value of null
  166. * means to use the current context in
  167. * the template manager.
  168. */
  169. public function __construct( $stream, $resource = false, $code = false, ezcTemplateOutputContext $context = null )
  170. {
  171. $this->stream = $stream;
  172. $this->resource = $resource;
  173. $this->code = $code;
  174. $this->context = $context;
  175. }
  176. /**
  177. * Loads the data from the PHP stream into the $code member variable.
  178. *
  179. * @throws ezcTemplateFileNotFoundException if the file does not exist on disk.
  180. * @throws ezcTemplateFileNotReadableException if the file cannot be read.
  181. *
  182. * @see isAvailable(), isReadable()
  183. *
  184. * Note: Calling this multiple times will re-init the $source variable.
  185. *
  186. * @return void
  187. */
  188. public function load()
  189. {
  190. if ( !file_exists( $this->stream ) )
  191. throw new ezcTemplateFileNotFoundException( $this->stream );
  192. if ( !is_readable( $this->stream ) )
  193. throw new ezcTemplateFileNotReadableException( $this->stream );
  194. $this->code = file_get_contents( $this->stream );
  195. }
  196. /**
  197. * Saves the data from $code member variable to the PHP stream.
  198. *
  199. * This method creates a backup from the exisiting template. The name of the
  200. * backup template appends a tilde (~). If a backup already exists,
  201. * this method overwrites the old backup.
  202. *
  203. * @throws ezcTemplateFileNotWritableException if the file cannot be written to.
  204. *
  205. * @see isWriteable()
  206. * Note: Storing the data will not record the template file in the system or
  207. * signal the changes, call the template manager to perform these tasks.
  208. *
  209. * Note: Calling this multiple times will overwrite the file contents over and
  210. * over again. And the backup contains the same information as the original.
  211. *
  212. * @return void
  213. */
  214. public function save()
  215. {
  216. if ( file_exists( $this->stream ) && !is_writeable( $this->stream ) )
  217. throw new ezcTemplateFileNotWriteableException( $this->stream );
  218. // Store data in a temporary file
  219. $tempName = dirname( $this->stream ) . '/#' . basename( $this->stream ) . '#';
  220. if ( file_put_contents( $tempName, $this->code, LOCK_EX ) === false )
  221. throw new ezcTemplateFileNotWriteableException( $this->stream );
  222. $backupName = $this->stream . '~';
  223. // Remove old backup (if it exists)
  224. if ( file_exists( $backupName ) &&
  225. !unlink( $backupName ) )
  226. {
  227. unlink( $tempName );
  228. throw new ezcTemplateFileFailedUnlinkException( $backupName );
  229. }
  230. // Make the current file (if it exists) a backup
  231. if ( file_exists( $this->stream ) &&
  232. !rename( $this->stream, $backupName ) )
  233. {
  234. unlink( $tempName );
  235. throw new ezcTemplateFileRenameFailedException( $this->stream, $backupName );
  236. }
  237. // Make the temporary file the current one
  238. if ( !rename( $tempName, $this->stream ) )
  239. {
  240. unlink( $tempName );
  241. rename( $backupName, $this->stream );
  242. throw new ezcTemplateFileRenamedFailedException( $tempName, $this->stream );
  243. }
  244. }
  245. /**
  246. * Deletes the file from the file system.
  247. *
  248. * @throws ezcTemplateFileNotFoundException if the file does not exist on disk.
  249. * @throws ezcTemplateFileFailedUnlinkException if the file could not be unlinked.
  250. *
  251. *
  252. * @see isAvailable()
  253. *
  254. * @return void
  255. */
  256. public function delete()
  257. {
  258. if ( !file_exists( $this->stream ) )
  259. throw new ezcTemplateFileNotFoundException( $this->stream );
  260. if ( !unlink( $this->stream ) )
  261. throw new ezcTemplateFileFailedUnlinkException( $this->stream );
  262. }
  263. /**
  264. * Checks if the template file exists on disk and can be read.
  265. *
  266. * @return bool
  267. */
  268. public function isAvailable()
  269. {
  270. return file_exists( $this->stream );
  271. }
  272. /**
  273. * Checks if the template file can be read from.
  274. *
  275. * @return bool
  276. */
  277. public function isReadable()
  278. {
  279. return is_readable( $this->stream );
  280. }
  281. /**
  282. * Checks if the template file can be written to.
  283. *
  284. * @return bool
  285. */
  286. public function isWriteable()
  287. {
  288. return is_writeable( $this->stream );
  289. }
  290. /**
  291. * Checks if source code has been loaded from the template file or set by PHP
  292. * code.
  293. *
  294. * @return bool
  295. */
  296. public function hasCode()
  297. {
  298. return $this->code !== false;
  299. }
  300. }
  301. ?>