1: <?php
2: /**
3: * P800/P900/P910:
4: * ---------------
5: * Charset:
6: * This device is able to handle UTF-8 and sends its XML packages in UTF8.
7: * However even though the XML itself is UTF-8, it expects the enclosed
8: * vcard-data to be ISO-8859-1 unless explicitly stated otherwise (using the
9: * CHARSET option, which is deprecated for VCARD 3.0)
10: *
11: * Encoding:
12: * String values are encoded "QUOTED-PRINTABLE"
13: *
14: * Other:
15: * This devices handles tasks and events in one database.
16: *
17: * As the P800 was the first device to work with package, most of the
18: * required conversions are in Device.php's default handling.
19: *
20: * Copyright 2005-2012 Horde LLC (http://www.horde.org/)
21: *
22: * See the enclosed file COPYING for license information (LGPL). If you
23: * did not receive this file, see http://www.horde.org/licenses/lgpl21.
24: *
25: * @author Karsten Fourmont <karsten@horde.org>
26: * @package SyncMl
27: */
28: class Horde_SyncMl_Device_P800 extends Horde_SyncMl_Device
29: {
30: /**
31: * Convert the content.
32: *
33: * @param string $content The content to convert.
34: * @param string $contentType The contentType of the content.
35: * @return array array($newcontent, $newcontentType):
36: * the converted content and the
37: * (possibly changed) new ContentType.
38: */
39: public function convertClient2Server($content, $contentType)
40: {
41: list($content, $contentType) =
42: parent::convertClient2Server($content, $contentType);
43:
44: /* P800 sends categories as "X-Category". Remove the "X-".
45: * @todo: This hack only works with a single category. */
46: $content = preg_replace('/(\r\n|\r|\n)CATEGORIES:X-/', '\1CATEGORIES:',
47: $content, 1);
48:
49: /* P800 sends all day events as s.th. like
50: * DTSTART:20050505T000000Z^M
51: * DTEND:20050505T240000Z^M
52: * This is no longer an all day event when converted to local timezone.
53: * So manually handle this. */
54: if (preg_match('/(\r\n|\r|\n)DTSTART:.*T000000Z(\r\n|\r|\n)/',
55: $content) &&
56: preg_match('/(\r\n|\r|\n)DTEND:(\d\d\d\d)(\d\d)(\d\d)T240000Z(\r\n|\r|\n)/',
57: $content, $m)) {
58: $content = preg_replace(
59: '/(\r\n|\r|\n)DTSTART:(.*)T000000Z(\r\n|\r|\n)/',
60: "$1DTSTART;VALUE=DATE:$2$3", $content);
61: /* End timestamp must be converted to next day's date. Or maybe
62: * not? */
63: $s = date('Ymd', mktime(0, 0, 0, $m[3], $m[4], $m[2]) /* + 24*3600 */);
64: $content = preg_replace(
65: '/(\r\n|\r|\n)DTEND:(.*)T240000Z(\r\n|\r|\n)/',
66: "$1DTEND;VALUE=DATE:$s$3", $content);
67: }
68:
69: $GLOBALS['backend']->logFile(
70: Horde_SyncMl_Backend::LOGFILE_DATA,
71: "\ninput converted for server ($contentType):\n$content\n");
72:
73: return array($content, $contentType);
74: }
75:
76: /**
77: * Converts the content from the backend to a format suitable for the
78: * client device.
79: *
80: * Strips the uid (primary key) information as client and server might use
81: * different ones.
82: *
83: * @param string $content The content to convert
84: * @param string $contentType The content type of content as returned
85: * from the backend
86: * @param string $database The server database URI.
87: *
88: * @return array Three-element array with the converted content, the
89: * (possibly changed) new content type, and encoding type
90: * (like b64 as used by Funambol).
91: */
92: public function convertServer2Client($content, $contentType, $database)
93: {
94: list($content, $contentType, $encodingType) =
95: parent::convertServer2Client($content, $contentType, $database);
96:
97: /* Convert all day events. */
98: if (preg_match('/(\r\n|\r|\n)DTSTART:(\d{8})T000000/',
99: $content)
100: && preg_match('/(\r\n|\r|\n)DTEND:(\d\d\d\d)(\d\d)(\d\d)T235959/',
101: $content, $m)) {
102: /* @TODO: This is for P990. Check if it's different for P900.
103: * This might require T000000Z rather than T000000 */
104:
105: /* The P990 seems to require this to recognize an entry as all day: */
106: $a = $m[1] . 'X-EPOCAGENDAENTRYTYPE:EVENT';
107: $content = preg_replace('/(\r\n|\r|\n)DTSTART:(\d{8})T000000/',
108: "$a$1DTSTART:$2T000000", $content);
109: /* End date must be converted to timestamp. */
110: $s = date('Ymd', mktime(0, 0, 0, $m[3], $m[4]+1, $m[2]));
111: $content = preg_replace('/(\r\n|\r|\n)DTEND:(\d{8})T235959/',
112: "$1DTEND:${s}T000000", $content);
113: }
114:
115: $l = "\noutput converted for client ($contentType):\n" . $content . "\n";
116: $GLOBALS['backend']->logFile(Horde_SyncMl_Backend::LOGFILE_DATA, $l);
117:
118: return array($content, $contentType, $encodingType);
119: }
120:
121: /**
122: * Some devices like the Sony Ericsson P800/P900/P910 handle vtodos (tasks)
123: * and vevents in the same "calendar" sync.
124: * This requires special actions on our side as we store this in different
125: * databases (nag and kronolith).
126: * This public function could directly return true but tries to be a bit more
127: * generic so it might work for other phones as well.
128: */
129: public function handleTasksInCalendar()
130: {
131: $di = $GLOBALS['backend']->state->deviceInfo;
132:
133: if (isset($di->CTCaps['text/x-vcalendar']) &&
134: !empty($di->CTCaps['text/x-vcalendar']['BEGIN']->ValEnum['VEVENT']) &&
135: !empty($di->CTCaps['text/x-vcalendar']['BEGIN']->ValEnum['VTODO'])) {
136: return true;
137: }
138:
139: return parent::handleTasksInCalendar();
140: }
141:
142: /**
143: * Send individual status response for each Add,Delete,Replace.
144: * The P800 class of devices seem to have trouble with too many
145: * status responses. So omit them for these (and only these),
146: */
147: public function omitIndividualSyncStatus()
148: {
149: return true;
150: }
151: }
152: