1: <?php
2: /**
3: * The Horde_SyncMl_Command_Put class provides a SyncML implementation of the
4: * Put command as defined in SyncML Representation Protocol, version 1.1,
5: * section 5.5.10.
6: *
7: * The Put command is used to transfer data items to a recipient network device
8: * or database. The Horde_SyncMl_Command_Put class handles DevInf device
9: * information sent by the client.
10: *
11: * The data is stored in a Horde_SyncMl_DeviceInfo object which is defined in
12: * Device.php and then stored in Horde_SyncMl_Device as an attribute.
13: *
14: * Copyright 2005-2012 Horde LLC (http://www.horde.org/)
15: *
16: * See the enclosed file COPYING for license information (LGPL). If you
17: * did not receive this file, see http://www.horde.org/licenses/lgpl21.
18: *
19: * @author Karsten Fourmont <karsten@horde.org>
20: * @author Jan Schneider <jan@horde.org>
21: * @package SyncMl
22: */
23: class Horde_SyncMl_Command_Put extends Horde_SyncMl_Command
24: {
25: /**
26: * Name of the command.
27: *
28: * @var string
29: */
30: protected $_cmdName = 'Put';
31:
32: /**
33: * The Horde_SyncMl_DeviceInfo object where all parsed <DevInf> content is
34: * saved.
35: *
36: * <DevInf> specifies the type of the source synchronization device.
37: *
38: * @var Horde_SyncMl_DeviceInfo
39: */
40: protected $_devinf;
41:
42: /**
43: * A Horde_SyncMl_DataStore object where the information from the currently
44: * parsed <DataStore> section is saved.
45: *
46: * <DataStore> specifies the properties of a given local datastore.
47: *
48: * @var Horde_SyncMl_DataStore
49: */
50: protected $_currentDS;
51:
52: /**
53: * The MIME content type as specified by the last <CTType> element like
54: * text/calendar or text/x-vcard.
55: *
56: * <CTType> specifies the type of a supported content type.
57: *
58: * @var string
59: */
60: protected $_currentCTType;
61:
62: /**
63: * The version of the MIME content type in $_currentCTType as specified by
64: * the last <VerCT> element like 1.0 for text/x-vcalendar or 2.1 for
65: * text/x-vcard.
66: *
67: * <VerCT> specifies the version of a supported content type.
68: *
69: * @var string
70: */
71: protected $_VerCT;
72:
73: /**
74: * A property name of the currently parsed content type (CTType), like
75: * 'DTSTART' for text/calendar or 'BDAY' for text/x-vcard.
76: *
77: * <PropName> specifies a supported property of a given content type.
78: *
79: * @var string
80: */
81: protected $_currentPropName;
82:
83: /**
84: * A property name of the currently parsed property name (PropName), like
85: * 'ROLE' for 'ATTENDEE' or 'HOME' for 'ADR'.
86: *
87: * <ParamName> specifies supported parameters of a given content type
88: * property.
89: *
90: * @var string
91: */
92: protected $_currentParamName;
93:
94: /**
95: * The name of the currently parsed DevInf extension (<Ext>) as specified
96: * by the XNam element.
97: *
98: * <XNam> specifies the name of one of the DevInf extension element types.
99: *
100: * @var string
101: */
102: protected $_currentXNam;
103:
104: /**
105: * Start element handler for the XML parser, delegated from
106: * Horde_SyncMl_ContentHandler::startElement().
107: *
108: * @param string $uri The namespace URI of the element.
109: * @param string $element The element tag name.
110: * @param array $attrs A hash with the element's attributes.
111: */
112: public function startElement($uri, $element, $attrs)
113: {
114: parent::startElement($uri, $element, $attrs);
115:
116: switch (count($this->_stack)) {
117: case 1:
118: $this->_devinf = new Horde_SyncMl_DeviceInfo();
119: break;
120:
121: case 5:
122: if ($element == 'DataStore') {
123: $this->_currentDS = new Horde_SyncMl_DataStore();
124: }
125: break;
126: }
127: }
128:
129: /**
130: * End element handler for the XML parser, delegated from
131: * Horde_SyncMl_ContentHandler::endElement().
132: *
133: * @param string $uri The namespace URI of the element.
134: * @param string $element The element tag name.
135: */
136: public function endElement($uri, $element)
137: {
138: switch ($element) {
139: case 'VerDTD':
140: case 'Man':
141: case 'Mod':
142: case 'OEM':
143: case 'FwV':
144: case 'SwV':
145: case 'HwV':
146: case 'DevID':
147: case 'DevTyp':
148: $this->_devinf->$element = trim($this->_chars);
149: break;
150:
151: case 'UTC':
152: case 'SupportLargeObjs':
153: case 'SupportNumberOfChanges':
154: $this->_devinf->$element = true;
155: break;
156:
157: case 'DataStore':
158: $this->_devinf->DataStores[] = $this->_currentDS;
159: break;
160:
161: case 'CTCap':
162: case 'Ext':
163: // Automatically handled by subelements.
164: break;
165:
166: case 'SourceRef':
167: case 'DisplayName':
168: case 'MaxGUIDSize':
169: $this->_currentDS->$element = trim($this->_chars);
170: break;
171:
172: case 'Rx-Pref':
173: case 'Rx':
174: case 'Tx-Pref':
175: case 'Tx':
176: $property = str_replace('-', '_', $element);
177: $this->_currentDS->{$property}[$this->_currentCTType] = $this->_VerCT;
178: break;
179:
180: case 'DSMem':
181: // Currently ignored, to be done.
182: break;
183:
184: case 'SyncCap':
185: // Automatically handled by SyncType subelement.
186: break;
187:
188: case 'CTType':
189: $this->_currentCTType = trim($this->_chars);
190: break;
191:
192: case 'PropName':
193: $this->_currentPropName = trim($this->_chars);
194: // Reset param state.
195: unset($this->_currentParamName);
196: $this->_devinf->CTCaps[$this->_currentCTType][$this->_currentPropName] = new Horde_SyncMl_Property();
197: break;
198:
199: case 'ParamName':
200: $this->_currentParamName = trim($this->_chars);
201: $this->_devinf->CTCaps[$this->_currentCTType][$this->_currentPropName]->Params[$this->_currentParamName] = new Horde_SyncMl_PropertyParameter();
202: break;
203:
204: case 'ValEnum':
205: if (!empty($this->_currentParamName)) {
206: // We're in parameter mode.
207: $this->_devinf->CTCaps[$this->_currentCTType][$this->_currentPropName]->Params[$this->_currentParamName]->ValEnum[trim($this->_chars)] = true;
208: } else {
209: $this->_devinf->CTCaps[$this->_currentCTType][$this->_currentPropName]->ValEnum[trim($this->_chars)] = true;
210: }
211: break;
212:
213: case 'DataType':
214: case 'Size':
215: case 'DisplayName':
216: if (!empty($this->_currentParamName)) {
217: // We're in parameter mode.
218: $this->_devinf->CTCaps[$this->_currentCTType][$this->_currentPropName]->Params[$this->_currentParamName]->{'_' . $element} = trim($this->_chars);
219: } else {
220: $this->_devinf->CTCaps[$this->_currentCTType][$this->_currentPropName]->{'_' . $element} = trim($this->_chars);
221: }
222: break;
223:
224: case 'XNam':
225: $this->_currentXNam = trim($this->_chars);
226: break;
227: case 'XVal':
228: $this->_devinf->Exts[$this->_currentXNam][] = trim($this->_chars);
229: break;
230:
231: case 'VerCT':
232: $this->_VerCT = trim($this->_chars);
233: break;
234: case 'SyncType':
235: $this->_currentDS->SyncCap[trim($this->_chars)] = true;
236: break;
237: }
238:
239: parent::endElement($uri, $element);
240: }
241:
242: /**
243: * Implements the actual business logic of the Alert command.
244: */
245: public function handleCommand($debug = false)
246: {
247: $state = $GLOBALS['backend']->state;
248:
249: // Store received data.
250: $state->deviceInfo = $this->_devinf;
251:
252: // Log DevInf object.
253: $GLOBALS['backend']->logFile(Horde_SyncMl_Backend::LOGFILE_DEVINF,
254: var_export($this->_devinf, true));
255:
256: // Create status response.
257: $this->_outputHandler->outputStatus($this->_cmdID, $this->_cmdName,
258: Horde_SyncMl::RESPONSE_OK, '',
259: $state->getDevInfURI());
260: }
261: }
262: