1: <?php
2: /**
3: * Handles attributes with multiple values.
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: /**
15: * Handles attributes with multiple values.
16: *
17: * Copyright 2011-2012 Horde LLC (http://www.horde.org/)
18: *
19: * See the enclosed file COPYING for license information (LGPL). If you did not
20: * receive this file, see
21: * http://www.horde.org/licenses/lgpl21.
22: *
23: * @since Horde_Kolab_Format 1.1.0
24: *
25: * @category Kolab
26: * @package Kolab_Format
27: * @author Gunnar Wrobel <wrobel@pardus.de>
28: * @license http://www.horde.org/licenses/lgpl21 LGPL
29: * @link http://www.horde.org/libraries/Horde_Kolab_Format
30: */
31: class Horde_Kolab_Format_Xml_Type_Multiple
32: extends Horde_Kolab_Format_Xml_Type_Base
33: {
34: /**
35: * The class name representing the element that can occur multiple times.
36: *
37: * @var string
38: */
39: protected $element;
40:
41: /**
42: * Indicate which value type is expected.
43: *
44: * @var int
45: */
46: protected $value = Horde_Kolab_Format_Xml::VALUE_MAYBE_MISSING;
47:
48: /**
49: * A default value if required.
50: *
51: * @var string
52: */
53: protected $default;
54:
55: /**
56: * Load the node value from the Kolab object.
57: *
58: * @param string $name The name of the the
59: * attribute to be fetched.
60: * @param array &$attributes The data array that
61: * holds all attribute
62: * values.
63: * @param DOMNode $parent_node The parent node of the
64: * node to be loaded.
65: * @param Horde_Kolab_Format_Xml_Helper $helper A XML helper instance.
66: * @param array $params Additiona parameters for
67: * this parse operation.
68: *
69: * @return DOMNode|boolean The named DOMNode or false if no node value was
70: * found.
71: */
72: public function load(
73: $name,
74: &$attributes,
75: $parent_node,
76: Horde_Kolab_Format_Xml_Helper $helper,
77: $params = array()
78: )
79: {
80: $children = $helper->findNodesRelativeTo('./' . $name, $parent_node);
81: if ($children->length > 0) {
82: $sub_type = $this->createSubType($this->element, $params);
83: $result = array();
84: foreach ($children as $child) {
85: $result[] = $sub_type->loadNodeValue(
86: $child, $helper, $params
87: );
88: }
89: $attributes[$name] = $result;
90: } else {
91: $attributes[$name] = $this->loadMissing($name, $params);
92: }
93: return false;
94: }
95:
96: /**
97: * Update the specified attribute.
98: *
99: * @param string $name The name of the the
100: * attribute to be updated.
101: * @param array $attributes The data array that holds
102: * all attribute values.
103: * @param DOMNode $parent_node The parent node of the
104: * node that should be
105: * updated.
106: * @param Horde_Kolab_Format_Xml_Helper $helper A XML helper instance.
107: * @param array $params Additional parameters
108: * for this write operation.
109: *
110: * @return DOMNode|boolean The new/updated child node or false if this
111: * failed.
112: *
113: * @throws Horde_Kolab_Format_Exception If converting the data to XML failed.
114: */
115: public function save(
116: $name,
117: $attributes,
118: $parent_node,
119: Horde_Kolab_Format_Xml_Helper $helper,
120: $params = array()
121: )
122: {
123: $children = $helper->findNodesRelativeTo(
124: './' . $name, $parent_node
125: );
126:
127: if (!isset($attributes[$name])) {
128: if ($children->length == 0) {
129: if ($this->value == Horde_Kolab_Format_Xml::VALUE_MAYBE_MISSING ||
130: ($this->value == Horde_Kolab_Format_Xml::VALUE_NOT_EMPTY &&
131: $this->isRelaxed($params))) {
132: return false;
133: }
134: } else {
135: if ($this->value == Horde_Kolab_Format_Xml::VALUE_MAYBE_MISSING) {
136: /** Client indicates that the value should get removed */
137: $helper->removeNodes($parent_node, $name);
138: return false;
139: } else {
140: return $children;
141: }
142: }
143: }
144:
145: //@todo What is required to get around this overwriting of the old values?
146: $helper->removeNodes($parent_node, $name);
147: return $this->_writeMultiple(
148: $parent_node,
149: $name,
150: $this->generateWriteValue($name, $attributes, $params),
151: $helper,
152: $params
153: );
154: }
155:
156: /**
157: * Generate the value that should be written to the node. Override in the
158: * extending classes.
159: *
160: * @param string $name The name of the the attribute
161: * to be updated.
162: * @param array $attributes The data array that holds all
163: * attribute values.
164: * @param array $params The parameters for this write operation.
165: *
166: * @return mixed The value to be written.
167: */
168: protected function generateWriteValue($name, $attributes, $params)
169: {
170: if (isset($attributes[$name])) {
171: return $attributes[$name];
172: } else {
173: return $this->loadMissing($name, $params);
174: }
175: }
176:
177: /**
178: * Write multiple values to one parent node.
179: *
180: * @param DOMNode $parent_node The parent node of the
181: * node that should be
182: * updated.
183: * @param string $name The name of the the
184: * attribute to be updated.
185: * @param array $values The values to write.
186: * @param Horde_Kolab_Format_Xml_Helper $helper A XML helper instance.
187: * @param array $params The parameters for this
188: * write operation.
189: *
190: * @return array The list of new/updated child nodes.
191: *
192: * @throws Horde_Kolab_Format_Exception If converting the data to XML failed.
193: */
194: private function _writeMultiple(
195: $parent_node,
196: $name,
197: $values,
198: Horde_Kolab_Format_Xml_Helper $helper,
199: $params
200: )
201: {
202: $sub_type = $this->createSubType($this->element, $params);
203: $result = array();
204: foreach ($values as $value) {
205: $result[] = $sub_type->saveNodeValue(
206: $name, $value, $parent_node, $helper, $params
207: );
208: }
209: return $result;
210: }
211: }
212: