Overview

Packages

  • Horde
    • Data
  • None
  • Turba

Classes

  • Turba_Application
  • Turba_Block_Minisearch
  • Turba_Exception_NotSupported
  • Turba_View_List_AlphaFilter
  • Turba_View_List_PageFilter
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * Turba application API.
  4:  *
  5:  * This file defines Horde's core API interface. Other core Horde libraries
  6:  * can interact with Turba through this API.
  7:  *
  8:  * Copyright 2010-2012 Horde LLC (http://www.horde.org/)
  9:  *
 10:  * See the enclosed file COPYING for license information (APL). If you
 11:  * did not receive this file, see http://www.horde.org/licenses/apl.html.
 12:  *
 13:  * @category Horde
 14:  * @license  http://www.horde.org/licenses/apl.html APL
 15:  * @package  Turba
 16:  */
 17: 
 18: /* Determine the base directories. */
 19: if (!defined('TURBA_BASE')) {
 20:     define('TURBA_BASE', dirname(__FILE__) . '/..');
 21: }
 22: 
 23: if (!defined('HORDE_BASE')) {
 24:     /* If Horde does not live directly under the app directory, the HORDE_BASE
 25:      * constant should be defined in config/horde.local.php. */
 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: /* Load the Horde Framework core (needed to autoload
 34:  * Horde_Registry_Application::). */
 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:      * Global variables defined:
 45:      *   $addSources   - TODO
 46:      *   $attributes - (array) Attribute data from the config/attributes.php
 47:      *                 file.
 48:      *   $browse_source_count - TODO
 49:      *   $browse_source_options - TODO
 50:      *   $cfgSources   - TODO
 51:      *   $copymove_source_options - TODO
 52:      *   $copymoveSources - TODO
 53:      *   $turba_shares - TODO
 54:      */
 55:     protected function _init()
 56:     {
 57:         // Turba source and attribute configuration.
 58:         $attributes = Horde::loadConfiguration('attributes.php', 'attributes', 'turba');
 59:         $cfgSources = Turba::availableSources();
 60: 
 61:         /* UGLY UGLY UGLY - we should NOT be using this as a global
 62:          * variable all over the place. */
 63:         $GLOBALS['cfgSources'] = &$cfgSources;
 64: 
 65:         // See if any of our sources are configured to use Horde_Share.
 66:         foreach ($cfgSources as $key => $cfg) {
 67:             if (!empty($cfg['use_shares'])) {
 68:                 // Create a share instance.
 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:         // Build the directory sources select widget.
 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:         /* Only set $add_source_options if there is at least one editable
112:          * address book that is not the current address book. */
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:         // Run through every contact source.
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($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:         /* Import/Export */
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:                 // First the selected columns in their current order.
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:                     // Need to unset this for the loop below, otherwise
300:                     // selected columns from another source could interfere
301:                     unset($selected);
302:                 }
303: 
304:                 // Then the unselected columns in source order.
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:      * Returns values for <configspecial> configuration settings.
383:      *
384:      * @param string $what  Either 'client-fields' or 'sources'.
385:      *
386:      * @return array  The values for the requested configuration setting.
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:         /* We need a clean copy of the $cfgSources array here.*/
423:         $cfgSources = Turba::availableSources();
424:         foreach ($cfgSources as $source) {
425:             if (empty($source['use_shares'])) {
426:                 // Shares not enabled for this source
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:         /* Only attempt share removal if we have shares configured */
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:         // Look for the deleted user's shares and remove them
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:         /* Get a list of all shares this user has perms to and remove the
472:          * perms. */
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:     /* Sidebar method. */
485: 
486:     /**
487:      */
488:     public function sidebarCreate(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: 
API documentation generated by ApiGen