vobject.php 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. <?php
  2. /**
  3. * @author Bart Visscher <bartv@thisnet.nl>
  4. * @author Felix Moeller <mail@felixmoeller.de>
  5. * @author Lukas Reschke <lukas@owncloud.com>
  6. * @author Morris Jobke <hey@morrisjobke.de>
  7. * @author Robin McCorkell <rmccorkell@karoshi.org.uk>
  8. * @author Susinthiran Sithamparanathan <chesusin@gmail.com>
  9. * @author Thomas Müller <thomas.mueller@tmit.eu>
  10. *
  11. * @copyright Copyright (c) 2015, ownCloud, Inc.
  12. * @license AGPL-3.0
  13. *
  14. * This code is free software: you can redistribute it and/or modify
  15. * it under the terms of the GNU Affero General Public License, version 3,
  16. * as published by the Free Software Foundation.
  17. *
  18. * This program is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU Affero General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU Affero General Public License, version 3,
  24. * along with this program. If not, see <http://www.gnu.org/licenses/>
  25. *
  26. */
  27. /**
  28. * This class provides a streamlined interface to the Sabre VObject classes
  29. */
  30. class OC_VObject{
  31. /** @var Sabre\VObject\Component */
  32. protected $vObject;
  33. /**
  34. * @return Sabre\VObject\Component
  35. */
  36. public function getVObject() {
  37. return $this->vObject;
  38. }
  39. /**
  40. * Parses the VObject
  41. * @param string $data VObject as string
  42. * @return Sabre\VObject\Reader|null
  43. */
  44. public static function parse($data) {
  45. try {
  46. Sabre\VObject\Property::$classMap['LAST-MODIFIED'] = 'Sabre\VObject\Property\DateTime';
  47. $vObject = Sabre\VObject\Reader::read($data);
  48. if ($vObject instanceof Sabre\VObject\Component) {
  49. $vObject = new OC_VObject($vObject);
  50. }
  51. return $vObject;
  52. } catch (Exception $e) {
  53. OC_Log::write('vobject', $e->getMessage(), OC_Log::ERROR);
  54. return null;
  55. }
  56. }
  57. /**
  58. * Escapes semicolons
  59. * @param array $value
  60. * @return string
  61. */
  62. public static function escapeSemicolons($value) {
  63. foreach($value as &$i ) {
  64. $i = implode("\\\\;", explode(';', $i));
  65. }
  66. return implode(';', $value);
  67. }
  68. /**
  69. * Creates an array out of a multivalue property
  70. * @param string $value
  71. * @return array
  72. */
  73. public static function unescapeSemicolons($value) {
  74. $array = explode(';', $value);
  75. $arrayCount = count($array);
  76. for($i = 0; $i < $arrayCount; $i++) {
  77. if(substr($array[$i], -2, 2)=="\\\\") {
  78. if(isset($array[$i+1])) {
  79. $array[$i] = substr($array[$i], 0, count($array[$i])-2).';'.$array[$i+1];
  80. unset($array[$i+1]);
  81. }
  82. else{
  83. $array[$i] = substr($array[$i], 0, count($array[$i])-2).';';
  84. }
  85. $i = $i - 1;
  86. }
  87. }
  88. return $array;
  89. }
  90. /**
  91. * Constructor
  92. * @param Sabre\VObject\Component|string $vobject_or_name
  93. */
  94. public function __construct($vobject_or_name) {
  95. if (is_object($vobject_or_name)) {
  96. $this->vObject = $vobject_or_name;
  97. } else {
  98. $this->vObject = new Sabre\VObject\Component($vobject_or_name);
  99. }
  100. }
  101. /**
  102. * @todo Write documentation
  103. * @param \OC_VObject|\Sabre\VObject\Component $item
  104. * @param null $itemValue
  105. */
  106. public function add($item, $itemValue = null) {
  107. if ($item instanceof OC_VObject) {
  108. $item = $item->getVObject();
  109. }
  110. $this->vObject->add($item, $itemValue);
  111. }
  112. /**
  113. * Add property to vobject
  114. * @param object $name of property
  115. * @param object $value of property
  116. * @param array|object $parameters of property
  117. * @return Sabre\VObject\Property newly created
  118. */
  119. public function addProperty($name, $value, $parameters=array()) {
  120. if(is_array($value)) {
  121. $value = OC_VObject::escapeSemicolons($value);
  122. }
  123. $property = new Sabre\VObject\Property( $name, $value );
  124. foreach($parameters as $name => $value) {
  125. $property->parameters[] = new Sabre\VObject\Parameter($name, $value);
  126. }
  127. $this->vObject->add($property);
  128. return $property;
  129. }
  130. public function setUID() {
  131. $uid = substr(md5(rand().time()), 0, 10);
  132. $this->vObject->add('UID', $uid);
  133. }
  134. /**
  135. * @todo Write documentation
  136. * @param mixed $name
  137. * @param string $string
  138. */
  139. public function setString($name, $string) {
  140. if ($string != '') {
  141. $string = strtr($string, array("\r\n"=>"\n"));
  142. $this->vObject->__set($name, $string);
  143. }else{
  144. $this->vObject->__unset($name);
  145. }
  146. }
  147. /**
  148. * Sets or unsets the Date and Time for a property.
  149. * When $datetime is set to 'now', use the current time
  150. * When $datetime is null, unset the property
  151. *
  152. * @param string $name
  153. * @param DateTime $datetime
  154. * @param int $dateType
  155. * @return void
  156. */
  157. public function setDateTime($name, $datetime, $dateType=Sabre\VObject\Property\DateTime::LOCALTZ) {
  158. if ($datetime == 'now') {
  159. $datetime = new DateTime();
  160. }
  161. if ($datetime instanceof DateTime) {
  162. $datetime_element = new Sabre\VObject\Property\DateTime($name);
  163. $datetime_element->setDateTime($datetime, $dateType);
  164. $this->vObject->__set($name, $datetime_element);
  165. }else{
  166. $this->vObject->__unset($name);
  167. }
  168. }
  169. /**
  170. * @todo Write documentation
  171. * @param string $name
  172. * @return string
  173. */
  174. public function getAsString($name) {
  175. return $this->vObject->__isset($name) ?
  176. $this->vObject->__get($name)->value :
  177. '';
  178. }
  179. /**
  180. * @todo Write documentation
  181. * @param string $name
  182. * @return array
  183. */
  184. public function getAsArray($name) {
  185. $values = array();
  186. if ($this->vObject->__isset($name)) {
  187. $values = explode(',', $this->getAsString($name));
  188. $values = array_map('trim', $values);
  189. }
  190. return $values;
  191. }
  192. /**
  193. * @todo Write documentation
  194. * @param string $name
  195. * @return array|OC_VObject|\Sabre\VObject\Property
  196. */
  197. public function &__get($name) {
  198. if ($name == 'children') {
  199. return $this->vObject->children;
  200. }
  201. $return = $this->vObject->__get($name);
  202. if ($return instanceof Sabre\VObject\Component) {
  203. $return = new OC_VObject($return);
  204. }
  205. return $return;
  206. }
  207. /**
  208. * @todo Write documentation
  209. * @param string $name
  210. * @param string $value
  211. */
  212. public function __set($name, $value) {
  213. return $this->vObject->__set($name, $value);
  214. }
  215. /**
  216. * @todo Write documentation
  217. * @param string $name
  218. */
  219. public function __unset($name) {
  220. return $this->vObject->__unset($name);
  221. }
  222. /**
  223. * @todo Write documentation
  224. * @param string $name
  225. * @return bool
  226. */
  227. public function __isset($name) {
  228. return $this->vObject->__isset($name);
  229. }
  230. /**
  231. * @todo Write documentation
  232. * @param callable $function
  233. * @param array $arguments
  234. * @return mixed
  235. */
  236. public function __call($function, $arguments) {
  237. return call_user_func_array(array($this->vObject, $function), $arguments);
  238. }
  239. }