Пример #1
0
 public function compareReadmes($a, $b)
 {
     if ($this->_isHtmlReadme($a)) {
         return self::CHOOSE_A;
     }
     if ($this->_isHtmlReadme($b)) {
         return self::CHOOSE_B;
     }
     $a_len = Horde_String::length($a->getFileName());
     $b_len = Horde_String::length($b->getFileName());
     if ($a_len < $b_len) {
         return self::CHOOSE_A;
     } elseif ($b_len < $a_len) {
         return self::CHOOSE_B;
     } else {
         return strcasecmp($a->getFileName(), $b->getFileName());
     }
 }
Пример #2
0
 /**
  * Return a string containing an <option> listing of the given
  * gallery array.
  *
  * @param array $params  An array of options:
  *   <pre>
  *     (integer)selected  The gallery_id of the gallery that is selected
  *     (integer)perm      The permissions filter to use [Horde_Perms::SHOW]
  *     (mixed)attributes  Restrict the galleries returned to those matching
  *                        the filters. Can be an array of attribute/values
  *                        pairs or a gallery owner username.
  *     (boolean)all_levels
  *     (integer)from      The gallery to start listing at.
  *     (integer)count     The number of galleries to return.
  *     (integer)ignore    An Ansel_Gallery id to ignore when building the tree.
  *   </pre>
  *
  * @return string  The HTML to display the option list.
  */
 public static function selectGalleries($params = array())
 {
     $galleries = $GLOBALS['injector']->getInstance('Ansel_Storage')->listGalleries($params);
     $params = new Horde_Support_Array($params);
     $tree = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Tree')->create('gallery_tree', 'Select');
     // Remove the ignored gallery, make sure it's also not the selected
     if ($params->ignore) {
         if ($params->selected == $params->ignore) {
             $params->selected = null;
         }
     }
     foreach ($galleries as $gallery) {
         $gallery_id = $gallery->id;
         $gallery_name = $gallery->get('name');
         $label = Horde_String::abbreviate($gallery_name);
         $len = Horde_String::length($gallery_name);
         $treeparams = array();
         $treeparams['selected'] = $gallery_id == $params->selected;
         $parent = $gallery->getParent();
         $parent = empty($parent) ? null : $parent->id;
         $tree->addNode(array('id' => $gallery->id, 'parent' => $parent, 'label' => $label, 'params' => $treeparams));
     }
     return $tree->getTree();
 }
Пример #3
0
 /**
  */
 protected function _init()
 {
     global $injector, $notification, $page_output, $prefs, $registry, $session;
     $mailbox = $this->indices->mailbox;
     /* Call the mailbox redirection hook, if requested. */
     try {
         $redirect = $injector->getInstance('Horde_Core_Hooks')->callHook('mbox_redirect', 'imp', array($mailbox));
         if (!empty($redirect)) {
             Horde::url($redirect, true)->redirect();
         }
     } catch (Horde_Exception_HookNotSet $e) {
     }
     $mailbox_url = Horde::url('basic.php')->add('page', 'mailbox');
     $mailbox_imp_url = $mailbox->url('mailbox')->add('newmail', 1);
     $imp_flags = $injector->getInstance('IMP_Flags');
     $imp_imap = $mailbox->imp_imap;
     $imp_search = $injector->getInstance('IMP_Search');
     /* Run through the action handlers */
     if (($actionID = $this->vars->actionID) && $actionID != 'message_missing') {
         try {
             $session->checkToken($this->vars->token);
         } catch (Horde_Exception $e) {
             $notification->push($e);
             $actionID = null;
         }
     }
     /* We know we are going to be exclusively dealing with this mailbox,
      * so select it on the IMAP server (saves some STATUS calls). Open
      * R/W to clear the RECENT flag. This call will catch invalid
      * mailboxes. */
     $imp_imap->openMailbox($mailbox, Horde_Imap_Client::OPEN_READWRITE);
     $imp_mailbox = $mailbox->list_ob;
     /* Determine if mailbox is readonly. */
     $readonly = $mailbox->readonly;
     switch ($actionID) {
         case 'change_sort':
             $mailbox->setSort($this->vars->sortby, $this->vars->sortdir);
             break;
         case 'blacklist':
             $injector->getInstance('IMP_Filter')->blacklistMessage($this->indices);
             break;
         case 'whitelist':
             $injector->getInstance('IMP_Filter')->whitelistMessage($this->indices);
             break;
         case 'spam_report':
             $injector->getInstance('IMP_Factory_Spam')->create(IMP_Spam::SPAM)->report($this->indices);
             break;
         case 'innocent_report':
             $injector->getInstance('IMP_Factory_Spam')->create(IMP_Spam::INNOCENT)->report($this->indices);
             break;
         case 'message_missing':
             $notification->push(_("Requested message not found."), 'horde.error');
             break;
         case 'fwd_digest':
         case 'redirect_messages':
         case 'template_edit':
             if (count($this->indices)) {
                 $compose_actions = array('fwd_digest' => 'fwd_digest', 'redirect_messages' => 'redirect_compose', 'template_edit' => 'template_edit');
                 $clink = new IMP_Compose_Link($this->vars);
                 $options = array_merge(array('actionID' => $compose_actions[$actionID], 'muid' => strval($this->indices)), $clink->args);
                 if ($prefs->getValue('compose_popup')) {
                     $page_output->addInlineScript(array(Horde::popupJs(IMP_Basic_Compose::url(), array('novoid' => true, 'params' => array_merge(array('popup' => 1), $options)))), true);
                 } else {
                     IMP_Basic_Compose::url()->add($options)->redirect();
                 }
             }
             break;
         case 'delete_messages':
             $injector->getInstance('IMP_Message')->delete($this->indices, array('mailboxob' => $imp_mailbox));
             break;
         case 'undelete_messages':
             $injector->getInstance('IMP_Message')->undelete($this->indices);
             break;
         case 'move_messages':
         case 'copy_messages':
             if (isset($this->vars->targetMbox) && count($this->indices) && (!$readonly || $actionID == 'copy_messages')) {
                 $targetMbox = IMP_Mailbox::formFrom($this->vars->targetMbox);
                 if (!empty($this->vars->newMbox) && $this->vars->newMbox == 1) {
                     $targetMbox = IMP_Mailbox::get($this->vars->targetMbox)->namespace_append;
                     $newMbox = true;
                 } else {
                     $targetMbox = IMP_Mailbox::formFrom($this->vars->targetMbox);
                     $newMbox = false;
                 }
                 $injector->getInstance('IMP_Message')->copy($targetMbox, $actionID == 'move_messages' ? 'move' : 'copy', $this->indices, array('create' => $newMbox, 'mailboxob' => $imp_mailbox));
             }
             break;
         case 'flag_messages':
             if (!$readonly && $this->vars->flag && count($this->indices)) {
                 $flag = $imp_flags->parseFormId($this->vars->flag);
                 $injector->getInstance('IMP_Message')->flag(array($flag['set'] ? 'add' : 'remove' => array($flag['flag'])), $this->indices);
             }
             break;
         case 'filter_messages':
             if (!$readonly) {
                 $filter = IMP_Mailbox::formFrom($this->vars->filter);
                 $q_ob = null;
                 if (strpos($filter, self::FLAG_FILTER_PREFIX) === 0) {
                     /* Flag filtering. */
                     $flag_filter = $imp_flags->parseFormId(substr($filter, strpos($filter, "") + 1));
                     try {
                         $q_ob = $imp_search->createQuery(array(new IMP_Search_Element_Flag($flag_filter['flag'], $flag_filter['set'])), array('mboxes' => array($mailbox), 'type' => IMP_Search::CREATE_QUERY));
                     } catch (InvalidArgumentException $e) {
                     }
                 } else {
                     /* Pre-defined filters. */
                     try {
                         $q_ob = $imp_search->applyFilter($filter, array($mailbox));
                     } catch (InvalidArgumentException $e) {
                     }
                 }
                 if ($q_ob) {
                     IMP_Mailbox::get($q_ob)->url('mailbox')->redirect();
                     exit;
                 }
             }
             break;
         case 'hide_deleted':
             $mailbox->setHideDeletedMsgs(!$prefs->getValue('delhide'));
             break;
         case 'expunge_mailbox':
             $injector->getInstance('IMP_Message')->expungeMailbox(array(strval($mailbox) => 1), array('mailboxob' => $imp_mailbox));
             break;
         case 'filter':
             $mailbox->filter();
             break;
         case 'empty_mailbox':
             $injector->getInstance('IMP_Message')->emptyMailbox(array(strval($mailbox)));
             break;
         case 'view_messages':
             $mailbox->url(IMP_Basic_Thread::url(), null, false)->add(array('mode' => 'msgview', 'muid' => strval($this->indices)))->redirect();
             break;
     }
     /* Token to use in requests. */
     $token = $session->getToken();
     $search_mbox = $mailbox->search;
     /* Deal with filter options. */
     if (!$readonly && IMP_Filter::canApplyFilters() && !$mailbox->filterOnDisplay() && ($mailbox->inbox || $prefs->getValue('filter_any_mailbox') && !$search_mbox)) {
         $filter_url = $mailbox_imp_url->copy()->add(array('actionID' => 'filter', 'token' => $token));
     }
     /* Generate folder options list. */
     if ($imp_imap->access(IMP_Imap::ACCESS_FOLDERS)) {
         $iterator = new IMP_Ftree_IteratorFilter($injector->getInstance('IMP_Ftree'));
         $iterator->add($iterator::NONIMAP);
         $folder_options = new IMP_Ftree_Select(array('heading' => _("Messages to"), 'inc_notepads' => true, 'inc_tasklists' => true, 'iterator' => $iterator, 'new_mbox' => true));
     }
     /* Build the list of messages in the mailbox. */
     $pageOb = $imp_mailbox->buildMailboxPage($this->vars->mpage, $this->vars->start);
     $show_preview = $prefs->getValue('preview_enabled');
     $mbox_info = $imp_mailbox->getMailboxArray(range($pageOb['begin'], $pageOb['end']), array('headers' => true, 'preview' => (int) $show_preview, 'type' => $prefs->getValue('atc_flag')));
     /* Determine sorting preferences. */
     $sortpref = $mailbox->getSort();
     $thread_sort = $sortpref->sortby == Horde_Imap_Client::SORT_THREAD;
     /* Determine if we are going to show the Hide/Purge Deleted Message
      * links. */
     if (!($use_trash = $prefs->getValue('use_trash')) && !$mailbox->vinbox) {
         $showdelete = array('hide' => true, 'purge' => $mailbox->access_expunge);
     } else {
         $showdelete = array('hide' => false, 'purge' => false);
     }
     if ($showdelete['hide'] && !$prefs->isLocked('delhide')) {
         if ($prefs->getValue('delhide')) {
             $deleted_prompt = _("Show Deleted");
         } else {
             $deleted_prompt = _("Hide Deleted");
         }
     }
     /* Generate paging links. */
     if ($pageOb['pagecount']) {
         if ($pageOb['page'] == 1) {
             $url_first = $url_prev = null;
             $pages_first = 'navfirstgreyImg';
             $pages_prev = 'navleftgreyImg';
         } else {
             $url_first = $mailbox_imp_url->copy()->add('mpage', 1);
             $pages_first = 'navfirstImg';
             $url_prev = $mailbox_imp_url->copy()->add('mpage', $pageOb['page'] - 1);
             $pages_prev = 'navleftImg';
         }
         if ($pageOb['page'] == $pageOb['pagecount']) {
             $url_last = $url_next = null;
             $pages_last = 'navlastgreyImg';
             $pages_next = 'navrightgreyImg';
         } else {
             $url_next = $mailbox_imp_url->copy()->add('mpage', $pageOb['page'] + 1);
             $pages_next = 'navrightImg';
             $url_last = $mailbox_imp_url->copy()->add('mpage', $pageOb['pagecount']);
             $pages_last = 'navlastImg';
         }
     }
     /* Generate RSS link. */
     if ($mailbox->inbox) {
         $rss_box = '';
     } else {
         $ns_info = $mailbox->namespace_info;
         if (is_null($ns_info)) {
             $rss_box = null;
         } else {
             $rss_box = str_replace(rawurlencode($ns_info->delimiter), '/', rawurlencode($ns_info->delimiter . ($ns_info->type == $ns_info::NS_PERSONAL ? $ns_info->stripNamespace($mailbox) : $mailbox)));
         }
     }
     if (!is_null($rss_box)) {
         $page_output->addLinkTag(array('href' => Horde::url('rss.php', true, -1) . $rss_box));
     }
     /* If user wants the mailbox to be refreshed, set time here. */
     $refresh_url = $mailbox_imp_url->copy()->add('mpage', $pageOb['page']);
     if (isset($filter_url)) {
         $filter_url->add('mpage', $pageOb['page']);
     }
     /* Determine if we are showing previews. */
     $preview_tooltip = $show_preview ? $prefs->getValue('preview_show_tooltip') : false;
     if (!$preview_tooltip) {
         $strip_preview = $prefs->getValue('preview_strip_nl');
     }
     $unread = $imp_mailbox->unseenMessages(Horde_Imap_Client::SEARCH_RESULTS_COUNT);
     $page_output->addInlineJsVars(array('ImpMailbox.pop3' => intval(!$mailbox->is_imap), 'ImpMailbox.text' => array('delete_messages' => _("Are you sure you wish to PERMANENTLY delete these messages?"), 'delete_all' => _("Are you sure you wish to delete all mail in this mailbox?"), 'delete_vfolder' => _("Are you sure you want to delete this Virtual Folder Definition?"), 'innocent_report' => _("Are you sure you wish to report this message as innocent?"), 'moveconfirm' => _("Are you sure you want to move the message(s)? (Some message information might get lost, like message headers, text formatting or attachments!)"), 'newmbox' => _("You are copying/moving to a new mailbox.") . "\n" . _("Please enter a name for the new mailbox:") . "\n", 'no' => _("No"), 'selectone' => _("You must select at least one message first."), 'selectonlyone' => _("You must select only one message for this action."), 'spam_report' => _("Are you sure you wish to report this message as spam?"), 'submit' => _("You must select at least one message first."), 'target_mbox' => _("You must select a target mailbox first.")), 'ImpMailbox.unread' => intval($unread)));
     $pagetitle = $this->title = $mailbox->label;
     if ($mailbox->editvfolder) {
         $query_text = wordwrap($imp_search[$mailbox]->querytext);
         $pagetitle .= ' [' . Horde::linkTooltip('#', $query_text, '', '', '', $query_text) . _("Virtual Folder") . '</a>]';
         $this->title .= ' [' . _("Virtual Folder") . ']';
     } elseif ($mailbox->editquery) {
         $query_text = wordwrap($imp_search[$mailbox]->querytext);
         $pagetitle = Horde::linkTooltip('#', $query_text, '', '', '', $query_text) . $pagetitle . '</a>';
     } else {
         $pagetitle = $this->title = htmlspecialchars($this->title);
     }
     /* Generate mailbox summary string. */
     $subinfo = new IMP_View_Subinfo(array('mailbox' => $mailbox));
     $subinfo->value = $pagetitle . ' (';
     if (empty($pageOb['end'])) {
         $subinfo->value .= _("No Messages");
     } else {
         $subinfo->value .= $pageOb['pagecount'] > 1 ? sprintf(_("%d Messages"), $pageOb['msgcount']) . ' / ' . sprintf(_("Page %d of %d"), $pageOb['page'], $pageOb['pagecount']) : sprintf(_("%d Messages"), $pageOb['msgcount']);
     }
     $subinfo->value .= ')';
     $injector->getInstance('Horde_View_Topbar')->subinfo = $subinfo->render();
     $page_output->addScriptFile('hordecore.js', 'horde');
     $page_output->addScriptFile('mailbox.js');
     $page_output->addScriptPackage('Horde_Core_Script_Package_Dialog');
     $page_output->metaRefresh($prefs->getValue('refresh_time'), $refresh_url);
     /* Prepare the header template. */
     $view = new Horde_View(array('templatePath' => IMP_TEMPLATES . '/basic/mailbox'));
     $view->addHelper('FormTag');
     $view->addHelper('Horde_Core_View_Helper_Accesskey');
     $view->addHelper('Tag');
     $hdr_view = clone $view;
     $hdr_view->readonly = $readonly;
     $hdr_view->refresh_url = $refresh_url;
     if (isset($filter_url)) {
         $hdr_view->filter_url = $filter_url;
     }
     if ($mailbox->access_search) {
         if (!$search_mbox) {
             $hdr_view->search_url = $mailbox->url(IMP_Basic_Searchbasic::url());
         } else {
             if ($mailbox->editvfolder) {
                 $edit_search = _("Edit Virtual Folder");
             } elseif ($mailbox->query) {
                 if ($mailbox->editquery) {
                     $edit_search = _("Edit Search Query");
                 } else {
                     /* Basic search results. */
                     $search_mailbox = IMP_Mailbox::get($imp_search[$mailbox]->mboxes[0]);
                     $hdr_view->search_url = $search_mailbox->url(IMP_Basic_Searchbasic::url());
                     $hdr_view->searchclose = $search_mailbox->url('mailbox');
                 }
             }
             if (isset($edit_search)) {
                 $hdr_view->edit_search_url = $imp_search->editUrl($mailbox);
                 $hdr_view->edit_search_title = $edit_search;
             }
         }
     }
     if ($mailbox->access_empty) {
         $hdr_view->empty = $mailbox_imp_url->copy()->add(array('actionID' => 'empty_mailbox', 'token' => $token));
     }
     $this->output = $hdr_view->render('header');
     /* If no messages, exit immediately. */
     if (empty($pageOb['end'])) {
         if ($pageOb['anymsg'] && isset($deleted_prompt)) {
             /* Show 'Show Deleted' prompt if mailbox has no viewable
              * message but has hidden, deleted messages. */
             $del_view = clone $view;
             $del_view->hide = Horde::widget(array('url' => $refresh_url->copy()->add(array('actionID' => 'hide_deleted', 'token' => $token)), 'class' => 'hideAction', 'title' => $deleted_prompt));
             if ($mailbox->access_expunge) {
                 $del_view->purge = Horde::widget(array('url' => $refresh_url->copy()->add(array('actionID' => 'expunge_mailbox', 'token' => $token)), 'class' => 'purgeAction', 'title' => _("Pur_ge Deleted")));
             }
             $this->output .= $del_view->render('actions_deleted');
         }
         $empty_view = clone $view;
         $empty_view->search_mbox = $search_mbox;
         $this->output .= $empty_view->render('empty_mailbox');
         return;
     }
     $clink_ob = new IMP_Compose_Link();
     $clink = $clink_ob->link();
     /* Display the navbar and actions if there is at least 1 message in
      * mailbox. */
     if ($pageOb['msgcount']) {
         /* Prepare the navbar template. */
         $n_view = clone $view;
         $n_view->id = 1;
         $n_view->readonly = $readonly;
         $filtermsg = false;
         if ($mailbox->access_flags) {
             $args = array('imap' => true, 'mailbox' => $search_mbox ? null : $mailbox);
             $form_set = $form_unset = array();
             foreach ($imp_flags->getList($args) as $val) {
                 if ($val->canset) {
                     $form_set[] = array('f' => $val->form_set, 'l' => $val->label, 'v' => IMP_Mailbox::formTo(self::FLAG_FILTER_PREFIX . $val->form_set));
                     $form_unset[] = array('f' => $val->form_unset, 'l' => $val->label, 'v' => IMP_Mailbox::formTo(self::FLAG_FILTER_PREFIX . $val->form_unset));
                 }
             }
             $n_view->flaglist_set = $form_set;
             $n_view->flaglist_unset = $form_unset;
             if (!$search_mbox && $mailbox->access_search) {
                 $filtermsg = $n_view->flag_filter = true;
             }
         }
         if (!$search_mbox && $mailbox->access_filters) {
             $filters = array();
             $iterator = IMP_Search_IteratorFilter::create(IMP_Search_IteratorFilter::FILTER);
             foreach ($iterator as $val) {
                 $filters[] = array('l' => $val->label, 'v' => IMP_Mailbox::formTo($val));
             }
             if (!empty($filters)) {
                 $filtermsg = true;
                 $n_view->filters = $filters;
             }
         }
         $n_view->filtermsg = $filtermsg;
         if ($imp_imap->access(IMP_Imap::ACCESS_FOLDERS)) {
             $n_view->move = Horde::widget(array('url' => '#', 'class' => 'moveAction', 'title' => _("Move"), 'nocheck' => true));
             $n_view->copy = Horde::widget(array('url' => '#', 'class' => 'copyAction', 'title' => _("Copy"), 'nocheck' => true));
             $n_view->folder_options = $folder_options;
         }
         $n_view->mailbox_url = $mailbox_url;
         $n_view->mailbox = $mailbox->form_to;
         if ($pageOb['pagecount'] > 1) {
             $n_view->multiple_page = true;
             $n_view->pages_first = $pages_first;
             $n_view->url_first = $url_first;
             $n_view->pages_prev = $pages_prev;
             $n_view->url_prev = $url_prev;
             $n_view->pages_next = $pages_next;
             $n_view->url_next = $url_next;
             $n_view->pages_last = $pages_last;
             $n_view->url_last = $url_last;
             $n_view->page_val = $pageOb['page'];
             $n_view->page_size = Horde_String::length($pageOb['pagecount']);
         }
         $this->output .= $n_view->render('navbar');
         /* Prepare the actions template. */
         $a_view = clone $view;
         if ($mailbox->access_deletemsgs) {
             $del_class = $use_trash && $mailbox->trash ? 'permdeleteAction' : 'deleteAction';
             $a_view->delete = Horde::widget(array('url' => '#', 'class' => $del_class, 'title' => _("_Delete")));
         }
         if ($showdelete['purge'] || $mailbox->vtrash) {
             $a_view->undelete = Horde::widget(array('url' => '#', 'class' => 'undeleteAction', 'title' => _("_Undelete")));
         }
         $mboxactions = array();
         if ($showdelete['purge']) {
             $mailbox_link = $mailbox_imp_url->copy()->add('mpage', $pageOb['page']);
             if (isset($deleted_prompt)) {
                 $mboxactions[] = Horde::widget(array('url' => $mailbox_link->copy()->add(array('actionID' => 'hide_deleted', 'token' => $token)), 'class' => 'hideAction', 'title' => $deleted_prompt));
             }
             $mboxactions[] = Horde::widget(array('url' => $mailbox_link->copy()->add(array('actionID' => 'expunge_mailbox', 'token' => $token)), 'class' => 'purgeAction', 'title' => _("Pur_ge Deleted")));
         }
         if (!$sortpref->sortby_locked && $sortpref->sortby != Horde_Imap_Client::SORT_SEQUENCE) {
             $mboxactions[] = Horde::widget(array('url' => $mailbox_imp_url->copy()->add(array('sortby' => Horde_Imap_Client::SORT_SEQUENCE, 'actionID' => 'change_sort', 'token' => $token)), 'title' => _("Clear Sort")));
         }
         if ($mailbox->templates) {
             $a_view->templateedit = Horde::widget(array('url' => '#', 'class' => 'templateeditAction', 'title' => _("Edit Template")));
             $mboxactions[] = Horde::widget(array('url' => $clink->copy()->add(array('actionID' => 'template_new')), 'title' => _("Create New Template")));
         }
         $a_view->mboxactions = $mboxactions;
         if ($registry->hasMethod('mail/blacklistFrom')) {
             $a_view->blacklist = Horde::widget(array('url' => '#', 'class' => 'blacklistAction', 'title' => _("_Blacklist")));
         }
         if ($registry->hasMethod('mail/whitelistFrom')) {
             $a_view->whitelist = Horde::widget(array('url' => '#', 'class' => 'whitelistAction', 'title' => _("_Whitelist")));
         }
         if (IMP_Compose::canCompose()) {
             $a_view->forward = Horde::widget(array('url' => '#', 'class' => 'forwardAction', 'title' => _("Fo_rward")));
             $a_view->redirect = Horde::widget(array('url' => '#', 'class' => 'redirectAction', 'title' => _("Redirect")));
         }
         if ($mailbox->spam_show) {
             $a_view->spam = Horde::widget(array('url' => '#', 'class' => 'spamAction', 'title' => _("Report as Spam")));
         }
         if ($mailbox->innocent_show) {
             $a_view->innocent = Horde::widget(array('url' => '#', 'class' => 'innocentAction', 'title' => _("Report as Innocent")));
         }
         $a_view->view_messages = Horde::widget(array('url' => '#', 'class' => 'viewAction', 'title' => _("View Messages")));
         $this->output .= $a_view->render('actions');
     }
     /* Define some variables now so we don't have to keep redefining in
      * the foreach loop or the templates. */
     $lastMbox = '';
     $mh_count = 0;
     $sortImg = $sortpref->sortdir ? 'sortup' : 'sortdown';
     $headers = array(Horde_Imap_Client::SORT_TO => array('id' => 'mboxto', 'stext' => _("Sort by To Address"), 'text' => _("To")), Horde_Imap_Client::SORT_FROM => array('id' => 'mboxfrom', 'stext' => _("Sort by From Address"), 'text' => _("Fro_m")), Horde_Imap_Client::SORT_THREAD => array('id' => 'mboxthread', 'stext' => _("Sort by Thread"), 'text' => _("_Thread")), Horde_Imap_Client::SORT_SUBJECT => array('id' => 'mboxsubject', 'stext' => _("Sort by Subject"), 'text' => _("Sub_ject")), IMP::IMAP_SORT_DATE => array('id' => 'mboxdate', 'stext' => _("Sort by Date"), 'text' => _("Dat_e")), Horde_Imap_Client::SORT_SIZE => array('id' => 'mboxsize', 'stext' => _("Sort by Message Size"), 'text' => _("Si_ze")));
     /* If this is the Drafts or Sent-Mail mailbox, sort by To instead of
      * From. */
     if ($mailbox->special_outgoing) {
         unset($headers[Horde_Imap_Client::SORT_FROM]);
     } else {
         unset($headers[Horde_Imap_Client::SORT_TO]);
     }
     /* Determine which of Subject/Thread to emphasize. */
     if (!$mailbox->access_sortthread || $sortpref->sortby_locked) {
         unset($headers[Horde_Imap_Client::SORT_THREAD]);
         if ($sortpref->sortby_locked && $thread_sort) {
             $sortpref->sortby = Horde_Imap_Client::SORT_SUBJECT;
         }
     } else {
         if ($thread_sort) {
             $extra = Horde_Imap_Client::SORT_SUBJECT;
             $standard = Horde_Imap_Client::SORT_THREAD;
         } else {
             $extra = Horde_Imap_Client::SORT_THREAD;
             $standard = Horde_Imap_Client::SORT_SUBJECT;
         }
         $headers[$standard]['altsort'] = Horde::widget(array('url' => $mailbox_imp_url->copy()->add(array('actionID' => 'change_sort', 'token' => $token, 'sortby' => $extra)), 'title' => $headers[$extra]['text']));
         unset($headers[$extra]);
     }
     foreach ($headers as $key => $val) {
         $ptr =& $headers[$key];
         if ($sortpref->sortby == $key) {
             $csl_icon = '<span class="iconImg ' . $sortImg . '"></span>';
             if ($sortpref->sortdir_locked) {
                 $ptr['change_sort_link'] = $csl_icon;
                 $ptr['change_sort_widget'] = Horde::stripAccessKey($val['text']);
             } else {
                 $tmp = $mailbox_imp_url->copy()->add(array('sortby' => $key, 'sortdir' => intval(!$sortpref->sortdir), 'actionID' => 'change_sort', 'token' => $token));
                 $ptr['change_sort_link'] = Horde::link($tmp, $val['stext'], null, null, null, $val['stext']) . $csl_icon . '</a>';
                 $ptr['change_sort_widget'] = Horde::widget(array('url' => $tmp, 'title' => $val['text']));
             }
         } else {
             $ptr['change_sort_link'] = null;
             $ptr['change_sort_widget'] = $sortpref->sortby_locked ? Horde::stripAccessKey($val['text']) : Horde::widget(array('url' => $mailbox_imp_url->copy()->add(array('actionID' => 'change_sort', 'token' => $token, 'sortby' => $key)), 'title' => $val['text']));
         }
         $ptr['class'] = 'horde-split-left';
     }
     /* Output the form start. */
     $f_view = clone $view;
     $f_view->mailbox = $mailbox->form_to;
     $f_view->mailbox_url = $mailbox_url;
     $f_view->page = $pageOb['page'];
     $f_view->token = $token;
     $this->output .= $f_view->render('form_start');
     /* Prepare the message headers template. */
     $mh_view = clone $view;
     $mh_view->headers = $headers;
     if (!$search_mbox) {
         $mh_view->show_checkbox = !$mh_count++;
         $this->output .= $mh_view->render('message_headers');
     }
     /* Initialize repetitively used variables. */
     $fromlinkstyle = $prefs->getValue('from_link');
     $imp_ui = new IMP_Mailbox_Ui($mailbox);
     /* Display message information. */
     $msgs = array();
     $search_view = clone $view;
     $summary_view = clone $view;
     while (list(, $ob) = each($mbox_info['overview'])) {
         if ($search_mbox) {
             if (empty($lastMbox) || $ob['mailbox'] != $lastMbox) {
                 if (!empty($lastMbox)) {
                     $this->_outputSummaries($msgs, $summary_view);
                     $msgs = array();
                 }
                 $mbox = IMP_Mailbox::get($ob['mailbox']);
                 $search_view->mbox_link = Horde::link($mbox->url($mailbox_url), sprintf(_("View messages in %s"), $mbox->display), 'smallheader') . $mbox->display_html . '</a>';
                 $this->output .= $search_view->render('searchmbox');
                 $mh_view->show_checkbox = !$mh_count++;
                 $this->output .= $mh_view->render('message_headers');
             }
         }
         $lastMbox = $ob['mailbox'];
         /* Initialize the data fields. */
         $msg = array('bg' => '', 'buid' => $imp_mailbox->getBuid($ob['mailbox'], $ob['uid']), 'class' => '', 'date' => $imp_ui->getDate($ob['envelope']->date), 'preview' => '', 'status' => '', 'size' => IMP::sizeFormat($ob['size']));
         /* Generate the target link. */
         if ($mailbox->drafts || $mailbox->templates) {
             $clink_copy = clone $clink_ob;
             $clink_copy->args['buid'] = $msg['buid'];
             $clink_copy->args['mailbox'] = $mailbox;
             $target = $clink_copy->link()->add(array('actionID' => $mailbox->drafts ? 'draft' : 'template'));
         } else {
             $target = $mailbox->url('message', $msg['buid']);
         }
         /* Get all the flag information. */
         $flag_parse = $imp_flags->parse(array('flags' => $ob['flags'], 'headers' => $ob['headers'], 'runhook' => $ob, 'personal' => $ob['envelope']->to));
         $css_class = $subject_flags = array();
         foreach ($flag_parse as $val) {
             if ($val instanceof IMP_Flag_User) {
                 $subject_flags[] = $val;
             } else {
                 if (!$val->bgdefault) {
                     $msg['bg'] = $val->bgcolor;
                 }
                 $css_class[] = $val->css;
                 $msg['status'] .= $val->span;
             }
         }
         $msg['class'] = implode(' ', $css_class);
         /* Show message preview? */
         if ($show_preview && isset($ob['preview'])) {
             if (empty($ob['preview'])) {
                 $ptext = '[[' . _("No Preview Text") . ']]';
             } else {
                 $ptext = empty($strip_preview) ? str_replace("\r", '', $ob['preview']) : preg_replace(array('/\\n/', '/(\\s)+/'), array(' ', '$1'), str_replace("\r", "\n", $ob['preview']));
                 if (!$preview_tooltip) {
                     $ptext = $injector->getInstance('Horde_Core_Factory_TextFilter')->filter($ptext, 'text2html', array('parselevel' => Horde_Text_Filter_Text2html::NOHTML));
                 }
                 $maxlen = $prefs->getValue('preview_maxlen');
                 if (Horde_String::length($ptext) > $maxlen) {
                     $ptext = Horde_String::truncate($ptext, $maxlen);
                 } elseif (empty($ob['previewcut'])) {
                     $ptext .= '[[' . _("END") . ']]';
                 }
             }
             $msg['preview'] = $ptext;
         }
         /* Format the From: Header. */
         $getfrom = $imp_ui->getFrom($ob['envelope']);
         $msg['from'] = htmlspecialchars($getfrom['from'], ENT_QUOTES, 'UTF-8');
         switch ($fromlinkstyle) {
             case 0:
                 $from_tmp = array();
                 foreach ($getfrom['from_list']->base_addresses as $from_ob) {
                     $from_tmp[] = call_user_func_array(array('Horde', $preview_tooltip ? 'linkTooltip' : 'link'), array($clink->copy()->add(array('actionID' => 'mailto_link', 'to' => strval($from_ob))), sprintf(_("New Message to %s"), $from_ob->label))) . htmlspecialchars($from_ob->label, ENT_QUOTES, 'UTF-8') . '</a>';
                 }
                 if (!empty($from_tmp)) {
                     $msg['from'] = implode(', ', $from_tmp);
                 }
                 break;
             default:
                 $from_uri = $mailbox->url('message', $msg['buid']);
                 $msg['from'] = Horde::link($from_uri) . $msg['from'] . '</a>';
                 break;
         }
         /* Format the Subject: Header. */
         $msg['subject'] = $imp_ui->getSubject($ob['envelope']->subject, true);
         $msg['subject'] = $preview_tooltip ? substr(Horde::linkTooltip($target, $msg['preview'], '', '', '', $msg['preview']), 0, -1) . ' class="mboxSubject">' . $msg['subject'] . '</a>' : substr(Horde::link($target, $imp_ui->getSubject($ob['envelope']->subject)), 0, -1) . ' class="mboxSubject">' . $msg['subject'] . '</a>' . (!empty($msg['preview']) ? '<br /><small>' . $msg['preview'] . '</small>' : '');
         /* Add subject flags. */
         foreach ($subject_flags as $val) {
             $flag_label = Horde_String::truncate($val->label, 12);
             $msg['subject'] = '<span class="' . $val->css . '" style="' . ($val->bgdefault ? '' : 'background:' . htmlspecialchars($val->bgcolor) . ';') . 'color:' . htmlspecialchars($val->fgcolor) . '" title="' . htmlspecialchars($val->label) . '">' . htmlspecialchars($flag_label) . '</span>' . $msg['subject'];
         }
         /* Set up threading tree now. */
         if ($thread_sort) {
             $t_ob = $imp_mailbox->getThreadOb($ob['idx']);
             $msg['subject'] = ($sortpref->sortdir ? $t_ob->reverse_img : $t_ob->img) . ' ' . $msg['subject'];
         }
         $msgs[$msg['buid']] = $msg;
     }
     $this->_outputSummaries($msgs, $summary_view);
     $this->output .= '</form>';
     /* If there are 20 messages or less, don't show the actions/navbar
      * again. */
     if ($pageOb['end'] - $pageOb['begin'] >= 20) {
         $this->output .= $a_view->render('actions');
         $n_view->id = 2;
         $this->output .= $n_view->render('navbar');
     }
 }
Пример #4
0
 /**
  * Returns the main text body of the message suitable for sending over
  * EAS response.
  *
  * @param array $options  An options array containgin:
  *  - bodyprefs: (array)  Bodypref settings
  *               DEFAULT: none (No bodyprefs used).
  *  - mimesupport: (integer)  Indicates if MIME is supported or not.
  *                  Possible values: 0 - Not supported 1 - Only S/MIME or
  *                  2 - All MIME.
  *                  DEFAULT: 0 (No MIME support)
  *  - protocolversion: (float)  The EAS protocol we are supporting.
  *                     DEFAULT 2.5
  *
  * @return array  An array of one or both of 'plain' and 'html' content.
  *
  * @throws Horde_ActiveSync_Exception, Horde_Exception_NotFound
  */
 public function getMessageBodyData(array $options = array())
 {
     $version = empty($options['protocolversion']) ? Horde_ActiveSync::VERSION_TWOFIVE : $options['protocolversion'];
     // Look for the parts we need. We try to detect and fetch only the parts
     // we need, while ensuring we have something to return. So, e.g., if we
     // don't have BODYPREF_TYPE_HTML, we only request plain text, but if we
     // can't find plain text but we have a html body, fetch that anyway.
     $text_id = $this->_message->findBody('plain');
     $html_id = $this->_message->findBody('html');
     // Deduce which part(s) we need to request.
     $want_html_text = $version >= Horde_ActiveSync::VERSION_TWELVE && (!empty($options['bodyprefs'][Horde_ActiveSync::BODYPREF_TYPE_HTML]) || !empty($options['bodyprefs'][Horde_ActiveSync::BODYPREF_TYPE_MIME]));
     $want_plain_text = $version == Horde_ActiveSync::VERSION_TWOFIVE || empty($options['bodyprefs']) || !empty($options['bodyprefs'][Horde_ActiveSync::BODYPREF_TYPE_PLAIN]) || !empty($options['bodyprefs'][Horde_ActiveSync::BODYPREF_TYPE_RTF]) || !empty($options['bodyprefs'][Horde_ActiveSync::BODYPREF_TYPE_MIME]) || $want_html_text && empty($html_id);
     $want_html_as_plain = false;
     if (!empty($text_id) && $want_plain_text) {
         $text_body_part = $this->_message->getPart($text_id);
         $charset = $text_body_part->getCharset();
     } elseif ($want_plain_text && !empty($html_id) && empty($options['bodyprefs'][Horde_ActiveSync::BODYPREF_TYPE_MIME])) {
         $want_html_text = true;
         $want_html_as_plain = true;
     }
     if (!empty($html_id) && $want_html_text) {
         $html_body_part = $this->_message->getPart($html_id);
         $html_charset = $html_body_part->getCharset();
     }
     // Sanity check the truncation stuff
     if (empty($options['bodyprefs'][Horde_ActiveSync::BODYPREF_TYPE_PLAIN]) && !empty($options['bodyprefs'][Horde_ActiveSync::BODYPREF_TYPE_HTML]) && $want_plain_text && $want_html_text) {
         // We only have HTML truncation data, requested HTML body but only
         // have plaintext.
         $options['bodyprefs'][Horde_ActiveSync::BODYPREF_TYPE_PLAIN] = $options['bodyprefs'][Horde_ActiveSync::BODYPREF_TYPE_HTML];
     }
     $query = new Horde_Imap_Client_Fetch_Query();
     $query_opts = array('decode' => true, 'peek' => true);
     // Get body information
     if ($version >= Horde_ActiveSync::VERSION_TWELVE) {
         if (!empty($html_id)) {
             $query->bodyPartSize($html_id);
             $query->bodyPart($html_id, $query_opts);
         }
         if (!empty($text_id)) {
             $query->bodyPart($text_id, $query_opts);
             $query->bodyPartSize($text_id);
         }
     } else {
         // EAS 2.5 Plaintext body
         $query->bodyPart($text_id, $query_opts);
         $query->bodyPartSize($text_id);
     }
     try {
         $fetch_ret = $this->_imap->fetch($this->_mbox, $query, array('ids' => new Horde_Imap_Client_Ids(array($this->_uid))));
     } catch (Horde_Imap_Client_Exception $e) {
         throw new Horde_ActiveSync_Exception($e);
     }
     if (!($data = $fetch_ret->first())) {
         throw new Horde_Exception_NotFound(sprintf('Could not load message %s from server.', $this->_uid));
     }
     $return = array();
     if (!empty($text_id) && $want_plain_text) {
         $text = $data->getBodyPart($text_id);
         if (!$data->getBodyPartDecode($text_id)) {
             $text_body_part->setContents($text);
             $text = $text_body_part->getContents();
         }
         $text_size = !is_null($data->getBodyPartSize($text_id)) ? $data->getBodyPartSize($text_id) : Horde_String::length($text);
         if (!empty($options['bodyprefs'][Horde_ActiveSync::BODYPREF_TYPE_PLAIN]['truncationsize'])) {
             // EAS >= 12.0 truncation
             $text = Horde_String::substr($text, 0, $options['bodyprefs'][Horde_ActiveSync::BODYPREF_TYPE_PLAIN]['truncationsize'], $charset);
         }
         $truncated = $text_size > Horde_String::length($text);
         if ($version >= Horde_ActiveSync::VERSION_TWELVE && $truncated && !empty($options['bodyprefs'][Horde_ActiveSync::BODYPREF_TYPE_PLAIN]['allornone'])) {
             $text = '';
         }
         $return['plain'] = array('charset' => $charset, 'body' => $text, 'truncated' => $truncated, 'size' => $text_size);
     }
     if (!empty($html_id) && $want_html_text) {
         $html = $data->getBodyPart($html_id);
         if (!$data->getBodyPartDecode($html_id)) {
             $html_body_part->setContents($html);
             $html = $html_body_part->getContents();
         }
         // Size of the original HTML part.
         $html_size = !is_null($data->getBodyPartSize($html_id)) ? $data->getBodyPartSize($html_id) : Horde_String::length($html);
         if (!empty($options['bodyprefs'][Horde_ActiveSync::BODYPREF_TYPE_HTML]['truncationsize'])) {
             $html = Horde_String::substr($html, 0, $options['bodyprefs'][Horde_ActiveSync::BODYPREF_TYPE_HTML]['truncationsize'], $html_charset);
         } elseif ($want_html_as_plain) {
             $html = Horde_Text_Filter::filter($html, 'Html2text', array('charset' => $html_charset));
             // Get the new size, since it probably changed.
             $html_size = Horde_String::length($html);
             if (!empty($options['bodyprefs'][Horde_ActiveSync::BODYPREF_TYPE_PLAIN]['truncationsize'])) {
                 // EAS >= 12.0 truncation
                 $html = Horde_String::substr($html, 0, $options['bodyprefs'][Horde_ActiveSync::BODYPREF_TYPE_PLAIN]['truncationsize'], $html_charset);
             }
         }
         // Was the part truncated?
         $truncated = $html_size > Horde_String::length($html);
         if ($want_html_as_plain) {
             $return['plain'] = array('charset' => $html_charset, 'body' => $html, 'truncated' => $truncated, 'size' => $html_size);
         }
         if ($version >= Horde_ActiveSync::VERSION_TWELVE && !($truncated && !empty($options['bodyprefs'][Horde_ActiveSync::BODYPREF_TYPE_HTML]['allornone']))) {
             $return['html'] = array('charset' => $html_charset, 'body' => $html, 'estimated_size' => $html_size, 'truncated' => $truncated);
         }
     }
     return $return;
 }
Пример #5
0
 /**
  * Helper method to build a view object for a tweet.
  *
  * @param  stdClass $tweet  The tweet object.
  *
  * @return Horde_View  The view object, populated with tweet data.
  */
 protected function _buildTweet($tweet)
 {
     global $injector, $registry;
     $view = new Horde_View(array('templatePath' => HORDE_TEMPLATES . '/block'));
     $view->addHelper('Tag');
     $view->ajax_uri = $registry->getServiceLink('ajax', $registry->getApp());
     $filter = $injector->getInstance('Horde_Core_Factory_TextFilter');
     $instance = $this->vars->i;
     // Links and media
     $map = $previews = array();
     foreach ($tweet->entities->urls as $link) {
         $replace = '<a target="_blank" href="' . $link->url . '" title="' . $link->expanded_url . '">' . htmlspecialchars($link->display_url) . '</a>';
         $map[$link->indices[0]] = array($link->indices[1], $replace);
     }
     if (!empty($tweet->entities->media)) {
         foreach ($tweet->entities->media as $picture) {
             $replace = '<a target="_blank" href="' . $picture->url . '" title="' . $picture->expanded_url . '">' . htmlentities($picture->display_url, ENT_COMPAT, 'UTF-8') . '</a>';
             $map[$picture->indices[0]] = array($picture->indices[1], $replace);
             $previews[] = ' <a href="#" onclick="return Horde[\'twitter' . $instance . '\'].showPreview(\'' . $picture->media_url . ':small\');"><img src="' . Horde_Themes::img('mime/image.png') . '" /></a>';
         }
     }
     if (!empty($tweet->entities->user_mentions)) {
         foreach ($tweet->entities->user_mentions as $user) {
             $replace = ' <a target="_blank" title="' . $user->name . '" href="http://twitter.com/' . $user->screen_name . '">@' . htmlentities($user->screen_name, ENT_COMPAT, 'UTF-8') . '</a>';
             $map[$user->indices[0]] = array($user->indices[1], $replace);
         }
     }
     if (!empty($tweet->entities->hashtags)) {
         foreach ($tweet->entities->hashtags as $hashtag) {
             $replace = ' <a target="_blank" href="http://twitter.com/search?q=#' . urlencode($hashtag->text) . '">#' . htmlentities($hashtag->text, ENT_COMPAT, 'UTF-8') . '</a>';
             $map[$hashtag->indices[0]] = array($hashtag->indices[1], $replace);
         }
     }
     $body = '';
     $pos = 0;
     while ($pos <= Horde_String::length($tweet->text) - 1) {
         if (!empty($map[$pos])) {
             $entity = $map[$pos];
             $body .= $entity[1];
             $pos = $entity[0];
         } else {
             $body .= Horde_String::substr($tweet->text, $pos, 1);
             ++$pos;
         }
     }
     foreach ($previews as $preview) {
         $body .= $preview;
     }
     $view->body = $body;
     /* If this is a retweet, use the original author's profile info */
     if (!empty($tweet->retweeted_status)) {
         $tweetObj = $tweet->retweeted_status;
     } else {
         $tweetObj = $tweet;
     }
     /* These are all referencing the *original* tweet */
     $view->profileLink = Horde::externalUrl('http://twitter.com/' . htmlspecialchars($tweetObj->user->screen_name), true);
     $view->profileImg = $GLOBALS['browser']->usingSSLConnection() ? $tweetObj->user->profile_image_url_https : $tweetObj->user->profile_image_url;
     $view->authorName = '@' . htmlspecialchars($tweetObj->user->screen_name);
     $view->authorFullname = htmlspecialchars($tweetObj->user->name);
     $view->createdAt = $tweetObj->created_at;
     $view->clientText = $filter->filter($tweet->source, 'xss');
     $view->tweet = $tweet;
     $view->instanceid = $instance;
     return $view;
 }
Пример #6
0
 /**
  * Create an AS memo from this task
  *
  * @param array $memo  A memo array.
  * @param array $options
  *
  * @return Horde_ActiveSync_Message_Note
  */
 public function toASNote($memo, $options = array())
 {
     $message = new Horde_ActiveSync_Message_Note(array('protocolversion' => $options['protocolversion']));
     $message->subject = $memo['desc'];
     $bp = $options['bodyprefs'];
     $body = new Horde_ActiveSync_Message_AirSyncBaseBody();
     // When the note is encrypted, we won't have the passphrase so the
     // body will be a Mnemo_Exception.
     if ($memo['body'] instanceof Mnemo_Exception) {
         $memo['body'] = $memo['body']->getMessage();
     }
     if (isset($bp[Horde_ActiveSync::BODYPREF_TYPE_HTML])) {
         $body->type = Horde_ActiveSync::BODYPREF_TYPE_HTML;
         $memo['body'] = Horde_Text_Filter::filter($memo['body'], 'Text2html', array('parselevel' => Horde_Text_Filter_Text2html::MICRO));
         if (isset($bp[Horde_ActiveSync::BODYPREF_TYPE_HTML]['truncationsize']) && Horde_String::length($memo['body']) > $bp[Horde_ActiveSync::BODYPREF_TYPE_HTML]['truncationsize']) {
             $body->data = Horde_String::substr($memo['body'], $bp[Horde_ActiveSync::BODYPREF_TYPE_HTML]['truncationsize']);
             $body->truncated = 1;
         } else {
             $body->data = $memo['body'];
         }
     } else {
         $body->type = Horde_ActiveSync::BODYPREF_TYPE_PLAIN;
         if (isset($bp[Horde_ActiveSync::BODYPREF_TYPE_PLAIN]['truncationsize']) && Horde_String::length($memo['body']) > $bp[Horde_ActiveSync::BODYPREF_TYPE_PLAIN]['truncationsize']) {
             $body->data = Horde_String::substr($memo['body'], 0, $bp[Horde_ActiveSync::BODYPREF_TYPE_PLAIN]['truncationsize']);
             $body->truncated = 1;
         } else {
             $body->data = $memo['body'];
         }
     }
     $body->estimateddatasize = Horde_String::length($memo['body']);
     $message->body = $body;
     if (!empty($memo['tags'])) {
         $message->categories = $memo['tags'];
     }
     $history = $GLOBALS['injector']->getInstance('Horde_History');
     $last = $history->getActionTimeStamp('mnemo:' . $memo['memolist_id'] . ':' . $memo['uid'], 'modify');
     if (empty($last)) {
         $last = $history->getActionTimeStamp('mnemo:' . $memo['memolist_id'] . ':' . $memo['uid'], 'add');
     }
     $message->lastmodified = new Horde_Date($last);
     return $message;
 }
Пример #7
0
 /**
  * Takes all necessary actions for the given import step, parameters and
  * form values and returns the next necessary step.
  *
  * @param integer $action  The current step. One of the IMPORT_* constants.
  * @param array $param     An associative array containing needed
  *                         parameters for the current step. Keys for this
  *                         driver:
  *   - check_charset: (boolean) Do some checks to see if the correct
  *                    charset has been provided. Throws charset exception
  *                    on error.
  *   - import_mapping: TODO
  *
  * @return mixed  Either the next step as an integer constant or imported
  *                data set after the final step.
  * @throws Horde_Data_Exception
  * @throws Horde_Data_Exception_Charset
  */
 public function nextStep($action, array $param = array())
 {
     switch ($action) {
         case Horde_Data::IMPORT_FILE:
             parent::nextStep($action, $param);
             /* Move uploaded file so that we can read it again in the next
                step after the user gave some format details. */
             $file_name = $_FILES['import_file']['tmp_name'];
             if (($file_data = file_get_contents($file_name)) === false) {
                 throw new Horde_Data_Exception(Horde_Data_Translation::t("The uploaded file could not be saved."));
             }
             /* Do charset checking now, if requested. */
             if (isset($param['check_charset'])) {
                 $charset = isset($this->_vars->charset) ? Horde_String::lower($this->_vars->charset) : 'utf-8';
                 switch ($charset) {
                     case 'utf-8':
                         $error = !Horde_String::validUtf8($file_data);
                         break;
                     default:
                         $error = $file_data != Horde_String::convertCharset(Horde_String::convertCharset($file_data, $charset, 'UTF-8'), 'UTF-8', $charset);
                         break;
                 }
                 if ($error) {
                     $e = new Horde_Data_Exception_Charset(Horde_Data_Translation::t("Incorrect charset given for the data."));
                     $e->badCharset = $charset;
                     throw $e;
                 }
             }
             $this->storage->set('charset', $this->_vars->charset);
             $this->storage->set('file_data', $file_data);
             /* Read the file's first two lines to show them to the user. */
             $first_lines = '';
             if ($fp = @fopen($file_name, 'r')) {
                 for ($line_no = 1, $line = fgets($fp); $line_no <= 3 && $line; $line_no++, $line = fgets($fp)) {
                     $line = Horde_String::convertCharset($line, $this->_vars->charset, 'UTF-8');
                     $first_lines .= Horde_String::truncate($line);
                     if (Horde_String::length($line) > 100) {
                         $first_lines .= "\n";
                     }
                 }
             }
             $this->storage->set('first_lines', $first_lines);
             /* Import the first line to guess the number of fields. */
             if ($first_lines) {
                 rewind($fp);
                 $line = self::getCsv($fp);
                 if ($line) {
                     $this->storage->set('fields', count($line));
                 }
             }
             return Horde_Data::IMPORT_CSV;
         case Horde_Data::IMPORT_CSV:
             $this->storage->set('header', $this->_vars->header);
             $import_mapping = array();
             if (isset($param['import_mapping'])) {
                 $import_mapping = $param['import_mapping'];
             }
             $file_name = Horde_Util::getTempFile('import');
             file_put_contents($file_name, $this->storage->get('file_data'));
             $this->storage->set('data', $this->importFile($file_name, $this->_vars->header, $this->_vars->sep, $this->_vars->quote, $this->_vars->fields, $import_mapping, $this->storage->get('charset'), $this->storage->get('crlf')));
             $this->storage->set('map');
             return Horde_Data::IMPORT_MAPPED;
         default:
             return parent::nextStep($action, $param);
     }
 }
Пример #8
0
 /**
  * Takes all necessary actions for the given import step, parameters and
  * form values and returns the next necessary step.
  *
  * @param integer $action  The current step. One of the IMPORT_* constants.
  * @param array $param     An associative array containing needed
  *                         parameters for the current step.
  *
  * @return mixed  Either the next step as an integer constant or imported
  *                data set after the final step.
  * @throws Horde_Data_Exception
  */
 public function nextStep($action, array $param = array())
 {
     switch ($action) {
         case Horde_Data::IMPORT_FILE:
             parent::nextStep($action, $param);
             $format = $this->storage->get('format');
             if (in_array($format, array('mulberry', 'pine'))) {
                 $filedata = $this->importFile($_FILES['import_file']['tmp_name']);
                 switch ($format) {
                     case 'mulberry':
                         $appKeys = array('alias', 'name', 'email', 'company', 'workAddress', 'workPhone', 'homePhone', 'fax', 'notes');
                         $dataKeys = array(0, 1, 2, 3, 4, 5, 6, 7, 9);
                         break;
                     case 'pine':
                         $appKeys = array('alias', 'name', 'email', 'notes');
                         $dataKeys = array(0, 1, 2, 4);
                         break;
                 }
                 foreach ($appKeys as $key => $app) {
                     $map[$dataKeys[$key]] = $app;
                 }
                 $data = array();
                 foreach ($filedata as $row) {
                     $hash = array();
                     switch ($format) {
                         case 'mulberry':
                             if (preg_match("/^Grp:/", $row[0]) || empty($row[1])) {
                                 continue;
                             }
                             $row[1] = preg_replace('/^([^,"]+),\\s*(.*)$/', '$2 $1', $row[1]);
                             foreach ($dataKeys as $key) {
                                 if (array_key_exists($key, $row)) {
                                     $hash[$key] = stripslashes(preg_replace('/\\\\r/', "\n", $row[$key]));
                                 }
                             }
                             break;
                         case 'pine':
                             if (count($row) < 3 || preg_match("/^#DELETED/", $row[0]) || preg_match("/[()]/", $row[2])) {
                                 continue;
                             }
                             $row[1] = preg_replace('/^([^,"]+),\\s*(.*)$/', '$2 $1', $row[1]);
                             /* Address can be a full RFC822 address */
                             $addr_ob = new Horde_Mail_Rfc822_Address($row[2]);
                             if (!$addr_ob->valid) {
                                 continue;
                             }
                             $row[2] = $addr_ob->bare_address;
                             if (empty($row[1]) && !is_null($addr_ob->personal)) {
                                 $row[1] = $addr_ob->personal;
                             }
                             foreach ($dataKeys as $key) {
                                 if (array_key_exists($key, $row)) {
                                     $hash[$key] = $row[$key];
                                 }
                             }
                             break;
                     }
                     $data[] = $hash;
                 }
                 $this->storage->set('data', $data);
                 $this->storage->set('map', $map);
                 return $this->nextStep(Horde_Data::IMPORT_DATA, $param);
             }
             /* Store uploaded file data so that we can read it again in the
              * next step after the user gives some format details. */
             try {
                 $this->_browser->wasFileUploaded('import_file', Horde_Data_Translation::t("TSV file"));
             } catch (Horde_Browser_Exception $e) {
                 throw new Horde_Data_Exception($e);
             }
             $file_name = $_FILES['import_file']['tmp_name'];
             if (($file_data = file_get_contents($file_name)) === false) {
                 throw new Horde_Data_Exception(Horde_Data_Translation::t("The uploaded file could not be saved."));
             }
             $this->storage->set('file_data', $file_data);
             /* Read the file's first two lines to show them to the user. */
             $first_lines = '';
             if ($fp = @fopen($file_name, 'r')) {
                 $line_no = 1;
                 while ($line_no < 3 && ($line = fgets($fp))) {
                     $newline = Horde_String::length($line) > 100 ? "\n" : '';
                     $first_lines .= substr($line, 0, 100) . $newline;
                     ++$line_no;
                 }
             }
             $this->storage->set('first_lines', $first_lines);
             return Horde_Data::IMPORT_TSV;
         case Horde_Data::IMPORT_TSV:
             $file_name = Horde_Util::getTempFile('import');
             file_put_contents($file_name, $this->storage->get('file_data'));
             $this->storage->set('header', $this->_vars->header);
             $this->storage->set('data', $this->importFile($file_name, $this->storage->get('header')));
             $this->storage->set('map');
             return Horde_Data::IMPORT_MAPPED;
     }
     return parent::nextStep($action, $param);
 }
Пример #9
0
 /**
  * Formats the name according to the user's preference.
  *
  * If the format is 'none', the full name with all parts is returned. If
  * the format is 'last_first' or 'first_last', only the first name and
  * last name are returned.
  *
  * @param Turba_Object $ob     The object to get a name from.
  * @param string $name_format  The formatting. One of 'none', 'last_first'
  *                             or 'first_last'. Defaults to the user
  *                             preference.
  *
  * @return string  The formatted name, either "Firstname Lastname"
  *                 or "Lastname, Firstname" depending on $name_format or
  *                 the user's preference.
  */
 public static function formatName(Turba_Object $ob, $name_format = null)
 {
     if (!$name_format) {
         if (!isset(self::$_cache['defaultFormat'])) {
             self::$_cache['defaultFormat'] = $GLOBALS['prefs']->getValue('name_format');
         }
         $name_format = self::$_cache['defaultFormat'];
     }
     /* If no formatting, return original name. */
     if (!in_array($name_format, array('first_last', 'last_first'))) {
         return $ob->getValue('name');
     }
     /* See if we have the name fields split out explicitly. */
     if ($ob->hasValue('firstname') && $ob->hasValue('lastname')) {
         return $name_format == 'last_first' ? $ob->getValue('lastname') . ', ' . $ob->getValue('firstname') : $ob->getValue('firstname') . ' ' . $ob->getValue('lastname');
     }
     /* One field, we'll have to guess. */
     $name = $ob->getValue('name');
     $lastname = self::guessLastname($name);
     if ($name_format == 'last_first' && !is_int(strpos($name, ',')) && Horde_String::length($name) > Horde_String::length($lastname)) {
         return $lastname . ', ' . preg_replace('/\\s+' . preg_quote($lastname, '/') . '/', '', $name);
     }
     if ($name_format == 'first_last' && is_int(strpos($name, ',')) && Horde_String::length($name) > Horde_String::length($lastname)) {
         return preg_replace('/' . preg_quote($lastname, '/') . ',\\s*/', '', $name) . ' ' . $lastname;
     }
     return $name;
 }
Пример #10
0
 /**
  * Outputs data
  *
  * @param mixed $content  A string or stream resource to write to the output
  */
 private function _content($content)
 {
     if (!is_resource($content)) {
         if ($this->_logLevel == self::LOG_PROTOCOL && ($l = Horde_String::length($content)) > self::LOG_MAXCONTENT) {
             $this->_logContent(sprintf('[%d bytes of content]', $l));
         } else {
             $this->_logContent($content);
         }
     } else {
         $this->_logContent('[STREAM]');
     }
     $this->_outByte(self::STR_I);
     $this->_outTermStr($content);
 }
Пример #11
0
        Horde::url('list.php', true)->redirect();
    default:
        Horde::url('list.php', true)->redirect();
}
$view = $injector->createInstance('Horde_View');
$view->formInput = Horde_Util::formInput();
$view->id = $memo_id;
$view->listid = $memolist_id;
$view->modify = $actionID == 'modify_memo';
$view->passphrase = $show_passphrase;
$view->title = $title;
$view->url = Horde::url('memo.php');
if (!$view->modify || !$view->passphrase) {
    $injector->getInstance('Horde_Core_Factory_Imple')->create('Mnemo_Ajax_Imple_TagAutoCompleter', array('id' => 'memo_tags'));
    $view->body = $memo_body;
    $view->count = sprintf(_("%s characters"), '<span id="mnemo-count">' . Horde_String::length(str_replace(array("\r", "\n"), '', $memo_body)) . '</span>');
    $view->encrypted = $memo_encrypted;
    $view->encryption = $storage->encryptionSupported();
    try {
        $view->help = Horde::callHook('description_help', array(), 'mnemo', '');
    } catch (Horde_Exception_HookNotSet $e) {
    }
    $view->loadingImg = Horde::img('loading.gif', _("Loading..."));
    $view->notepads = array();
    if (!$prefs->isLocked('default_notepad')) {
        foreach (Mnemo::listNotepads(false, Horde_Perms::SHOW) as $id => $notepad) {
            if (!$notepad->hasPermission($user, Horde_Perms::EDIT)) {
                continue;
            }
            $view->notepads[] = array('id' => $id, 'selected' => $id == $memolist_id, 'label' => Mnemo::getLabel($notepad));
        }
Пример #12
0
 /**
  * Limits a string to a given maximum length in a smarter way than just
  * using substr().
  *
  * Namely, cut from the MIDDLE instead of from the end so that if we're
  * doing this on (for instance) a bunch of binder names that start off with
  * the same verbose description, and then are different only at the very
  * end, they'll still be different from one another after truncating.
  *
  * <code>
  * $str = 'The quick brown fox jumps over the lazy dog tomorrow morning.';
  * $shortStr = $this->truncateMiddle($str, 40);
  * // $shortStr == 'The quick brown fox... tomorrow morning.'
  * </code>
  *
  * @param string $str         A text to truncate.
  * @param integer $maxLength  The maximum length of the text
  * @param string $joiner      Replacement string for the truncated text.
  *
  * @return string  The truncated text.
  */
 public function truncateMiddle($str, $maxLength = 80, $joiner = '...')
 {
     if (Horde_String::length($str) <= $maxLength) {
         return $str;
     }
     $maxLength = $maxLength - Horde_String::length($joiner);
     if ($maxLength <= 0) {
         return $str;
     }
     $startPieceLength = (int) ceil($maxLength / 2);
     $endPieceLength = (int) floor($maxLength / 2);
     $trimmedString = rtrim(Horde_String::substr($str, 0, $startPieceLength)) . $joiner;
     if ($endPieceLength > 0) {
         $trimmedString .= ltrim(Horde_String::substr($str, -1 * $endPieceLength));
     }
     return $trimmedString;
 }
Пример #13
0
 /**
  * Regenerates body text for use in the compose screen from IMAP data.
  *
  * @param IMP_Contents $contents  An IMP_Contents object.
  * @param array $options          Additional options:
  * <ul>
  *  <li>html: (boolean) Return text/html part, if available.</li>
  *  <li>imp_msg: (integer) If non-empty, the message data was created by
  *               IMP. Either:
  *   <ul>
  *    <li>self::COMPOSE</li>
  *    <li>self::FORWARD</li>
  *    <li>self::REPLY</li>
  *   </ul>
  *  </li>
  *  <li>replylimit: (boolean) Enforce length limits?</li>
  *  <li>toflowed: (boolean) Do flowed conversion?</li>
  * </ul>
  *
  * @return mixed  Null if bodypart not found, or array with the following
  *                keys:
  *   - charset: (string) The guessed charset to use.
  *   - flowed: (Horde_Text_Flowed) A flowed object, if the text is flowed.
  *             Otherwise, null.
  *   - id: (string) The MIME ID of the bodypart.
  *   - mode: (string) Either 'text' or 'html'.
  *   - text: (string) The body text.
  */
 protected function _getMessageText($contents, array $options = array())
 {
     global $conf, $injector, $notification, $prefs;
     $body_id = null;
     $mode = 'text';
     $options = array_merge(array('imp_msg' => self::COMPOSE), $options);
     if (!empty($options['html']) && self::canHtmlCompose() && ($body_id = $contents->findBody('html')) !== null) {
         $mime_message = $contents->getMIMEMessage();
         switch ($mime_message->getPrimaryType()) {
             case 'multipart':
                 if ($body_id != '1' && $mime_message->getSubType() == 'mixed' && ($id_ob = new Horde_Mime_Id('1')) && !$id_ob->isChild($body_id)) {
                     $body_id = null;
                 } else {
                     $mode = 'html';
                 }
                 break;
             default:
                 if (strval($body_id) != '1') {
                     $body_id = null;
                 } else {
                     $mode = 'html';
                 }
                 break;
         }
     }
     if (is_null($body_id)) {
         $body_id = $contents->findBody();
         if (is_null($body_id)) {
             return null;
         }
     }
     if (!($part = $contents->getMimePart($body_id))) {
         return null;
     }
     $type = $part->getType();
     $part_charset = $part->getCharset();
     $msg = Horde_String::convertCharset($part->getContents(), $part_charset, 'UTF-8');
     /* Enforce reply limits. */
     if (!empty($options['replylimit']) && !empty($conf['compose']['reply_limit'])) {
         $limit = $conf['compose']['reply_limit'];
         if (Horde_String::length($msg) > $limit) {
             $msg = Horde_String::substr($msg, 0, $limit) . "\n" . _("[Truncated Text]");
         }
     }
     if ($mode == 'html') {
         $dom = $injector->getInstance('Horde_Core_Factory_TextFilter')->filter($msg, 'Xss', array('charset' => $this->charset, 'return_dom' => true, 'strip_style_attributes' => false));
         /* If we are replying to a related part, and this part refers
          * to local message parts, we need to move those parts into this
          * message (since the original message may disappear during the
          * compose process). */
         if ($related_part = $contents->findMimeType($body_id, 'multipart/related')) {
             $this->_setMetadata('related_contents', $contents);
             $related_ob = new Horde_Mime_Related($related_part);
             $related_ob->cidReplace($dom, array($this, '_getMessageTextCallback'), $part_charset);
             $this->_setMetadata('related_contents', null);
         }
         /* Convert any Data URLs to attachments. */
         $xpath = new DOMXPath($dom->dom);
         foreach ($xpath->query('//*[@src]') as $val) {
             $data_url = new Horde_Url_Data($val->getAttribute('src'));
             if (strlen($data_url->data)) {
                 $data_part = new Horde_Mime_Part();
                 $data_part->setContents($data_url->data);
                 $data_part->setType($data_url->type);
                 try {
                     $atc = $this->addAttachmentFromPart($data_part);
                     $val->setAttribute('src', $atc->viewUrl());
                     $this->addRelatedAttachment($atc, $val, 'src');
                 } catch (IMP_Compose_Exception $e) {
                     $notification->push($e, 'horde.warning');
                 }
             }
         }
         $msg = $dom->returnBody();
     } elseif ($type == 'text/html') {
         $msg = $injector->getInstance('Horde_Core_Factory_TextFilter')->filter($msg, 'Html2text');
         $type = 'text/plain';
     }
     /* Always remove leading/trailing whitespace. The data in the
      * message body is not intended to be the exact representation of the
      * original message (use forward as message/rfc822 part for that). */
     $msg = trim($msg);
     if ($type == 'text/plain') {
         if ($prefs->getValue('reply_strip_sig') && ($pos = strrpos($msg, "\n-- ")) !== false) {
             $msg = rtrim(substr($msg, 0, $pos));
         }
         /* Remove PGP armored text. */
         $pgp = $injector->getInstance('Horde_Crypt_Pgp_Parse')->parseToPart($msg);
         if (!is_null($pgp)) {
             $msg = '';
             $pgp->buildMimeIds();
             foreach ($pgp->partIterator() as $val) {
                 if ($val->getPrimaryType() === 'text') {
                     $msg .= $val->getContents();
                 }
             }
         }
         if ($part->getContentTypeParameter('format') == 'flowed') {
             $flowed = new Horde_Text_Flowed($msg, 'UTF-8');
             if (Horde_String::lower($part->getContentTypeParameter('delsp')) == 'yes') {
                 $flowed->setDelSp(true);
             }
             $flowed->setMaxLength(0);
             $msg = $flowed->toFixed(false);
         } else {
             /* If the input is *not* in flowed format, make sure there is
              * no padding at the end of lines. */
             $msg = preg_replace("/\\s*\n/U", "\n", $msg);
         }
         if (isset($options['toflowed'])) {
             $flowed = new Horde_Text_Flowed($msg, 'UTF-8');
             $msg = $options['toflowed'] ? $flowed->toFlowed(true) : $flowed->toFlowed(false, array('nowrap' => true));
         }
     }
     if (strcasecmp($part->getCharset(), 'windows-1252') === 0) {
         $part_charset = 'ISO-8859-1';
     }
     return array('charset' => $part_charset, 'flowed' => isset($flowed) ? $flowed : null, 'id' => $body_id, 'mode' => $mode, 'text' => $msg);
 }
Пример #14
0
 /**
  * Returns the widget necessary to configure this block.
  *
  * @param $app TODO
  * @param $block TODO
  * @param $param_id TODO
  * @param $val TODO
  *
  * @return TODO
  */
 public function getOptionsWidget($app, $block, $param_id, $val = null)
 {
     $widget = '';
     /* getParams() loads $_blocks */
     $this->getParams($app, $block);
     $param = $this->_blocks[$app][$block]['params'][$param_id];
     if (!isset($param['default'])) {
         $param['default'] = '';
     }
     switch ($param['type']) {
         case 'boolean':
         case 'checkbox':
             $checked = !empty($val[$param_id]) ? ' checked="checked"' : '';
             $widget = sprintf('<input type="checkbox" name="params[%s]"%s />', $param_id, $checked);
             break;
         case 'enum':
             $widget = sprintf('<select name="params[%s]">', $param_id);
             foreach ($param['values'] as $key => $name) {
                 if (Horde_String::length($name) > 30) {
                     $name = substr($name, 0, 27) . '...';
                 }
                 $widget .= sprintf("<option value=\"%s\"%s>%s</option>\n", htmlspecialchars($key), isset($val[$param_id]) && $val[$param_id] == $key ? ' selected="selected"' : '', htmlspecialchars($name));
             }
             $widget .= '</select>';
             break;
         case 'multienum':
             $widget = sprintf('<select multiple="multiple" name="params[%s][]">', $param_id);
             foreach ($param['values'] as $key => $name) {
                 if (Horde_String::length($name) > 30) {
                     $name = substr($name, 0, 27) . '...';
                 }
                 $widget .= sprintf("<option value=\"%s\"%s>%s</option>\n", htmlspecialchars($key), isset($val[$param_id]) && in_array($key, $val[$param_id]) ? ' selected="selected"' : '', htmlspecialchars($name));
             }
             $widget .= '</select>';
             break;
         case 'mlenum':
             // Multi-level enum.
             if (is_array($val) && isset($val['__' . $param_id])) {
                 $firstval = $val['__' . $param_id];
             } else {
                 $tmp = array_keys($param['values']);
                 $firstval = current($tmp);
             }
             $blockvalues = $param['values'][$firstval];
             asort($blockvalues);
             $widget = sprintf('<select name="params[__%s]" onchange="document.blockform.action.value=\'save-resume\';document.blockform.submit()">', $param_id) . "\n";
             foreach (array_keys($param['values']) as $key) {
                 $name = Horde_String::length($key) > 30 ? Horde_String::substr($key, 0, 27) . '...' : $key;
                 $widget .= sprintf("<option value=\"%s\"%s>%s</option>\n", htmlspecialchars($key), $key == $firstval ? ' selected="selected"' : '', htmlspecialchars($name));
             }
             $widget .= "</select><br />\n";
             $widget .= sprintf("<select name=\"params[%s]\">\n", $param_id);
             foreach ($blockvalues as $key => $name) {
                 $name = Horde_String::length($name) > 30 ? Horde_String::substr($name, 0, 27) . '...' : $name;
                 $widget .= sprintf("<option value=\"%s\"%s>%s</option>\n", htmlspecialchars($key), $val[$param_id] == $key ? ' selected="selected"' : '', htmlspecialchars($name));
             }
             $widget .= "</select><br />\n";
             break;
         case 'int':
         case 'text':
             $widget = sprintf('<input type="text" name="params[%s]" value="%s" />', $param_id, !isset($val[$param_id]) ? $param['default'] : $val[$param_id]);
             break;
         case 'password':
             $widget = sprintf('<input type="password" name="params[%s]" value="%s" />', $param_id, !isset($val[$param_id]) ? $param['default'] : $val[$param_id]);
             break;
         case 'error':
             $widget = '<span class="form-error">' . $param['default'] . '</span>';
             break;
     }
     return $widget;
 }
Пример #15
0
 /**
  * Generate the preview text.
  *
  * @return array  Array with the following keys:
  *   - cut: (boolean) Was the preview text cut?
  *   - text: (string) The preview text.
  */
 public function generatePreview()
 {
     // For preview generation, don't go through overhead of scanning for
     // embedded parts. Necessary evil, or else very large parts (e.g
     // 5 MB+ text parts) will take ages to scan.
     $oldbuild = $this->_build;
     $this->_build = true;
     $mimeid = $this->findBody();
     if (is_null($mimeid)) {
         $this->_build = $oldbuild;
         return array('cut' => false, 'text' => '');
     }
     $maxlen = empty($GLOBALS['conf']['msgcache']['preview_size']) ? $GLOBALS['prefs']->getValue('preview_maxlen') : $GLOBALS['conf']['msgcache']['preview_size'];
     // Retrieve 3x the size of $maxlen of bodytext data. This should
     // account for any content-encoding & HTML tags.
     $pmime = $this->getMIMEPart($mimeid, array('length' => $maxlen * 3));
     $ptext = Horde_String::convertCharset($pmime->getContents(), $pmime->getCharset(), 'UTF-8');
     if ($pmime->getType() == 'text/html') {
         $ptext = $GLOBALS['injector']->getInstance('Horde_Core_Factory_TextFilter')->filter($ptext, 'Html2text');
     }
     $this->_build = $oldbuild;
     if (Horde_String::length($ptext) > $maxlen) {
         return array('cut' => true, 'text' => Horde_String::truncate($ptext, $maxlen));
     }
     return array('cut' => false, 'text' => $ptext);
 }
Пример #16
0
 /**
  * Log the token.
  *
  * @param array  The element array.
  *
  * @return void
  */
 protected function _logToken($el)
 {
     switch ($el[self::EN_TYPE]) {
         case self::EN_TYPE_STARTTAG:
             if ($el[self::EN_FLAGS] & self::EN_FLAGS_CONTENT) {
                 $spaces = str_repeat(' ', count($this->_logStack));
                 $this->_logStack[] = $el[self::EN_TAG];
                 $this->_logger->debug(sprintf('[%s] I %s <%s>', $this->_procid, $spaces, $el[self::EN_TAG]));
             } else {
                 $spaces = str_repeat(' ', count($this->_logStack));
                 $this->_logger->debug(sprintf('[%s] I %s <%s />', $this->_procid, $spaces, $el[self::EN_TAG]));
             }
             break;
         case self::EN_TYPE_ENDTAG:
             $tag = array_pop($this->_logStack);
             $spaces = str_repeat(' ', count($this->_logStack));
             $this->_logger->debug(sprintf('[%s] I %s </%s>', $this->_procid, $spaces, $tag));
             break;
         case self::EN_TYPE_CONTENT:
             $spaces = str_repeat(' ', count($this->_logStack) + 1);
             if ($this->_logLevel == self::LOG_PROTOCOL && ($l = Horde_String::length($el[self::EN_CONTENT])) > self::LOG_MAXCONTENT) {
                 $this->_logger->debug(sprintf('[%s] I %s %s', $this->_procid, $spaces, sprintf('[%d bytes of content]', $l)));
             } else {
                 $this->_logger->debug(sprintf('[%s] I %s %s', $this->_procid, $spaces, $el[self::EN_CONTENT]));
             }
             break;
     }
 }
Пример #17
0
 /**
  * Executes any code necessary after applying the filter patterns.
  *
  * @param string $text  The text after the filtering.
  *
  * @return string  The modified text.
  */
 public function postProcess($text)
 {
     try {
         $dom = new Horde_Domhtml($text, $this->_params['charset']);
         // Add two to take into account the <html> and <body> nodes.
         if (!empty($this->_params['nestingLimit'])) {
             $this->_params['nestingLimit'] += 2;
         }
         $text = Horde_String::convertCharset($this->_node($dom->dom, $dom->dom), 'UTF-8', $this->_params['charset']);
     } catch (Exception $e) {
         $text = strip_tags(preg_replace("/\\<br\\s*\\/?\\>/i", "\n", $text));
     }
     /* Bring down number of empty lines to 2 max, and remove trailing
      * ws. */
     $text = preg_replace(array("/\\s*\n{3,}/", "/ +\n/"), array("\n\n", "\n"), $text);
     /* Wrap the text to a readable format. */
     if ($this->_params['width']) {
         $text = wordwrap($text, $this->_params['width']);
     }
     /* Add link list. */
     if (!empty($this->_linkList)) {
         $text .= "\n\n" . Horde_Text_Filter_Translation::t("Links") . ":\n" . str_repeat('-', Horde_String::length(Horde_Text_Filter_Translation::t("Links")) + 1) . "\n";
         foreach ($this->_linkList as $key => $val) {
             $text .= '[' . ($key + 1) . '] ' . $val . "\n";
         }
     }
     return ltrim(rtrim($text), "\n");
 }
Пример #18
0
 /**
  * Create an AS message from this task
  *
  * @param array $options  Options:
  *   - protocolversion: (float)  The EAS version to support
  *                      DEFAULT: 2.5
  *   - bodyprefs: (array)  A BODYPREFERENCE array.
  *                DEFAULT: none (No body prefs enforced).
  *   - truncation: (integer)  Truncate event body to this length
  *                 DEFAULT: none (No truncation).
  *
  * @return Horde_ActiveSync_Message_Task
  */
 public function toASTask(array $options = array())
 {
     $message = new Horde_ActiveSync_Message_Task(array('protocolversion' => $options['protocolversion']));
     /* Notes and Title */
     if ($options['protocolversion'] >= Horde_ActiveSync::VERSION_TWELVE) {
         $bp = $options['bodyprefs'];
         $body = new Horde_ActiveSync_Message_AirSyncBaseBody();
         $body->type = Horde_ActiveSync::BODYPREF_TYPE_PLAIN;
         if (isset($bp[Horde_ActiveSync::BODYPREF_TYPE_PLAIN]['truncationsize'])) {
             $truncation = $bp[Horde_ActiveSync::BODYPREF_TYPE_PLAIN]['truncationsize'];
         } elseif (isset($bp[Horde_ActiveSync::BODYPREF_TYPE_HTML])) {
             $truncation = $bp[Horde_ActiveSync::BODYPREF_TYPE_HTML]['truncationsize'];
             $this->desc = Horde_Text_Filter::filter($this->desc, 'Text2html', array('parselevel' => Horde_Text_Filter_Text2html::MICRO));
         } else {
             $truncation = false;
         }
         if ($truncation && Horde_String::length($this->desc) > $truncation) {
             $body->data = Horde_String::substr($this->desc, 0, $truncation);
             $body->truncated = 1;
         } else {
             $body->data = $this->desc;
         }
         $body->estimateddatasize = Horde_String::length($this->desc);
         $message->airsyncbasebody = $body;
     } else {
         $message->body = $this->desc;
     }
     $message->subject = $this->name;
     /* Completion */
     if ($this->completed) {
         $message->datecompleted = new Horde_Date($this->completed_date);
         $message->complete = Horde_ActiveSync_Message_Task::TASK_COMPLETE_TRUE;
     } else {
         $message->complete = Horde_ActiveSync_Message_Task::TASK_COMPLETE_FALSE;
     }
     /* Due Date */
     if (!empty($this->due)) {
         $message->utcduedate = new Horde_Date($this->due);
         $message->duedate = new Horde_Date($this->due, 'UTC');
     }
     /* Start Date */
     if (!empty($this->start)) {
         $message->utcstartdate = new Horde_Date($this->start);
         $message->startdate = new Horde_Date($this->start, 'UTC');
     }
     /* Priority */
     switch ($this->priority) {
         case 5:
             $priority = Horde_ActiveSync_Message_Task::IMPORTANCE_LOW;
             break;
         case 4:
         case 3:
         case 2:
             $priority = Horde_ActiveSync_Message_Task::IMPORTANCE_NORMAL;
             break;
         case 1:
             $priority = Horde_ActiveSync_Message_Task::IMPORTANCE_HIGH;
             break;
         default:
             $priority = Horde_ActiveSync_Message_Task::IMPORTANCE_NORMAL;
     }
     $message->setImportance($priority);
     /* Reminders */
     if ($this->due && $this->alarm) {
         $message->setReminder(new Horde_Date($this->due - $this->alarm * 60));
     }
     /* Recurrence */
     if ($this->recurs()) {
         $message->setRecurrence($this->recurrence);
     }
     /* Categories */
     $message->categories = $this->tags;
     return $message;
 }
Пример #19
0
 /**
  * Returns human readable information on a PGP key.
  *
  * @param string $pgpdata  The PGP data block.
  *
  * @return string  Tabular information on the PGP key.
  * @throws Horde_Crypt_Exception
  */
 public function pgpPrettyKey($pgpdata)
 {
     $msg = '';
     $fingerprints = $this->getFingerprintsFromKey($pgpdata);
     $info = $this->pgpPacketInformation($pgpdata);
     if (empty($info['signature'])) {
         return $msg;
     }
     /* Making the property names the same width for all localizations .*/
     $leftrow = array(Horde_Crypt_Translation::t("Name"), Horde_Crypt_Translation::t("Key Type"), Horde_Crypt_Translation::t("Key Creation"), Horde_Crypt_Translation::t("Expiration Date"), Horde_Crypt_Translation::t("Key Length"), Horde_Crypt_Translation::t("Comment"), Horde_Crypt_Translation::t("E-Mail"), Horde_Crypt_Translation::t("Hash-Algorithm"), Horde_Crypt_Translation::t("Key ID"), Horde_Crypt_Translation::t("Key Fingerprint"));
     array_walk($leftrow, function (&$s, $k, $m) {
         $s .= ':' . str_repeat(' ', $m - Horde_String::length($s));
     }, max(array_map('strlen', $leftrow)) + 2);
     foreach ($info['signature'] as $uid_idx => $val) {
         if ($uid_idx == '_SIGNATURE') {
             continue;
         }
         $key = $this->pgpPacketSignatureByUidIndex($pgpdata, $uid_idx);
         $keyid = empty($key['keyid']) ? null : $this->getKeyIDString($key['keyid']);
         $fingerprint = isset($fingerprints[$keyid]) ? $fingerprints[$keyid] : null;
         $sig_key = 'sig_' . $key['keyid'];
         $msg .= $leftrow[0] . (isset($key['name']) ? stripcslashes($key['name']) : '') . "\n" . $leftrow[1] . ($key['key_type'] == 'public_key' ? Horde_Crypt_Translation::t("Public Key") : Horde_Crypt_Translation::t("Private Key")) . "\n" . $leftrow[2] . strftime("%D", $val[$sig_key]['created']) . "\n" . $leftrow[3] . (empty($val[$sig_key]['expires']) ? '[' . Horde_Crypt_Translation::t("Never") . ']' : strftime("%D", $val[$sig_key]['expires'])) . "\n" . $leftrow[4] . $key['key_size'] . " Bytes\n" . $leftrow[5] . (empty($key['comment']) ? '[' . Horde_Crypt_Translation::t("None") . ']' : $key['comment']) . "\n" . $leftrow[6] . (empty($key['email']) ? '[' . Horde_Crypt_Translation::t("None") . ']' : $key['email']) . "\n" . $leftrow[7] . (empty($key['micalg']) ? '[' . Horde_Crypt_Translation::t("Unknown") . ']' : $key['micalg']) . "\n" . $leftrow[8] . (empty($keyid) ? '[' . Horde_Crypt_Translation::t("Unknown") . ']' : $keyid) . "\n" . $leftrow[9] . (empty($fingerprint) ? '[' . Horde_Crypt_Translation::t("Unknown") . ']' : $fingerprint) . "\n\n";
     }
     return $msg;
 }
Пример #20
0
 /**
  * Determine the size of a MIME_Part and its child members.
  *
  * @return integer  Size of the MIME_Part, in bytes.
  */
 public function getBytes()
 {
     $bytes = 0;
     if (empty($this->_flags['contentsSet']) && $this->_bytes) {
         $bytes = $this->_bytes;
     } elseif ($this->getPrimaryType() == 'multipart') {
         reset($this->_parts);
         while (list(, $part) = each($this->_parts)) {
             /* Skip multipart entries (since this may result in double
                counting). */
             if ($part->getPrimaryType() != 'multipart') {
                 $bytes += $part->getBytes();
             }
         }
     } else {
         if ($this->getPrimaryType() == 'text') {
             $bytes = Horde_String::length($this->_contents, $this->getCharset());
         } else {
             $bytes = strlen($this->_contents);
         }
     }
     return $bytes;
 }
Пример #21
0
 /**
  * Executes any code necessaray after applying the filter patterns.
  *
  * @param string $text  The text after the filtering.
  *
  * @return string  The modified text.
  */
 public function postProcess($text)
 {
     /* Use cite blocks to display the different quoting levels? */
     $cb = $this->_params['citeblock'];
     /* Cite level before parsing the current line. */
     $qlevel = 0;
     /* Other loop variables. */
     $text_out = '';
     $lines = array();
     $tmp = array('level' => 0, 'lines' => array());
     $qcount = 0;
     /* Parse text line by line. */
     foreach (explode("\n", $text) as $line) {
         /* Cite level of current line. */
         $clevel = 0;
         $matches = array();
         /* Do we have a citation line? */
         if (preg_match('/^\\s*((&gt;\\s?)+)/m', $line, $matches)) {
             /* Count number of > characters => cite level */
             $clevel = count(preg_split('/&gt;\\s?/', $matches[1])) - 1;
         }
         if ($cb && isset($matches[1])) {
             /* Strip all > characters. */
             $line = substr($line, Horde_String::length($matches[1]));
         }
         /* Is this cite level lower than the current level? */
         if ($clevel < $qlevel) {
             $lines[] = $tmp;
             if ($clevel == 0) {
                 $text_out .= $this->_process($lines, $qcount);
                 $lines = array();
                 $qcount = 0;
             }
             $tmp = array('level' => $clevel, 'lines' => array());
             /* Is this cite level higher than the current level? */
         } elseif ($clevel > $qlevel) {
             $lines[] = $tmp;
             $tmp = array('level' => $clevel, 'lines' => array());
         }
         $tmp['lines'][] = $line;
         $qlevel = $clevel;
         if ($qlevel) {
             ++$qcount;
         }
     }
     $lines[] = $tmp;
     $text_out .= $this->_process($lines, $qcount);
     /* Remove the leading newline we added above, if it's still there. */
     return $text_out[0] == "\n" ? substr($text_out, 1) : $text_out;
 }
Пример #22
0
 public function getCostObjectType($vars)
 {
     global $registry;
     $clients = $vars->get('clients');
     if (count($clients) == 0) {
         $clients = array('');
     }
     $costobjects = array();
     foreach ($clients as $client) {
         $criteria = array('user' => $GLOBALS['registry']->getAuth(), 'active' => true, 'client_id' => $client);
         foreach ($registry->listApps() as $app) {
             if ($registry->hasMethod('listCostObjects', $app)) {
                 try {
                     $res = $registry->callByPackage($app, 'listCostObjects', array($criteria));
                 } catch (Horde_Exception $e) {
                     $GLOBALS['notification']->push(sprintf(_("Error retrieving cost objects from \"%s\": %s"), $registry->get('name', $app), $res->getMessage()), 'horde.error');
                     continue;
                 }
                 foreach (array_keys($res) as $catkey) {
                     foreach (array_keys($res[$catkey]['objects']) as $okey) {
                         $res[$catkey]['objects'][$okey]['id'] = $app . ':' . $res[$catkey]['objects'][$okey]['id'];
                     }
                 }
                 $costobjects = array_merge($costobjects, $res);
             }
         }
     }
     $elts = array();
     $counter = 0;
     foreach ($costobjects as $category) {
         Horde_Array::arraySort($category['objects'], 'name');
         foreach ($category['objects'] as $object) {
             $name = $object['name'];
             if (Horde_String::length($name) > 80) {
                 $name = Horde_String::substr($name, 0, 76) . ' ...';
             }
             $elts[$object['id']] = $name;
         }
     }
     return $elts;
 }
Пример #23
0
 /**
  * Generate the display path (the path with any root information stripped
  * out).
  *
  * @param string $path  The path to display.
  *
  * @return string  The display path.
  */
 public static function getDisplayPath($path)
 {
     $path = Horde_Util::realPath($path);
     if (self::$backend['root'] != '/' && strpos($path, self::$backend['root']) === 0) {
         $path = substr($path, Horde_String::length(self::$backend['root']));
     }
     return $path;
 }
Пример #24
0
 /**
  * List code points for a given input.
  *
  * @param string $input
  *
  * @return array  Multi-dimension array with basic, non-basic and
  *                aggregated code points.
  */
 protected function _codePoints($input)
 {
     $codePoints = array('all' => array(), 'basic' => array(), 'nonBasic' => array());
     $len = Horde_String::length($input, 'UTF-8');
     for ($i = 0; $i < $len; ++$i) {
         $char = Horde_String::substr($input, $i, 1, 'UTF-8');
         $code = $this->_charToCodePoint($char);
         if ($code < 128) {
             $codePoints['all'][] = $codePoints['basic'][] = $code;
         } else {
             $codePoints['all'][] = $codePoints['nonBasic'][] = $code;
         }
     }
     return $codePoints;
 }
Пример #25
0
 /**
  * Reformats the input string, where the string is 'format=flowed' plain
  * text as described in RFC 2646.
  *
  * @param boolean $toflowed  Convert to flowed?
  * @param boolean $quote     Add level of quoting to each line?
  * @param boolean $wrap      Wrap unquoted lines?
  */
 protected function _reformat($toflowed, $quote, $wrap = true)
 {
     $format_type = implode('|', array($toflowed, $quote));
     if ($format_type == $this->_formattype) {
         return;
     }
     $this->_output = array();
     $this->_formattype = $format_type;
     /* Set variables used in regexps. */
     $delsp = $toflowed && $this->_delsp ? 1 : 0;
     $opt = $this->_optlength - 1 - $delsp;
     /* Process message line by line. */
     $text = preg_split("/\r?\n/", $this->_text);
     $text_count = count($text) - 1;
     $skip = 0;
     reset($text);
     while (list($no, $line) = each($text)) {
         if ($skip) {
             --$skip;
             continue;
         }
         /* Per RFC 2646 [4.3], the 'Usenet Signature Convention' line
          * (DASH DASH SP) is not considered flowed.  Watch for this when
          * dealing with potentially flowed lines. */
         /* The next three steps come from RFC 2646 [4.2]. */
         /* STEP 1: Determine quote level for line. */
         if ($num_quotes = $this->_numquotes($line)) {
             $line = substr($line, $num_quotes);
         }
         /* Only combine lines if we are converting to flowed or if the
          * current line is quoted. */
         if (!$toflowed || $num_quotes) {
             /* STEP 2: Remove space stuffing from line. */
             $line = $this->_unstuff($line);
             /* STEP 3: Should we interpret this line as flowed?
              * While line is flowed (not empty and there is a space
              * at the end of the line), and there is a next line, and the
              * next line has the same quote depth, add to the current
              * line. A line is not flowed if it is a signature line. */
             if ($line != '-- ') {
                 while (!empty($line) && substr($line, -1) == ' ' && $text_count != $no && $this->_numquotes($text[$no + 1]) == $num_quotes) {
                     /* If DelSp is yes and this is flowed input, we need to
                      * remove the trailing space. */
                     if (!$toflowed && $this->_delsp) {
                         $line = substr($line, 0, -1);
                     }
                     $line .= $this->_unstuff(substr($text[++$no], $num_quotes));
                     ++$skip;
                 }
             }
         }
         /* Ensure line is fixed, since we already joined all flowed
          * lines. Remove all trailing ' ' from the line. */
         if ($line != '-- ') {
             $line = rtrim($line);
         }
         /* Increment quote depth if we're quoting. */
         if ($quote) {
             $num_quotes++;
         }
         /* The quote prefix for the line. */
         $quotestr = str_repeat('>', $num_quotes);
         if (empty($line)) {
             /* Line is empty. */
             $this->_output[] = array('text' => $quotestr, 'level' => $num_quotes);
         } elseif (!$wrap && !$num_quotes || empty($this->_maxlength) || Horde_String::length($line, $this->_charset) + $num_quotes <= $this->_maxlength) {
             /* Line does not require rewrapping. */
             $this->_output[] = array('text' => $quotestr . $this->_stuff($line, $num_quotes, $toflowed), 'level' => $num_quotes);
         } else {
             $min = $num_quotes + 1;
             /* Rewrap this paragraph. */
             while ($line) {
                 /* Stuff and re-quote the line. */
                 $line = $quotestr . $this->_stuff($line, $num_quotes, $toflowed);
                 $line_length = Horde_String::length($line, $this->_charset);
                 if ($line_length <= $this->_optlength) {
                     /* Remaining section of line is short enough. */
                     $this->_output[] = array('text' => $line, 'level' => $num_quotes);
                     break;
                 } else {
                     $regex = array();
                     if ($min <= $opt) {
                         $regex[] = '^(.{' . $min . ',' . $opt . '}) (.*)';
                     }
                     if ($min <= $this->_maxlength) {
                         $regex[] = '^(.{' . $min . ',' . $this->_maxlength . '}) (.*)';
                     }
                     $regex[] = '^(.{' . $min . ',})? (.*)';
                     if ($m = Horde_String::regexMatch($line, $regex, $this->_charset)) {
                         /* We need to wrap text at a certain number of
                          * *characters*, not a certain number of *bytes*;
                          * thus the need for a multibyte capable regex.
                          * If a multibyte regex isn't available, we are
                          * stuck with preg_match() (the function will
                          * still work - are just left with shorter rows
                          * than expected if multibyte characters exist in
                          * the row).
                          *
                          * 1. Try to find a string as long as _optlength.
                          * 2. Try to find a string as long as _maxlength.
                          * 3. Take the first word. */
                         if (empty($m[1])) {
                             $m[1] = $m[2];
                             $m[2] = '';
                         }
                         $this->_output[] = array('text' => $m[1] . ' ' . ($delsp ? ' ' : ''), 'level' => $num_quotes);
                         $line = $m[2];
                     } elseif ($line_length > 998) {
                         /* One excessively long word left on line.  Be
                          * absolutely sure it does not exceed 998
                          * characters in length or else we must
                          * truncate. */
                         $this->_output[] = array('text' => Horde_String::substr($line, 0, 998, $this->_charset), 'level' => $num_quotes);
                         $line = Horde_String::substr($line, 998, null, $this->_charset);
                     } else {
                         $this->_output[] = array('text' => $line, 'level' => $num_quotes);
                         break;
                     }
                 }
             }
         }
     }
 }
Пример #26
0
 /**
  * Convert the contact to an ActiveSync contact message
  *
  * @param Turba_Object $object  The turba object to convert
  * @param array $options        Options:
  *   - protocolversion: (float)  The EAS version to support
  *                      DEFAULT: 2.5
  *   - bodyprefs: (array)  A BODYPREFERENCE array.
  *                DEFAULT: none (No body prefs enforced).
  *   - truncation: (integer)  Truncate event body to this length
  *                 DEFAULT: none (No truncation).
  *   - device: (Horde_ActiveSync_Device) The device object.
  *
  * @return Horde_ActiveSync_Message_Contact
  */
 public function toASContact(Turba_Object $object, array $options = array())
 {
     global $injector;
     $message = new Horde_ActiveSync_Message_Contact(array('logger' => $injector->getInstance('Horde_Log_Logger'), 'protocolversion' => $options['protocolversion'], 'device' => !empty($options['device']) ? $options['device'] : null));
     $hash = $object->getAttributes();
     if (!isset($hash['lastname']) && isset($hash['name'])) {
         $this->_guessName($hash);
     }
     // Ensure we have at least a good guess as to separate address fields.
     // Not ideal, but EAS does not have a single "address" field so we must
     // map "common" to either home or work. I choose home since
     // work/non-personal installs will be more likely to have separated
     // address fields.
     if (!empty($hash['commonAddress'])) {
         if (!isset($hash['commonStreet'])) {
             $hash['commonStreet'] = $hash['commonHome'];
         }
         foreach (array('Address', 'Street', 'POBox', 'Extended', 'City', 'Province', 'PostalCode', 'Country') as $field) {
             $hash['home' . $field] = $hash['common' . $field];
         }
     } else {
         if (isset($hash['homeAddress']) && !isset($hash['homeStreet'])) {
             $hash['homeStreet'] = $hash['homeAddress'];
         }
         if (isset($hash['workAddress']) && !isset($hash['workStreet'])) {
             $hash['workStreet'] = $hash['workAddress'];
         }
     }
     $hooks = $injector->getInstance('Horde_Core_Hooks');
     $decode_hook = $hooks->hookExists('decode_attribute', 'turba');
     foreach ($hash as $field => $value) {
         if ($decode_hook) {
             try {
                 $value = $hooks->callHook('decode_attribute', 'turba', array($field, $value, $object));
             } catch (Turba_Exception $e) {
                 Horde::log($e);
             }
         }
         if (isset(self::$_asMap[$field])) {
             try {
                 $message->{self::$_asMap[$field]} = $value;
             } catch (InvalidArgumentException $e) {
             }
             continue;
         }
         switch ($field) {
             case 'photo':
                 $message->picture = base64_encode($value);
                 break;
             case 'homeCountry':
                 $message->homecountry = !empty($hash['homeCountryFree']) ? $hash['homeCountryFree'] : !empty($hash['homeCountry']) ? Horde_Nls::getCountryISO($hash['homeCountry']) : null;
                 break;
             case 'otherCountry':
                 $message->othercountry = !empty($hash['otherCountryFree']) ? $hash['otherCountryFree'] : !empty($hash['otherCountry']) ? Horde_Nls::getCountryISO($hash['otherCountry']) : null;
                 break;
             case 'workCountry':
                 $message->businesscountry = !empty($hash['workCountryFree']) ? $hash['workCountryFree'] : !empty($hash['workCountry']) ? Horde_Nls::getCountryISO($hash['workCountry']) : null;
                 break;
             case 'email':
                 $message->email1address = $value;
                 break;
             case 'homeEmail':
                 $message->email2address = $value;
                 break;
             case 'workEmail':
                 $message->email3address = $value;
                 break;
             case 'emails':
                 $address = 1;
                 foreach (explode(',', $value) as $email) {
                     while ($address <= 3 && $message->{'email' . $address . 'address'}) {
                         $address++;
                     }
                     if ($address > 3) {
                         break;
                     }
                     $message->{'email' . $address . 'address'} = $email;
                     $address++;
                 }
                 break;
             case 'children':
                 // Children FROM horde are a simple string value. Even though EAS
                 // uses an array stucture to pass them, we pass as a single
                 // string since we can't assure what delimter the user will
                 // use and (at least in some languages) a comma can be used
                 // within a full name.
                 $message->children = array($value);
                 break;
             case 'notes':
                 if ($options['protocolversion'] > Horde_ActiveSync::VERSION_TWOFIVE) {
                     $bp = $options['bodyprefs'];
                     $note = new Horde_ActiveSync_Message_AirSyncBaseBody();
                     // No HTML supported in Turba's notes. Always use plaintext.
                     $note->type = Horde_ActiveSync::BODYPREF_TYPE_PLAIN;
                     if (isset($bp[Horde_ActiveSync::BODYPREF_TYPE_PLAIN]['truncationsize'])) {
                         if (Horde_String::length($value) > $bp[Horde_ActiveSync::BODYPREF_TYPE_PLAIN]['truncationsize']) {
                             $note->data = Horde_String::substr($value, 0, $bp[Horde_ActiveSync::BODYPREF_TYPE_PLAIN]['truncationsize']);
                             $note->truncated = 1;
                         } else {
                             $note->data = $value;
                         }
                         $note->estimateddatasize = Horde_String::length($value);
                     }
                     $message->airsyncbasebody = $note;
                 } else {
                     // EAS 2.5
                     $message->body = $value;
                     $message->bodysize = strlen($message->body);
                     $message->bodytruncated = 0;
                 }
                 break;
             case 'birthday':
             case 'anniversary':
                 if (!empty($value) && $value != '0000-00-00') {
                     try {
                         $date = new Horde_Date($value);
                     } catch (Horde_Date_Exception $e) {
                         $message->{$field} = null;
                     }
                     // Some sanity checking to make sure the date was
                     // successfully parsed.
                     if ($date->month != 0) {
                         $message->{$field} = $date;
                     } else {
                         $message->{$field} = null;
                     }
                 } else {
                     $message->{$field} = null;
                 }
                 break;
         }
     }
     /* Get tags. */
     $message->categories = explode(',', $object->getValue('__tags'));
     if (empty($this->fileas)) {
         $message->fileas = Turba::formatName($object);
     }
     return $message;
 }
Пример #27
0
 /**
  * Export this event as a MS ActiveSync Message
  *
  * @param array $options  Options:
  *   - protocolversion: (float)  The EAS version to support
  *                      DEFAULT: 2.5
  *   - bodyprefs: (array)  A BODYPREFERENCE array.
  *                DEFAULT: none (No body prefs enforced).
  *   - truncation: (integer)  Truncate event body to this length
  *                 DEFAULT: none (No truncation).
  *
  * @return Horde_ActiveSync_Message_Appointment
  */
 public function toASAppointment(array $options = array())
 {
     global $prefs, $registry;
     $message = new Horde_ActiveSync_Message_Appointment(array('logger' => $GLOBALS['injector']->getInstance('Horde_Log_Logger'), 'protocolversion' => $options['protocolversion']));
     if (!$this->isPrivate()) {
         // Handle body/truncation
         if (!empty($options['bodyprefs'])) {
             if (Horde_String::length($this->description) > 0) {
                 $bp = $options['bodyprefs'];
                 $note = new Horde_ActiveSync_Message_AirSyncBaseBody();
                 // No HTML supported. Always use plaintext.
                 $note->type = Horde_ActiveSync::BODYPREF_TYPE_PLAIN;
                 if (isset($bp[Horde_ActiveSync::BODYPREF_TYPE_PLAIN]['truncationsize'])) {
                     $truncation = $bp[Horde_ActiveSync::BODYPREF_TYPE_PLAIN]['truncationsize'];
                 } elseif (isset($bp[Horde_ActiveSync::BODYPREF_TYPE_HTML])) {
                     $truncation = $bp[Horde_ActiveSync::BODYPREF_TYPE_HTML]['truncationsize'];
                     $this->description = Horde_Text_Filter::filter($this->description, 'Text2html', array('parselevel' => Horde_Text_Filter_Text2html::MICRO));
                 } else {
                     $truncation = false;
                 }
                 if ($truncation && Horde_String::length($this->description) > $truncation) {
                     $note->data = Horde_String::substr($this->desciption, 0, $truncation);
                     $note->truncated = 1;
                 } else {
                     $note->data = $this->description;
                 }
                 $note->estimateddatasize = Horde_String::length($this->description);
                 $message->airsyncbasebody = $note;
             }
         } else {
             $message->setBody($this->description);
         }
         $message->setLocation($this->location);
     }
     $message->setSubject($this->getTitle());
     $message->setDatetime(array('start' => $this->start, 'end' => $this->end, 'allday' => $this->isAllDay()));
     $message->setTimezone($this->start);
     // Organizer
     if (count($this->attendees)) {
         if ($this->creator == $registry->getAuth()) {
             $as_ident = $prefs->getValue('activesync_identity') == 'horde' ? $prefs->getValue('default_identity') : $prefs->getValue('activesync_identity');
             $name = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Identity')->create($this->creator)->getValue('fullname', $as_ident);
             $email = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Identity')->create($this->creator)->getValue('from_addr', $as_ident);
         } else {
             $name = Kronolith::getUserName($this->creator);
             $email = Kronolith::getUserEmail($this->creator);
         }
         $message->setOrganizer(array('name' => $name, 'email' => $email));
     }
     // Privacy
     $message->setSensitivity($this->private ? Horde_ActiveSync_Message_Appointment::SENSITIVITY_PRIVATE : Horde_ActiveSync_Message_Appointment::SENSITIVITY_NORMAL);
     // Busy Status
     switch ($this->status) {
         case Kronolith::STATUS_CANCELLED:
             $status = Horde_ActiveSync_Message_Appointment::BUSYSTATUS_FREE;
             break;
         case Kronolith::STATUS_CONFIRMED:
             $status = Horde_ActiveSync_Message_Appointment::BUSYSTATUS_BUSY;
             break;
         case Kronolith::STATUS_TENTATIVE:
             $status = Horde_ActiveSync_Message_Appointment::BUSYSTATUS_TENTATIVE;
         case Kronolith::STATUS_FREE:
         case Kronolith::STATUS_NONE:
             $status = Horde_ActiveSync_Message_Appointment::BUSYSTATUS_FREE;
     }
     $message->setBusyStatus($status);
     // DTStamp
     $message->setDTStamp($_SERVER['REQUEST_TIME']);
     // Recurrence
     if ($this->recurs()) {
         $message->setRecurrence($this->recurrence, $GLOBALS['prefs']->getValue('week_start_monday'));
         /* Exceptions are tricky. Exceptions, even those that represent
          * deleted instances of a recurring event, must be added. To do this
          * we query the storage for all the events that represent exceptions
          * (those with the baseid == $this->uid) and then remove the
          * exceptionoriginaldate from the list of exceptions we know about.
          * Any dates left in this list when we are done, must represent
          * deleted instances of this recurring event.*/
         if (!empty($this->recurrence) && ($exceptions = $this->recurrence->getExceptions())) {
             $results = $this->boundExceptions();
             foreach ($results as $exception) {
                 $e = new Horde_ActiveSync_Message_Exception(array('protocolversion' => $options['protocolversion']));
                 $e->setDateTime(array('start' => $exception->start, 'end' => $exception->end, 'allday' => $exception->isAllDay()));
                 // The start time of the *original* recurring event
                 $e->setExceptionStartTime($exception->exceptionoriginaldate);
                 $originaldate = $exception->exceptionoriginaldate->format('Ymd');
                 $key = array_search($originaldate, $exceptions);
                 if ($key !== false) {
                     unset($exceptions[$key]);
                 }
                 // Remaining properties that could be different
                 $e->setSubject($exception->getTitle());
                 if (!$exception->isPrivate()) {
                     $e->setLocation($exception->location);
                     $e->setBody($exception->description);
                 }
                 $e->setSensitivity($exception->private ? Horde_ActiveSync_Message_Appointment::SENSITIVITY_PRIVATE : Horde_ActiveSync_Message_Appointment::SENSITIVITY_NORMAL);
                 $e->setReminder($exception->alarm);
                 $e->setDTStamp($_SERVER['REQUEST_TIME']);
                 if ($options['protocolversion'] > Horde_ActiveSync::VERSION_TWELVEONE) {
                     switch ($exception->status) {
                         case Kronolith::STATUS_TENTATIVE:
                             $e->responsetype = Horde_ActiveSync_Message_Appointment::RESPONSE_TENTATIVE;
                             break;
                         case Kronolith::STATUS_NONE:
                             $e->responsetype = Horde_ActiveSync_Message_Appointment::RESPONSE_NORESPONSE;
                             break;
                         case Kronolith::STATUS_CONFIRMED:
                             $e->responsetype = Horde_ActiveSync_Message_Appointment::RESPONSE_ACCEPTED;
                             break;
                         default:
                             $e->responsetype = Horde_ActiveSync_Message_Appointment::RESPONSE_NONE;
                     }
                 }
                 // Tags/Categories
                 if (!$exception->isPrivate()) {
                     foreach ($exception->tags as $tag) {
                         $e->addCategory($tag);
                     }
                 }
                 $message->addexception($e);
             }
             // Any dates left in $exceptions must be deleted exceptions
             foreach ($exceptions as $deleted) {
                 $e = new Horde_ActiveSync_Message_Exception(array('protocolversion' => $options['protocolversion']));
                 // Kronolith stores the date only, but some AS clients need
                 // the datetime.
                 list($year, $month, $mday) = sscanf($deleted, '%04d%02d%02d');
                 $st = clone $this->start;
                 $st->year = $year;
                 $st->month = $month;
                 $st->mday = $mday;
                 $e->setExceptionStartTime($st);
                 $e->deleted = true;
                 $message->addException($e);
             }
         }
     }
     // Attendees
     if (!$this->isPrivate() && count($this->attendees)) {
         $message->setMeetingStatus(Horde_ActiveSync_Message_Appointment::MEETING_IS_MEETING);
         foreach ($this->attendees as $email => $properties) {
             $attendee = new Horde_ActiveSync_Message_Attendee(array('protocolversion' => $options['protocolversion']));
             $adr_obj = new Horde_Mail_Rfc822_Address($email);
             $attendee->name = $adr_obj->label;
             $attendee->email = $adr_obj->bare_address;
             // AS only has required or optional, and only EAS Version > 2.5
             if ($options['protocolversion'] > Horde_ActiveSync::VERSION_TWOFIVE) {
                 $attendee->type = $properties['attendance'] !== Kronolith::PART_REQUIRED ? Horde_ActiveSync_Message_Attendee::TYPE_OPTIONAL : Horde_ActiveSync_Message_Attendee::TYPE_REQUIRED;
                 switch ($properties['response']) {
                     case Kronolith::RESPONSE_NONE:
                         $attendee->status = Horde_ActiveSync_Message_Attendee::STATUS_NORESPONSE;
                         break;
                     case Kronolith::RESPONSE_ACCEPTED:
                         $attendee->status = Horde_ActiveSync_Message_Attendee::STATUS_ACCEPT;
                         break;
                     case Kronolith::RESPONSE_DECLINED:
                         $attendee->status = Horde_ActiveSync_Message_Attendee::STATUS_DECLINE;
                         break;
                     case Kronolith::RESPONSE_TENTATIVE:
                         $attendee->status = Horde_ActiveSync_Message_Attendee::STATUS_TENTATIVE;
                         break;
                     default:
                         $attendee->status = Horde_ActiveSync_Message_Attendee::STATUS_UNKNOWN;
                 }
             }
             $message->addAttendee($attendee);
         }
     } else {
         $message->setMeetingStatus(Horde_ActiveSync_Message_Appointment::MEETING_NOT_MEETING);
     }
     // Resources
     if ($options['protocolversion'] > Horde_ActiveSync::VERSION_TWOFIVE) {
         $r = $this->getResources();
         foreach ($r as $id => $data) {
             $resource = Kronolith::getDriver('Resource')->getResource($id);
             // EAS *REQUIRES* an email field for Resources. If it is missing
             // a number of clients will fail, losing push.
             if ($resource->get('email')) {
                 $attendee = new Horde_ActiveSync_Message_Attendee(array('protocolversion' => $options['protocolversion']));
                 $attendee->email = $resource->get('email');
                 $attendee->type = Horde_ActiveSync_Message_Attendee::TYPE_RESOURCE;
                 $attendee->name = $data['name'];
                 $attendee->status = $data['response'];
                 $message->addAttendee($attendee);
             }
         }
     }
     // Reminder
     if ($this->alarm) {
         $message->setReminder($this->alarm);
     }
     // Categories (tags)
     if (!$this->isPrivate()) {
         foreach ($this->tags as $tag) {
             $message->addCategory($tag);
         }
     }
     // EAS 14
     if ($options['protocolversion'] > Horde_ActiveSync::VERSION_TWELVEONE) {
         // We don't track the actual responses we sent to other's invitations.
         // Set this based on the status flag.
         switch ($this->status) {
             case Kronolith::STATUS_TENTATIVE:
                 $message->responsetype = Horde_ActiveSync_Message_Appointment::RESPONSE_TENTATIVE;
                 break;
             case Kronolith::STATUS_NONE:
                 $message->responsetype = Horde_ActiveSync_Message_Appointment::RESPONSE_NORESPONSE;
                 break;
             case Kronolith::STATUS_CONFIRMED:
                 $message->responsetype = Horde_ActiveSync_Message_Appointment::RESPONSE_ACCEPTED;
                 break;
             default:
                 $message->responsetype = Horde_ActiveSync_Message_Appointment::RESPONSE_NONE;
         }
     }
     // 14.1
     if ($options['protocolversion'] >= Horde_ActiveSync::VERSION_FOURTEENONE) {
         $message->onlinemeetingexternallink = $this->url;
     }
     return $message;
 }
Пример #28
0
 /**
  * Returns a plain text representation of a ticket.
  */
 public function toString()
 {
     $fields = array('queue' => _("Queue"), 'version' => _("Version"), 'type' => _("Type"), 'state' => _("State"), 'priority' => _("Priority"), 'due' => _("Due"));
     /* Find longest translated field name. */
     $length = 0;
     foreach (array_merge($fields, array(_("Summary"), _("Owners"))) as $field) {
         $length = max($length, Horde_String::length($field));
     }
     $wrap_break = "\n" . str_repeat(' ', $length + 2) . '| ';
     $wrap_width = 73 - $length;
     /* Ticket properties. */
     $message = ' ' . Horde_String::pad(_("Ticket"), $length) . ' | ' . $this->_id . "\n" . ' ' . Horde_String::pad(_("Summary"), $length) . ' | ' . Horde_String::wrap($this->get('summary'), $wrap_width, $wrap_break) . "\n";
     foreach ($fields as $field => $label) {
         if ($name = $this->get($field . '_name')) {
             $message .= ' ' . Horde_String::pad($label, $length) . ' | ' . Horde_String::wrap($name, $wrap_width, $wrap_break) . "\n";
         }
     }
     $message .= ' ' . Horde_String::pad(_("Owners"), $length) . ' | ' . Horde_String::wrap(Whups::getOwners($this->_id, false, true), $wrap_width, $wrap_break) . "\n";
     return $message;
 }
Пример #29
0
 function isValid(&$var, &$vars, $value, &$message)
 {
     $valid = true;
     $length = Horde_String::length(trim($value));
     if ($var->isRequired() && $length <= 0) {
         $valid = false;
         $message = Horde_Form_Translation::t("This field is required.");
     } elseif ($length > $this->_chars) {
         $valid = false;
         $message = sprintf(Horde_Form_Translation::ngettext("There are too many characters in this field. You have entered %d character; ", "There are too many characters in this field. You have entered %d characters; ", $length), $length) . sprintf(Horde_Form_Translation::t("you must enter less than %d."), $this->_chars);
     }
     return $valid;
 }
Пример #30
0
 /**
  * Generates a replacement for the matched text.
  *
  * Token options are:
  *
  * 'type' =>
  *     'table_start' : the start of a bullet list
  *     'table_end'   : the end of a bullet list
  *     'row_start' : the start of a number list
  *     'row_end'   : the end of a number list
  *     'cell_start'   : the start of item text (bullet or number)
  *     'cell_end'     : the end of item text (bullet or number)
  *
  * 'cols' => the number of columns in the table (for 'table_start')
  *
  * 'rows' => the number of rows in the table (for 'table_start')
  *
  * 'span' => column span (for 'cell_start')
  *
  * 'attr' => column attribute flag (for 'cell_start')
  *
  * @param array $matches  The array of matches from parse().
  *
  * @return string  A series of text and delimited tokens marking the
  *                 different table elements and cell text.
  *
  */
 public function process($matches)
 {
     // Build the structure first and hope that the table isn't too large.
     $table = array();
     // the  width of columns in the table
     $widths = array();
     // rows are separated by newlines in the matched text
     $rows = explode("\n", $matches[1]);
     // loop through each row
     foreach ($rows as $row) {
         $table_row = array();
         // cells are separated by double-pipes
         $cells = explode('||', $row);
         // get the number of cells (columns) in this row
         $last = count($cells) - 1;
         // by default, cells span only one column (their own)
         $span = 1;
         // ignore cell zero, and ignore the "last" cell; cell zero
         // is before the first double-pipe, and the "last" cell is
         // after the last double-pipe. both are always empty.
         for ($i = 1; $i < $last; $i++) {
             // if there is no content at all, then it's an instance
             // of two sets of || next to each other, indicating a
             // span.
             if ($cells[$i] == '') {
                 // add to the span and loop to the next cell
                 $span += 1;
                 continue;
             }
             // this cell has content.
             $table_cell = array('attr' => null, 'span' => $span);
             // find any special "attr"ibute cell markers
             switch (substr($cells[$i], 0, 2)) {
                 case '> ':
                     // right-align
                     $table_cell['attr'] = 'right';
                     $content = substr($cells[$i], 2);
                     break;
                 case '= ':
                     // center-align
                     $table_cell['attr'] = 'center';
                     $content = substr($cells[$i], 2);
                     break;
                 case '< ':
                     // left-align
                     $table_cell['attr'] = 'left';
                     $content = substr($cells[$i], 2);
                     break;
                 case '~ ':
                     $table_cell['attr'] = 'header';
                     $content = substr($cells[$i], 2);
                     break;
                 default:
                     $content = $cells[$i];
             }
             $table_cell['content'] = trim($content);
             $table_cell['length'] = Horde_String::length($table_cell['content']);
             $table_row[] = $table_cell;
             // Record the column widths.
             if (isset($widths[$i])) {
                 $length = $table_cell['length'];
                 for ($j = $table_cell['span']; $j > 1; $j--) {
                     if (isset($widths[$i - $j + 1])) {
                         $length -= $widths[$i - $j + 1];
                     }
                 }
                 $widths[$i] = max($widths[$i], $length);
             } else {
                 $widths[$i] = ceil($table_cell['length'] / $table_cell['span']);
             }
             // reset the span.
             $span = 1;
         }
         $table[] = $table_row;
     }
     // our eventual return value
     $return = $this->wiki->addToken($this->rule, array('type' => 'table_start', 'widths' => array_values($widths)));
     // loop through each row
     foreach ($table as $row) {
         // start a new row
         $return .= $this->wiki->addToken($this->rule, array('type' => 'row_start'));
         foreach ($row as $cell) {
             // start a new cell...
             $return .= $this->wiki->addToken($this->rule, array('type' => 'cell_start', 'attr' => $cell['attr'], 'span' => $cell['span'], 'length' => $cell['length']));
             // ...add the content...
             $return .= $cell['content'];
             // ...and end the cell.
             $return .= $this->wiki->addToken($this->rule, array('type' => 'cell_end', 'attr' => $cell['attr'], 'span' => $cell['span'], 'length' => $cell['length']));
         }
         // end the row
         $return .= $this->wiki->addToken($this->rule, array('type' => 'row_end'));
     }
     // End the table.
     $return .= $this->wiki->addToken($this->rule, array('type' => 'table_end'));
     // we're done!
     return "\n{$return}\n\n";
 }