Node.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. <?php
  2. /**
  3. * Base node-class
  4. *
  5. * The node class implements the method used by both the File and the Directory classes
  6. *
  7. * @package Sabre
  8. * @subpackage DAV
  9. * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
  10. * @author Evert Pot (http://www.rooftopsolutions.nl/)
  11. * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
  12. */
  13. abstract class Sabre_DAV_FSExt_Node extends Sabre_DAV_FS_Node implements Sabre_DAV_IProperties {
  14. /**
  15. * Updates properties on this node,
  16. *
  17. * @param array $properties
  18. * @see Sabre_DAV_IProperties::updateProperties
  19. * @return bool|array
  20. */
  21. public function updateProperties($properties) {
  22. $resourceData = $this->getResourceData();
  23. foreach($properties as $propertyName=>$propertyValue) {
  24. // If it was null, we need to delete the property
  25. if (is_null($propertyValue)) {
  26. if (isset($resourceData['properties'][$propertyName])) {
  27. unset($resourceData['properties'][$propertyName]);
  28. }
  29. } else {
  30. $resourceData['properties'][$propertyName] = $propertyValue;
  31. }
  32. }
  33. $this->putResourceData($resourceData);
  34. return true;
  35. }
  36. /**
  37. * Returns a list of properties for this nodes.;
  38. *
  39. * The properties list is a list of propertynames the client requested, encoded as xmlnamespace#tagName, for example: http://www.example.org/namespace#author
  40. * If the array is empty, all properties should be returned
  41. *
  42. * @param array $properties
  43. * @return array
  44. */
  45. function getProperties($properties) {
  46. $resourceData = $this->getResourceData();
  47. // if the array was empty, we need to return everything
  48. if (!$properties) return $resourceData['properties'];
  49. $props = array();
  50. foreach($properties as $property) {
  51. if (isset($resourceData['properties'][$property])) $props[$property] = $resourceData['properties'][$property];
  52. }
  53. return $props;
  54. }
  55. /**
  56. * Returns the path to the resource file
  57. *
  58. * @return string
  59. */
  60. protected function getResourceInfoPath() {
  61. list($parentDir) = Sabre_DAV_URLUtil::splitPath($this->path);
  62. return $parentDir . '/.sabredav';
  63. }
  64. /**
  65. * Returns all the stored resource information
  66. *
  67. * @return array
  68. */
  69. protected function getResourceData() {
  70. $path = $this->getResourceInfoPath();
  71. if (!file_exists($path)) return array('properties' => array());
  72. // opening up the file, and creating a shared lock
  73. $handle = fopen($path,'r');
  74. flock($handle,LOCK_SH);
  75. $data = '';
  76. // Reading data until the eof
  77. while(!feof($handle)) {
  78. $data.=fread($handle,8192);
  79. }
  80. // We're all good
  81. fclose($handle);
  82. // Unserializing and checking if the resource file contains data for this file
  83. $data = unserialize($data);
  84. if (!isset($data[$this->getName()])) {
  85. return array('properties' => array());
  86. }
  87. $data = $data[$this->getName()];
  88. if (!isset($data['properties'])) $data['properties'] = array();
  89. return $data;
  90. }
  91. /**
  92. * Updates the resource information
  93. *
  94. * @param array $newData
  95. * @return void
  96. */
  97. protected function putResourceData(array $newData) {
  98. $path = $this->getResourceInfoPath();
  99. // opening up the file, and creating a shared lock
  100. $handle = fopen($path,'a+');
  101. flock($handle,LOCK_EX);
  102. $data = '';
  103. rewind($handle);
  104. // Reading data until the eof
  105. while(!feof($handle)) {
  106. $data.=fread($handle,8192);
  107. }
  108. // Unserializing and checking if the resource file contains data for this file
  109. $data = unserialize($data);
  110. $data[$this->getName()] = $newData;
  111. ftruncate($handle,0);
  112. rewind($handle);
  113. fwrite($handle,serialize($data));
  114. fclose($handle);
  115. }
  116. /**
  117. * Renames the node
  118. *
  119. * @param string $name The new name
  120. * @return void
  121. */
  122. public function setName($name) {
  123. list($parentPath, ) = Sabre_DAV_URLUtil::splitPath($this->path);
  124. list(, $newName) = Sabre_DAV_URLUtil::splitPath($name);
  125. $newPath = $parentPath . '/' . $newName;
  126. // We're deleting the existing resourcedata, and recreating it
  127. // for the new path.
  128. $resourceData = $this->getResourceData();
  129. $this->deleteResourceData();
  130. rename($this->path,$newPath);
  131. $this->path = $newPath;
  132. $this->putResourceData($resourceData);
  133. }
  134. /**
  135. * @return bool
  136. */
  137. public function deleteResourceData() {
  138. // When we're deleting this node, we also need to delete any resource information
  139. $path = $this->getResourceInfoPath();
  140. if (!file_exists($path)) return true;
  141. // opening up the file, and creating a shared lock
  142. $handle = fopen($path,'a+');
  143. flock($handle,LOCK_EX);
  144. $data = '';
  145. rewind($handle);
  146. // Reading data until the eof
  147. while(!feof($handle)) {
  148. $data.=fread($handle,8192);
  149. }
  150. // Unserializing and checking if the resource file contains data for this file
  151. $data = unserialize($data);
  152. if (isset($data[$this->getName()])) unset($data[$this->getName()]);
  153. ftruncate($handle,0);
  154. rewind($handle);
  155. fwrite($handle,serialize($data));
  156. fclose($handle);
  157. return true;
  158. }
  159. public function delete() {
  160. return $this->deleteResourceData();
  161. }
  162. }