PageRenderTime 54ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/connector/sabre/node.php

https://github.com/sezuan/core
PHP | 227 lines | 108 code | 32 blank | 87 comment | 15 complexity | 853acfcd07559a67d7e634effb873e53 MD5 | raw file
Possible License(s): AGPL-3.0, AGPL-1.0, MPL-2.0-no-copyleft-exception
  1. <?php
  2. /**
  3. * ownCloud
  4. *
  5. * @author Jakob Sack
  6. * @copyright 2011 Jakob Sack kde@jakobsack.de
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
  10. * License as published by the Free Software Foundation; either
  11. * version 3 of the License, or any later version.
  12. *
  13. * This library is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
  17. *
  18. * You should have received a copy of the GNU Affero General Public
  19. * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  20. *
  21. */
  22. abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IProperties {
  23. const GETETAG_PROPERTYNAME = '{DAV:}getetag';
  24. const LASTMODIFIED_PROPERTYNAME = '{DAV:}lastmodified';
  25. /**
  26. * Allow configuring the method used to generate Etags
  27. *
  28. * @var array(class_name, function_name)
  29. */
  30. public static $ETagFunction = null;
  31. /**
  32. * The path to the current node
  33. *
  34. * @var string
  35. */
  36. protected $path;
  37. /**
  38. * node fileinfo cache
  39. * @var array
  40. */
  41. protected $fileinfo_cache;
  42. /**
  43. * node properties cache
  44. * @var array
  45. */
  46. protected $property_cache = null;
  47. /**
  48. * @brief Sets up the node, expects a full path name
  49. * @param string $path
  50. * @return void
  51. */
  52. public function __construct($path) {
  53. $this->path = $path;
  54. }
  55. /**
  56. * @brief Returns the name of the node
  57. * @return string
  58. */
  59. public function getName() {
  60. list(, $name) = Sabre_DAV_URLUtil::splitPath($this->path);
  61. return $name;
  62. }
  63. /**
  64. * @brief Renames the node
  65. * @param string $name The new name
  66. * @return void
  67. */
  68. public function setName($name) {
  69. list($parentPath, ) = Sabre_DAV_URLUtil::splitPath($this->path);
  70. list(, $newName) = Sabre_DAV_URLUtil::splitPath($name);
  71. $newPath = $parentPath . '/' . $newName;
  72. $oldPath = $this->path;
  73. \OC\Files\Filesystem::rename($this->path, $newPath);
  74. $this->path = $newPath;
  75. $query = OC_DB::prepare( 'UPDATE `*PREFIX*properties` SET `propertypath` = ?'
  76. .' WHERE `userid` = ? AND `propertypath` = ?' );
  77. $query->execute( array( $newPath, OC_User::getUser(), $oldPath ));
  78. }
  79. public function setFileinfoCache($fileinfo_cache)
  80. {
  81. $this->fileinfo_cache = $fileinfo_cache;
  82. }
  83. /**
  84. * @brief Ensure that the fileinfo cache is filled
  85. * @note Uses OC_FileCache or a direct stat
  86. */
  87. protected function getFileinfoCache() {
  88. if (!isset($this->fileinfo_cache)) {
  89. if ($fileinfo_cache = \OC\Files\Filesystem::getFileInfo($this->path)) {
  90. } else {
  91. $fileinfo_cache = \OC\Files\Filesystem::stat($this->path);
  92. }
  93. $this->fileinfo_cache = $fileinfo_cache;
  94. }
  95. }
  96. public function setPropertyCache($property_cache)
  97. {
  98. $this->property_cache = $property_cache;
  99. }
  100. /**
  101. * @brief Returns the last modification time, as a unix timestamp
  102. * @return int
  103. */
  104. public function getLastModified() {
  105. $this->getFileinfoCache();
  106. return $this->fileinfo_cache['mtime'];
  107. }
  108. /**
  109. * sets the last modification time of the file (mtime) to the value given
  110. * in the second parameter or to now if the second param is empty.
  111. * Even if the modification time is set to a custom value the access time is set to now.
  112. */
  113. public function touch($mtime) {
  114. \OC\Files\Filesystem::touch($this->path, $mtime);
  115. }
  116. /**
  117. * @brief Updates properties on this node,
  118. * @param array $mutations
  119. * @see Sabre_DAV_IProperties::updateProperties
  120. * @return bool|array
  121. */
  122. public function updateProperties($properties) {
  123. $existing = $this->getProperties(array());
  124. foreach($properties as $propertyName => $propertyValue) {
  125. // If it was null, we need to delete the property
  126. if (is_null($propertyValue)) {
  127. if(array_key_exists( $propertyName, $existing )) {
  128. $query = OC_DB::prepare( 'DELETE FROM `*PREFIX*properties`'
  129. .' WHERE `userid` = ? AND `propertypath` = ? AND `propertyname` = ?' );
  130. $query->execute( array( OC_User::getUser(), $this->path, $propertyName ));
  131. }
  132. }
  133. else {
  134. if( strcmp( $propertyName, self::GETETAG_PROPERTYNAME) === 0 ) {
  135. \OC\Files\Filesystem::putFileInfo($this->path, array('etag'=> $propertyValue));
  136. } elseif( strcmp( $propertyName, self::LASTMODIFIED_PROPERTYNAME) === 0 ) {
  137. $this->touch($propertyValue);
  138. } else {
  139. if(!array_key_exists( $propertyName, $existing )) {
  140. $query = OC_DB::prepare( 'INSERT INTO `*PREFIX*properties`'
  141. .' (`userid`,`propertypath`,`propertyname`,`propertyvalue`) VALUES(?,?,?,?)' );
  142. $query->execute( array( OC_User::getUser(), $this->path, $propertyName,$propertyValue ));
  143. } else {
  144. $query = OC_DB::prepare( 'UPDATE `*PREFIX*properties` SET `propertyvalue` = ?'
  145. .' WHERE `userid` = ? AND `propertypath` = ? AND `propertyname` = ?' );
  146. $query->execute( array( $propertyValue,OC_User::getUser(), $this->path, $propertyName ));
  147. }
  148. }
  149. }
  150. }
  151. $this->setPropertyCache(null);
  152. return true;
  153. }
  154. /**
  155. * @brief Returns a list of properties for this nodes.;
  156. * @param array $properties
  157. * @return array
  158. * @note The properties list is a list of propertynames the client
  159. * requested, encoded as xmlnamespace#tagName, for example:
  160. * http://www.example.org/namespace#author If the array is empty, all
  161. * properties should be returned
  162. */
  163. public function getProperties($properties) {
  164. if (is_null($this->property_cache)) {
  165. $sql = 'SELECT * FROM `*PREFIX*properties` WHERE `userid` = ? AND `propertypath` = ?';
  166. $result = OC_DB::executeAudited( $sql, array( OC_User::getUser(), $this->path ) );
  167. $this->property_cache = array();
  168. while( $row = $result->fetchRow()) {
  169. $this->property_cache[$row['propertyname']] = $row['propertyvalue'];
  170. }
  171. $this->property_cache[self::GETETAG_PROPERTYNAME] = $this->getETagPropertyForPath($this->path);
  172. }
  173. // if the array was empty, we need to return everything
  174. if(count($properties) == 0) {
  175. return $this->property_cache;
  176. }
  177. $props = array();
  178. foreach($properties as $property) {
  179. if (isset($this->property_cache[$property])) $props[$property] = $this->property_cache[$property];
  180. }
  181. return $props;
  182. }
  183. /**
  184. * Returns the ETag surrounded by double-quotes for this path.
  185. * @param string $path Path of the file
  186. * @return string|null Returns null if the ETag can not effectively be determined
  187. */
  188. static public function getETagPropertyForPath($path) {
  189. $data = \OC\Files\Filesystem::getFileInfo($path);
  190. if (isset($data['etag'])) {
  191. return '"'.$data['etag'].'"';
  192. }
  193. return null;
  194. }
  195. }