1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
17:
18:
19: if (!defined('TURBA_BASE')) {
20: define('TURBA_BASE', dirname(__FILE__) . '/..');
21: }
22:
23: if (!defined('HORDE_BASE')) {
24: 25:
26: if (file_exists(TURBA_BASE . '/config/horde.local.php')) {
27: include TURBA_BASE . '/config/horde.local.php';
28: } else {
29: define('HORDE_BASE', TURBA_BASE . '/..');
30: }
31: }
32:
33: 34:
35: require_once HORDE_BASE . '/lib/core.php';
36:
37: class Turba_Application extends Horde_Registry_Application
38: {
39: 40:
41: public $version = 'H4 (3.0.17-git)';
42:
43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54:
55: protected function _init()
56: {
57:
58: $attributes = Horde::loadConfiguration('attributes.php', 'attributes', 'turba');
59: $cfgSources = Turba::availableSources();
60:
61: 62:
63: $GLOBALS['cfgSources'] = &$cfgSources;
64:
65:
66: foreach ($cfgSources as $key => $cfg) {
67: if (!empty($cfg['use_shares'])) {
68:
69: $GLOBALS['session']->set('turba', 'has_share', true);
70: $GLOBALS['turba_shares'] = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Share')->create();
71: $cfgSources = Turba::getConfigFromShares($cfgSources);
72: break;
73: }
74: }
75:
76: $GLOBALS['attributes'] = $attributes;
77: $cfgSources = Turba::permissionsFilter($cfgSources);
78:
79:
80: $default_source = Horde_Util::nonInputVar('source');
81: if (empty($default_source)) {
82: if (!($default_source = $GLOBALS['session']->get('turba', 'source'))) {
83: $default_source = Turba::getDefaultAddressbook();
84: }
85: $default_source = Horde_Util::getFormData('source', $default_source);
86: }
87:
88: $GLOBALS['browse_source_count'] = 0;
89: $GLOBALS['browse_source_options'] = '';
90:
91: foreach (Turba::getAddressBooks() as $key => $curSource) {
92: if (!empty($curSource['browse'])) {
93: $selected = ($key == $default_source) ? ' selected="selected"' : '';
94: $GLOBALS['browse_source_options'] .= '<option value="' . htmlspecialchars($key) . '" ' . $selected . '>' .
95: htmlspecialchars($curSource['title']) . '</option>';
96:
97: ++$GLOBALS['browse_source_count'];
98:
99: if (empty($default_source)) {
100: $default_source = $key;
101: }
102: }
103: }
104:
105: if (empty($cfgSources[$default_source]['browse'])) {
106: $default_source = Turba::getDefaultAddressbook();
107: }
108: $GLOBALS['session']->set('turba', 'source', $default_source);
109: $GLOBALS['default_source'] = $default_source;
110:
111: 112:
113: $addSources = Turba::getAddressBooks(Horde_Perms::EDIT, array('require_add' => true));
114: $copymove_source_options = '';
115: $copymoveSources = $addSources;
116: unset($copymoveSources[$default_source]);
117: foreach ($copymoveSources as $key => $curSource) {
118: if ($key != $default_source) {
119: $copymove_source_options .= '<option value="' . htmlspecialchars($key) . '">' .
120: htmlspecialchars($curSource['title']) . '</option>';
121: }
122: }
123:
124: $GLOBALS['addSources'] = $addSources;
125: $GLOBALS['copymove_source_options'] = $copymove_source_options;
126: $GLOBALS['copymoveSources'] = $copymoveSources;
127: }
128:
129: 130:
131: public function perms()
132: {
133: $cfgSources = Turba::availableSources();
134:
135: $perms = array(
136: 'sources' => array(
137: 'title' => _("Sources")
138: )
139: );
140:
141:
142: foreach ($cfgSources as $source => $curSource) {
143: $perms['sources:' . $source] = array(
144: 'title' => $curSource['title']
145: );
146: $perms['sources:' . $source . ':max_contacts'] = array(
147: 'title' => _("Maximum Number of Contacts"),
148: 'type' => 'int'
149: );
150: }
151:
152: return $perms;
153: }
154:
155: 156:
157: public function ($menu)
158: {
159: if ($GLOBALS['session']->get('turba', 'has_share')) {
160: $menu->add(Horde::url('addressbooks/index.php'), _("_My Address Books"), 'turba.png');
161: }
162:
163: if ($GLOBALS['browse_source_count']) {
164: $menu->add(Horde::url('browse.php'), _("_Browse"), 'menu/browse.png', null, null, null, (($GLOBALS['prefs']->getValue('initial_page') == 'browse.php' && basename($_SERVER['PHP_SELF']) == 'index.php' && basename(dirname($_SERVER['PHP_SELF'])) != 'addressbooks') || (basename($_SERVER['PHP_SELF']) == 'browse.php' && Horde_Util::getFormData('key') != '**search')) ? 'current' : '__noselection');
165: }
166:
167: if (count($GLOBALS['addSources'])) {
168: $menu->add(Horde::url('add.php'), _("_New Contact"), 'menu/new.png');
169: }
170:
171: $menu->add(Horde::url('search.php'), _("_Search"), 'search.png', null, null, null, (($GLOBALS['prefs']->getValue('initial_page') == 'search.php' && basename($_SERVER['PHP_SELF']) == 'index.php' && strpos($_SERVER['PHP_SELF'], 'addressbooks/index.php') === false) || (basename($_SERVER['PHP_SELF']) == 'browse.php' && Horde_Util::getFormData('key') == '**search')) ? 'current' : null);
172:
173:
174: if ($GLOBALS['conf']['menu']['import_export']) {
175: $menu->add(Horde::url('data.php'), _("_Import/Export"), 'data.png');
176: }
177: }
178:
179: 180:
181: public function prefsGroup($ui)
182: {
183: global $prefs;
184:
185: $source_init = false;
186:
187: foreach ($ui->getChangeablePrefs() as $val) {
188: switch ($val) {
189: case 'columnselect':
190: Horde::addScriptFile('effects.js', 'horde');
191: Horde::addScriptFile('dragdrop.js', 'horde');
192: Horde::addScriptFile('columnprefs.js', 'turba');
193: break;
194:
195: case 'default_dir':
196: $out = array();
197: foreach ($GLOBALS['cfgSources'] as $key => $info) {
198: $out[$key] = $info['title'];
199: }
200: $ui->override['default_dir'] = $out;
201:
202: $source_init = true;
203: break;
204:
205: case 'sync_books':
206: $out = array();
207: foreach (Turba::getAddressBooks() as $key => $curSource) {
208: if (empty($curSource['map']['__uid'])) {
209: continue;
210: }
211: if (!empty($curSource['browse'])) {
212: $out[$key] = $curSource['title'];
213: }
214: $sync_books = @unserialize($prefs->getValue('sync_books'));
215: if (empty($sync_books)) {
216: $prefs->setValue('sync_books', serialize(array(Turba::getDefaultAddressbook())));
217: }
218: }
219: $ui->override['sync_books'] = $out;
220:
221: $source_init = true;
222: break;
223: }
224: }
225:
226: if ($source_init) {
227: Horde_Core_Prefs_Ui_Widgets::sourceInit();
228: }
229: }
230:
231: 232:
233: public function prefsSpecial($ui, $item)
234: {
235: switch ($item) {
236: case 'addressbookselect':
237: $order = Turba::getAddressBookOrder();
238: $selected = $sorted = $unselected = array();
239:
240: foreach (array_keys($GLOBALS['cfgSources']) as $val) {
241: if (isset($order[$val])) {
242: $sorted[intval($order[$val])] = $val;
243: } else {
244: $unselected[$val] = $GLOBALS['cfgSources'][$val]['title'];
245: }
246: }
247: ksort($sorted);
248:
249: foreach ($sorted as $val) {
250: $selected[$val] = $GLOBALS['cfgSources'][$val]['title'];
251: }
252:
253: return Horde_Core_Prefs_Ui_Widgets::source(array(
254: 'mainlabel' => _("Choose which address books to display, and in what order:"),
255: 'selectlabel' => _("These address books will display in this order:"),
256: 'sources' => array(array(
257: 'selected' => $selected,
258: 'unselected' => $unselected
259: )),
260: 'unselectlabel' => _("Address books that will not be displayed:")
261: ));
262:
263: case 'columnselect':
264: $sources = Turba::getColumns();
265:
266: $t = $GLOBALS['injector']->createInstance('Horde_Template');
267: $t->setOption('gettext', true);
268:
269: $t->set('columns', htmlspecialchars($GLOBALS['prefs']->getValue('columns')));
270:
271: $col_list = $cols = array();
272: foreach ($GLOBALS['cfgSources'] as $source => $info) {
273: $col_list[] = array(
274: 'first' => empty($col_list),
275: 'source' => htmlspecialchars($source),
276: 'title' => htmlspecialchars($info['title'])
277: );
278:
279:
280: $i = 0;
281: $inputs = array();
282:
283: if (isset($sources[$source])) {
284: $selected = array_flip($sources[$source]);
285: foreach ($sources[$source] as $column) {
286: if ((substr($column, 0, 2) == '__') ||
287: ($column == 'name')) {
288: continue;
289: }
290:
291: $inputs[] = array(
292: 'checked' => isset($selected[$column]),
293: 'column' => htmlspecialchars($column),
294: 'i' => $i++,
295: 'label' => htmlspecialchars($GLOBALS['attributes'][$column]['label'])
296: );
297: }
298: } else {
299:
300:
301: unset($selected);
302: }
303:
304:
305: foreach (array_keys($info['map']) as $column) {
306: if ((substr($column, 0, 2) == '__') ||
307: ($column == 'name') ||
308: isset($selected[$column])) {
309: continue;
310: }
311:
312: $inputs[] = array(
313: 'checked' => isset($selected[$column]),
314: 'column' => htmlspecialchars($column),
315: 'i' => $i++,
316: 'label' => htmlspecialchars($GLOBALS['attributes'][$column]['label'])
317: );
318: }
319:
320: $cols[] = array(
321: 'first' => empty($cols),
322: 'inputs' => $inputs,
323: 'source' => htmlspecialchars($source)
324: );
325: }
326:
327: if (!empty($col_list)) {
328: $t->set('col_list', $col_list);
329: $t->set('cols', $cols);
330: }
331:
332: return $t->fetch(TURBA_TEMPLATES . '/prefs/column.html');
333: }
334: }
335:
336: 337:
338: public function prefsSpecialUpdate($ui, $item)
339: {
340: global $prefs;
341:
342: switch ($item) {
343: case 'addressbookselect':
344: $data = Horde_Core_Prefs_Ui_Widgets::sourceUpdate($ui);
345: if (isset($data['sources'])) {
346: $prefs->setValue('addressbooks', $data['sources']);
347: return true;
348: }
349: break;
350:
351: case 'columnselect':
352: if (isset($ui->vars->columns)) {
353: $prefs->setValue('columns', $ui->vars->columns);
354: return true;
355: }
356: break;
357: }
358:
359: return false;
360: }
361:
362: 363:
364: public function prefsCallback($ui)
365: {
366: if ($GLOBALS['conf']['activesync']['enabled'] && $GLOBALS['prefs']->isDirty('sync_books')) {
367: try {
368: $stateMachine = $GLOBALS['injector']->getInstance('Horde_ActiveSyncState');
369: $stateMachine->setLogger($GLOBALS['injector']->getInstance('Horde_Log_Logger'));
370: $devices = $stateMachine->listDevices($GLOBALS['registry']->getAuth());
371: foreach ($devices as $device) {
372: $stateMachine->removeState(null, $device['device_id'], $GLOBALS['registry']->getAuth());
373: }
374: $GLOBALS['notification']->push(_("All state removed for your ActiveSync devices. They will resynchronize next time they connect to the server."));
375: } catch (Horde_ActiveSync_Exception $e) {
376: $GLOBALS['notification']->push(_("There was an error communicating with the ActiveSync server: %s"), $e->getMessage(), 'horde.err');
377: }
378: }
379: }
380:
381: 382: 383: 384: 385: 386: 387:
388: public function configSpecialValues($what)
389: {
390: switch ($what) {
391: case 'client-fields':
392: try {
393: $fields = $GLOBALS['registry']->call('clients/clientFields');
394: } catch (Horde_Exception $e) {
395: return array();
396: }
397: $f = array();
398: foreach ($fields as $field) {
399: $f[$field['name']] = $field['label'];
400: }
401: return $f;
402:
403: case 'sources':
404: try {
405: $addressbooks = Turba::getAddressBooks(Horde_Perms::READ);
406: } catch (Horde_Exception $e) {
407: return array();
408: }
409: foreach ($addressbooks as &$addressbook) {
410: $addressbook = $addressbook['title'];
411: }
412:
413: $addressbooks[''] = _("None");
414: return $addressbooks;
415: }
416: }
417:
418: 419:
420: public function removeUserData($user)
421: {
422:
423: $cfgSources = Turba::availableSources();
424: foreach ($cfgSources as $source) {
425: if (empty($source['use_shares'])) {
426:
427: try {
428: $driver = $GLOBALS['injector']->getInstance('Turba_Factory_Driver')->create($source);
429: } catch (Turba_Exception $e) {
430: Horde::logMessage($e, 'ERR');
431: }
432:
433: try {
434: $driver->removeUserData($user);
435: } catch (Turba_Exception_NotSupported $e) {
436: continue;
437: } catch (Turba_Exception $e) {
438: Horde::logMessage($e, 'ERR');
439: throw new Turba_Exception(sprintf(_("There was an error removing an address book for %s"), $user));
440: }
441: }
442: }
443:
444:
445: if (!$GLOBALS['session']->get('turba', 'has_share')) {
446: return;
447: }
448:
449: $shares = $GLOBALS['turba_shares']->listShares(
450: $user, array('attributes' => $user));
451:
452:
453: foreach ($shares as $share) {
454: $config = Turba::getSourceFromShare($share);
455: try {
456: $driver = $GLOBALS['injector']->getInstance('Turba_Factory_Driver')->create($config);
457: } catch (Turba_Exception $e) {
458: continue;
459: }
460:
461: try {
462: $driver->removeUserData($user);
463: } catch (Turba_Exception_NotSupported $e) {
464: continue;
465: } catch (Turba_Exception $e) {
466: Horde::logMessage($e, 'ERR');
467: throw new Turba_Exception(sprintf(_("There was an error removing an address book for %s"), $user));
468: }
469: }
470:
471: 472:
473: try {
474: $shares = $GLOBALS['turba_shares']->listShares($user);
475: foreach ($shares as $share) {
476: $share->removeUser($user);
477: }
478: } catch (Horde_Share_Exception $e) {
479: Horde::logMessage($e, 'ERR');
480: throw new Turba_Exception(sprintf(_("There was an error removing an address book for %s"), $user));
481: }
482: }
483:
484:
485:
486: 487:
488: public function (Horde_Tree_Base $tree, $parent = null,
489: array $params = array())
490: {
491: $add = Horde::url('add.php');
492: $browse = Horde::url('browse.php');
493:
494: if ($GLOBALS['addSources']) {
495: $newimg = Horde_Themes::img('menu/new.png');
496:
497: $tree->addNode(
498: $parent . '__new',
499: $parent,
500: _("New Contact"),
501: 1,
502: false,
503: array(
504: 'icon' => $newimg,
505: 'url' => $add
506: )
507: );
508:
509: foreach ($GLOBALS['addSources'] as $addressbook => $config) {
510: $tree->addNode(
511: $parent . $addressbook . '__new',
512: $parent . '__new',
513: sprintf(_("in %s"), $config['title']),
514: 2,
515: false,
516: array(
517: 'icon' => $newimg,
518: 'url' => $add->copy()->add('source', $addressbook)
519: )
520: );
521: }
522: }
523:
524: foreach (Turba::getAddressBooks() as $addressbook => $config) {
525: if (!empty($config['browse'])) {
526: $tree->addNode(
527: $parent . $addressbook,
528: $parent,
529: $config['title'],
530: 1,
531: false,
532: array(
533: 'icon' => Horde_Themes::img('menu/browse.png'),
534: 'url' => $browse->copy()->add('source', $addressbook)
535: )
536: );
537: }
538: }
539:
540: $tree->addNode(
541: $parent . '__search',
542: $parent,
543: _("Search"),
544: 1,
545: false,
546: array(
547: 'icon' => Horde_Themes::img('search.png'),
548: 'url' => Horde::url('search.php')
549: )
550: );
551: }
552:
553: }
554: