/framework/Kolab_Format/lib/Horde/Kolab/Format/Xml/Type/Composite/Recurrence.php

https://github.com/ewandor/horde · PHP · 241 lines · 152 code · 16 blank · 73 comment · 49 complexity · 6e15c42603899bb1ce5f351a61bcb0f9 MD5 · raw file

  1. <?php
  2. /**
  3. * Handles recurrence data.
  4. *
  5. * PHP version 5
  6. *
  7. * @category Kolab
  8. * @package Kolab_Format
  9. * @author Gunnar Wrobel <wrobel@pardus.de>
  10. * @license http://www.horde.org/licenses/lgpl21 LGPL
  11. * @link http://www.horde.org/libraries/Horde_Kolab_Format
  12. */
  13. /**
  14. * Handles recurrence data.
  15. *
  16. * Copyright 2011-2012 Horde LLC (http://www.horde.org/)
  17. *
  18. * See the enclosed file COPYING for license information (LGPL). If you did not
  19. * receive this file, see
  20. * http://www.horde.org/licenses/lgpl21.
  21. *
  22. * @since Horde_Kolab_Format 1.1.0
  23. *
  24. * @category Kolab
  25. * @package Kolab_Format
  26. * @author Gunnar Wrobel <wrobel@pardus.de>
  27. * @license http://www.horde.org/licenses/lgpl21 LGPL
  28. * @link http://www.horde.org/libraries/Horde_Kolab_Format
  29. */
  30. class Horde_Kolab_Format_Xml_Type_Composite_Recurrence
  31. extends Horde_Kolab_Format_Xml_Type_Composite
  32. {
  33. protected $elements = array(
  34. 'interval' => 'Horde_Kolab_Format_Xml_Type_RecurrenceInterval',
  35. 'day' => 'Horde_Kolab_Format_Xml_Type_Multiple_String',
  36. 'daynumber' => 'Horde_Kolab_Format_Xml_Type_Integer',
  37. 'month' => 'Horde_Kolab_Format_Xml_Type_String_MaybeMissing',
  38. 'range' => 'Horde_Kolab_Format_Xml_Type_RecurrenceRange',
  39. 'exclusion' => 'Horde_Kolab_Format_Xml_Type_Multiple_Date',
  40. 'complete' => 'Horde_Kolab_Format_Xml_Type_Multiple_Date',
  41. );
  42. /**
  43. * Load the node value from the Kolab object.
  44. *
  45. * @param string $name The name of the the
  46. * attribute to be fetched.
  47. * @param array &$attributes The data array that
  48. * holds all attribute
  49. * values.
  50. * @param DOMNode $parent_node The parent node of the
  51. * node to be loaded.
  52. * @param Horde_Kolab_Format_Xml_Helper $helper A XML helper instance.
  53. * @param array $params Additiona parameters for
  54. * this parse operation.
  55. *
  56. * @return DOMNode|boolean The named DOMNode or false if no node value was
  57. * found.
  58. */
  59. public function load(
  60. $name,
  61. &$attributes,
  62. $parent_node,
  63. Horde_Kolab_Format_Xml_Helper $helper,
  64. $params = array()
  65. )
  66. {
  67. $result = parent::load($name, $attributes, $parent_node, $helper, $params);
  68. if ($node = $helper->findNodeRelativeTo('./' . $name, $parent_node)) {
  69. // Get the cycle type (must be present)
  70. $attributes['recurrence']['cycle'] = $node->getAttribute('cycle');
  71. // Get the sub type (may be present)
  72. $attributes['recurrence']['type'] = $node->getAttribute('type');
  73. }
  74. if (empty($attributes['recurrence'])) {
  75. return $result;
  76. }
  77. $recurrence = $attributes['recurrence'];
  78. if ($recurrence['interval'] < 0) {
  79. throw new Horde_Kolab_Format_Exception_ParseError(
  80. sprintf(
  81. 'Recurrence: interval cannot be below zero [Value: %s]!',
  82. $recurrence['interval']
  83. )
  84. );
  85. }
  86. if (empty($recurrence['cycle'])) {
  87. throw new Horde_Kolab_Format_Exception_ParseError('Recurrence: "cycle" attribute missing!');
  88. }
  89. if ($recurrence['cycle'] == 'weekly') {
  90. // Check for <day>
  91. if (!isset($recurrence['day']) || count($recurrence['day']) == 0) {
  92. throw new Horde_Kolab_Format_Exception_ParseError(
  93. 'Recurrence: day tag missing for weekly recurrence!'
  94. );
  95. }
  96. }
  97. // The code below is only for monthly or yearly recurrences
  98. if ($recurrence['cycle'] == 'monthly'
  99. || $recurrence['cycle'] == 'yearly') {
  100. if (!isset($recurrence['type'])) {
  101. throw new Horde_Kolab_Format_Exception_ParseError(
  102. 'Recurrence: type attribute missing!'
  103. );
  104. }
  105. if (!isset($recurrence['daynumber'])) {
  106. throw new Horde_Kolab_Format_Exception_ParseError(
  107. 'Recurrence: daynumber tag missing!'
  108. );
  109. }
  110. $daynumber = $recurrence['daynumber'];
  111. if ($daynumber < 0) {
  112. throw new Horde_Kolab_Format_Exception_ParseError(
  113. sprintf(
  114. 'Recurrence: daynumber cannot be below zero ["%s"]!',
  115. $daynumber
  116. )
  117. );
  118. }
  119. if ($recurrence['type'] == 'daynumber') {
  120. if ($recurrence['cycle'] == 'yearly' && $daynumber > 366) {
  121. throw new Horde_Kolab_Format_Exception_ParseError(
  122. sprintf(
  123. 'Recurrence: daynumber cannot be larger than 366 for yearly recurrences ["%s"]!',
  124. $daynumber
  125. )
  126. );
  127. } else if ($recurrence['cycle'] == 'monthly' && $daynumber > 31) {
  128. throw new Horde_Kolab_Format_Exception_ParseError(
  129. sprintf(
  130. 'Recurrence: daynumber cannot be larger than 31 for monthly recurrences ["%s"]!',
  131. $daynumber
  132. )
  133. );
  134. }
  135. } else if ($recurrence['type'] == 'weekday') {
  136. // daynumber is the week of the month
  137. if ($daynumber > 5) {
  138. throw new Horde_Kolab_Format_Exception_ParseError(
  139. sprintf(
  140. 'Recurrence: daynumber cannot be larger than 5 for type weekday ["%s"]!',
  141. $daynumber
  142. )
  143. );
  144. }
  145. // Check for <day>
  146. if (!isset($recurrence['day']) || count($recurrence['day']) == 0) {
  147. throw new Horde_Kolab_Format_Exception_ParseError(
  148. 'Recurrence: day tag missing for type weekday!'
  149. );
  150. }
  151. }
  152. if (($recurrence['type'] == 'monthday' || $recurrence['type'] == 'yearday')
  153. && $recurrence['cycle'] == 'monthly') {
  154. throw new Horde_Kolab_Format_Exception_ParseError(
  155. 'Recurrence: type monthday/yearday is only allowed for yearly recurrences'
  156. );
  157. }
  158. if ($recurrence['cycle'] == 'yearly') {
  159. if ($recurrence['type'] == 'monthday') {
  160. // daynumber and month
  161. if (!isset($recurrence['month'])) {
  162. throw new Horde_Kolab_Format_Exception_ParseError(
  163. 'Recurrence: month tag missing for type monthday'
  164. );
  165. }
  166. if ($daynumber > 31) {
  167. throw new Horde_Kolab_Format_Exception_ParseError(
  168. sprintf(
  169. 'Recurrence: daynumber cannot be larger than 31 for type monthday ["%s"]!',
  170. $daynumber
  171. )
  172. );
  173. }
  174. } else if ($recurrence['type'] == 'yearday') {
  175. if ($daynumber > 366) {
  176. throw new Horde_Kolab_Format_Exception_ParseError(
  177. sprintf(
  178. 'Recurrence: daynumber cannot be larger than 366 for type yearday ["%s"]!',
  179. $daynumber
  180. )
  181. );
  182. }
  183. }
  184. }
  185. }
  186. return $result;
  187. }
  188. /**
  189. * Update the specified attribute.
  190. *
  191. * @param string $name The name of the attribute
  192. * to be updated.
  193. * @param mixed $value The value to store.
  194. * @param DOMNode $parent_node The parent node of the
  195. * node that should be
  196. * updated.
  197. * @param Horde_Kolab_Format_Xml_Helper $helper A XML helper instance.
  198. * @param array $params The parameters for this
  199. * write operation.
  200. * @param DOMNode|NULL $old_node The previous value (or
  201. * null if there is none).
  202. *
  203. * @return DOMNode|boolean The new/updated child node or false if this
  204. * failed.
  205. *
  206. * @throws Horde_Kolab_Format_Exception If converting the data to XML failed.
  207. */
  208. public function saveNodeValue(
  209. $name,
  210. $value,
  211. $parent_node,
  212. Horde_Kolab_Format_Xml_Helper $helper,
  213. $params = array(),
  214. $old_node = false
  215. )
  216. {
  217. $node = parent::saveNodeValue($name, $value, $parent_node, $helper, $params, $old_node);
  218. // Add attributes
  219. $node->setAttribute('cycle', $value['cycle']);
  220. if (isset($value['type'])) {
  221. $node->setAttribute('type', $value['type']);
  222. }
  223. return $node;
  224. }
  225. }