PageRenderTime 46ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

/inc/popoon/components/generators/directory.php

https://github.com/chregu/fluxcms
PHP | 254 lines | 135 code | 35 blank | 84 comment | 40 complexity | 83d5b0759485a0dca6cf568125a00f1b MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, Apache-2.0, LGPL-2.1
  1. <?php
  2. // +----------------------------------------------------------------------+
  3. // | popoon |
  4. // +----------------------------------------------------------------------+
  5. // | Copyright (c) 2001-2006 Bitflux GmbH |
  6. // | Copyright (c) 2003 Mike Hommey |
  7. // +----------------------------------------------------------------------+
  8. // | Licensed under the Apache License, Version 2.0 (the "License"); |
  9. // | you may not use this file except in compliance with the License. |
  10. // | You may obtain a copy of the License at |
  11. // | http://www.apache.org/licenses/LICENSE-2.0 |
  12. // | Unless required by applicable law or agreed to in writing, software |
  13. // | distributed under the License is distributed on an "AS IS" BASIS, |
  14. // | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
  15. // | implied. See the License for the specific language governing |
  16. // | permissions and limitations under the License. |
  17. // +----------------------------------------------------------------------+
  18. // | Author: Mike Hommey <mh@glandium.org> |
  19. // | Christian Stocker <chregu@bitflux.ch> |
  20. // | Iván Montes <imontes@imaginocreativa.com> |
  21. // +----------------------------------------------------------------------+
  22. //
  23. // $Id$
  24. include_once('popoon/components/generator.php');
  25. /**
  26. * This class returns xml from directory listing
  27. *
  28. * The "dateFormat" parameter should be a suitable format string for strftime()
  29. *
  30. * @author Mike Hommey <mh@glandium.org>
  31. * @version $Id$
  32. * @package popoon
  33. * @note Reversed sorting using 'directory' is somewhat broken :(
  34. * include and exclude patterns are a bit limited in my opinion, although I'm not
  35. * sure how they're handled in cocoon.
  36. * The only parameter missing from the cocoon implementation is the 'root' one.
  37. */
  38. class popoon_components_generators_directory extends popoon_components_generator {
  39. protected $mimeType;
  40. protected $ns = 'http://apache.org/cocoon/directory/2.0';
  41. protected $strDateFormat; // strftime format string
  42. protected $sortBy;
  43. protected $sortDir = false;
  44. protected $sortOrder;
  45. protected $includePattern = false;
  46. protected $excludePattern = false;
  47. /**
  48. * Constructor, does nothing at the moment
  49. */
  50. function __construct (&$sitemap) {
  51. parent::__construct($sitemap);
  52. }
  53. /**
  54. * generates an xml-DomDocument out of the xml-file
  55. *
  56. * @access public
  57. * @returns object DomDocument XML-Document
  58. */
  59. function DomStart(&$xml) {
  60. $this->mimeType = $this->getParameterDefault('mimeType');
  61. if ($this->mimeType && !function_exists("mime_content_type")) {
  62. $this->mimeType = false;
  63. }
  64. if (! $this->strDateFormat = $this->getParameterDefault('dateFormat')) {
  65. $this->strDateFormat = '%c'; //use current locale default
  66. }
  67. $this->includePattern = $this->getParameterDefault('include');
  68. $this->excludePattern = $this->getParameterDefault('exclude');
  69. //setup some flags to handle the sorting
  70. $this->sortBy = $this->getParameterDefault('sort');
  71. if ($this->sortBy === 'date') $this->sortBy = 'lastModified';
  72. if ($this->sortBy === 'directory') {
  73. $this->sortBy = 'name';
  74. $this->sortDir = true;
  75. }
  76. $this->sortOrder = (strtolower($this->getParameterDefault('reverse')) === 'true')?-1:1;
  77. $src = $this->getAttrib('src');
  78. $xml = new DOMDocument('1.0');
  79. $root = $xml->createElementNs($this->ns,'directory');
  80. $xml->appendChild($root);
  81. if (! $depth = $this->getParameterDefault('depth')) {
  82. $depth = 1;
  83. }
  84. if ($this->read_directory($xml,$root,$src, $depth)) {
  85. $stat = stat($this->sitemap->base_dir.'/'.$src);
  86. $root->setAttribute('requested','true');
  87. $root->setAttribute('size',$stat['size']);
  88. $root->setAttribute('lastModified', $stat['mtime']);
  89. $root->setAttribute('date', $this->formatDate($stat['mtime']));
  90. if ($this->sortBy) $root->setAttribute('sort', $this->getParameterDefault('sort'));
  91. $root->setAttribute('reverse', ($this->sortOrder==1)?'false':'true');
  92. } else {
  93. $xml = NULL;
  94. }
  95. return True;
  96. }
  97. function read_directory($dom, $parent, $directory, $depth = 1) {
  98. if (is_dir($directory) && ($dh = @opendir($directory))) {
  99. while (($file = readdir($dh)) !== false) {
  100. if (($file == ".") || ($file == "..")) continue;
  101. //check include and exclude patterns
  102. if ($this->includePattern && !preg_match($this->includePattern, $directory.'/'.$file)) continue;
  103. if ($this->excludePattern && preg_match($this->excludePattern, $directory.'/'.$file)) continue;
  104. $path = $directory.'/'.$file;
  105. while ($path && is_link($path)) { //get the real file
  106. $path = readlink($path);
  107. }
  108. if (is_file($path)) {
  109. $node = $dom->createElementNs($this->ns, 'file');
  110. } else if (is_dir($path)) {
  111. $node = $dom->createElementNs($this->ns, 'directory');
  112. } else {
  113. continue; //just in case :)
  114. }
  115. $node->setAttribute('name', $file);
  116. $info = $this->getInfo($path);
  117. foreach ($info as $k => $v) {
  118. $node->setAttribute($k, $v);
  119. }
  120. //performs the sorting
  121. $done = false;
  122. if ($this->sortBy) {
  123. foreach ($parent->childNodes as $child) {
  124. if (
  125. ($this->sortDir && $child->tagName == 'file' && $node->tagName == 'directory') ||
  126. (strcmp($child->getAttribute($this->sortBy), $node->getAttribute($this->sortBy)) == $this->sortOrder)
  127. ) {
  128. $node = $parent->insertBefore($node, $child);
  129. $done = true;
  130. break;
  131. }
  132. }
  133. }
  134. if (! $done) $parent->appendChild($node);
  135. if (is_dir($path) and ($depth > 1)) {
  136. $this->read_directory($dom, $node, $path, $depth - 1);
  137. }
  138. } //while
  139. closedir($dh);
  140. return true;
  141. } else {
  142. return false;
  143. }
  144. }
  145. function formatDate($timestamp) {
  146. if ($timestamp) return strftime($this->strDateFormat, $timestamp);
  147. }
  148. /**
  149. * gets information about a directory entry
  150. * Tip: Extend this method to add custom metadata to files like MP3, images ...
  151. *
  152. * @access public
  153. * @returns array
  154. */
  155. function getInfo($entry) {
  156. $info = array();
  157. $stat = stat($entry);
  158. //try to fetch details
  159. if ($this->mimeType) {
  160. $mimeType = mime_content_type($directory.'/'.$file);
  161. if (strpos($mimeType, "image") === 0) {
  162. $size = getimagesize($directory.'/'.$file);
  163. $info['imageWidth'] = $size[0];
  164. $info['imageHeight'] = $size[1];
  165. }
  166. $info['mimeType'] = $mimeType;
  167. }
  168. $info['size'] = $stat['size'];
  169. $info['lastModified'] = $stat['mtime'];
  170. $info['date'] = $this->formatDate($stat['mtime']);
  171. return $info;
  172. }
  173. /* CACHING STUFF */
  174. /**
  175. * Generate cacheKey
  176. *
  177. * Calls the method inherited from 'Component'
  178. *
  179. * @param array attributes
  180. * @param int last cacheKey
  181. * @see generateKeyDefault()
  182. */
  183. function generateKey($attribs, $keyBefore){
  184. return($this->generateKeyDefault($attribs, $keyBefore));
  185. }
  186. /** Generate validityObject
  187. *
  188. * This is common to all "readers", you'll find the same code there.
  189. * I'm thinking about making a method in the class component named generateValidityFile() or alike
  190. * instead of having the same code everywhere..
  191. *
  192. * @author Hannes Gassert <hannes.gassert@unifr.ch>
  193. * @see checkvalidity()
  194. * @return array $validityObject contains the components attributes plus file modification time and time of last access.
  195. */
  196. function generateValidity(){
  197. $validityObject = $this->attribs;
  198. $src = $this->getAttrib('src');
  199. $validityObject['filemtime'] = filemtime($src);
  200. $validityObject['fileatime'] = fileatime($src);
  201. return($validityObject);
  202. }
  203. /**
  204. * Check validity of a validityObject from cache
  205. *
  206. * This implements only the most simple form: If there's no fresher version, take that from cache.
  207. * I guess we'll need some more refined criteria..
  208. *
  209. * @return bool true if the validityObject indicates that the cached version can be used, false otherwise.
  210. * @param object validityObject
  211. */
  212. function checkValidity($validityObject){
  213. return(isset($validityObject['src']) &&
  214. isset($validityObject['filemtime']) &&
  215. file_exists($validityObject['src']) &&
  216. ($validityObject['filemtime'] == filemtime($validityObject['src'])));
  217. }
  218. }
  219. ?>