Example #1
0
 /**
  * Initial startup function
  * to register session, create database and imap connections
  *
  * @todo Remove global vars $DB, $USER
  */
 private function startup()
 {
     $config_all = $this->config->all();
     // initialize syslog
     if ($this->config->get('log_driver') == 'syslog') {
         $syslog_id = $this->config->get('syslog_id', 'roundcube');
         $syslog_facility = $this->config->get('syslog_facility', LOG_USER);
         openlog($syslog_id, LOG_ODELAY, $syslog_facility);
     }
     // set task and action properties
     $this->set_task(strip_quotes(get_input_value('_task', RCUBE_INPUT_GPC)));
     $this->action = asciiwords(get_input_value('_action', RCUBE_INPUT_GPC));
     // connect to database
     $GLOBALS['DB'] = $this->get_dbh();
     // use database for storing session data
     include_once 'include/session.inc';
     // set session domain
     if (!empty($config_all['session_domain'])) {
         ini_set('session.cookie_domain', $config_all['session_domain']);
     }
     // set session garbage collecting time according to session_lifetime
     if (!empty($config_all['session_lifetime'])) {
         ini_set('session.gc_maxlifetime', $config_all['session_lifetime'] * 120);
     }
     // start PHP session (if not in CLI mode)
     if ($_SERVER['REMOTE_ADDR']) {
         session_start();
     }
     // set initial session vars
     if (!isset($_SESSION['auth_time'])) {
         $_SESSION['auth_time'] = time();
         $_SESSION['temp'] = true;
     }
     // create user object
     $this->set_user(new rcube_user($_SESSION['user_id']));
     // reset some session parameters when changing task
     if ($_SESSION['task'] != $this->task) {
         unset($_SESSION['page']);
     }
     // set current task to session
     $_SESSION['task'] = $this->task;
     // create IMAP object
     if ($this->task == 'mail') {
         $this->imap_init();
     }
 }
Example #2
0
 /**
  * Register this plugin to be responsible for a specific task
  *
  * @param string $task Task name (only characters [a-z0-9_-] are allowed)
  * @param string $owner Plugin name that registers this action
  */
 public function register_task($task, $owner)
 {
     // tasks are irrelevant in framework mode
     if (!class_exists('rcmail', false)) {
         return true;
     }
     if ($task != asciiwords($task, true)) {
         rcube::raise_error(array('code' => 526, 'type' => 'php', 'file' => __FILE__, 'line' => __LINE__, 'message' => "Invalid task name: {$task}." . " Only characters [a-z0-9_.-] are allowed"), true, false);
     } else {
         if (in_array($task, rcmail::$main_tasks)) {
             rcube::raise_error(array('code' => 526, 'type' => 'php', 'file' => __FILE__, 'line' => __LINE__, 'message' => "Cannot register taks {$task};" . " already taken by another plugin or the application itself"), true, false);
         } else {
             $this->tasks[$task] = $owner;
             rcmail::$main_tasks[] = $task;
             return true;
         }
     }
     return false;
 }
Example #3
0
 /**
  * Setter for application task
  *
  * @param string Task to set
  */
 public function set_task($task)
 {
     $task = asciiwords($task, true);
     if ($this->user && $this->user->ID) {
         $task = !$task ? 'mail' : $task;
     } else {
         if (php_sapi_name() == 'cli') {
             $task = 'cli';
         } else {
             $task = 'login';
         }
     }
     $this->task = $task;
     $this->comm_path = $this->url(array('task' => $this->task));
     if (!empty($_REQUEST['_framed'])) {
         $this->comm_path .= '&_framed=1';
     }
     if ($this->output) {
         $this->output->set_env('task', $this->task);
         $this->output->set_env('comm_path', $this->comm_path);
     }
 }
Example #4
0
 /**
  * Validate the given input and save to local properties
  * @access private
  */
 private function _set_sort_order($sort_field, $sort_order)
 {
     if ($sort_field != null) {
         $this->sort_field = asciiwords($sort_field);
     }
     if ($sort_order != null) {
         $this->sort_order = strtoupper($sort_order) == 'DESC' ? 'DESC' : 'ASC';
     }
 }
Example #5
0
 /**
  * Handler for the 'message_compose' plugin hook. This will check for
  * a compose parameter 'calendar_event' and create an attachment with the
  * referenced event in iCal format
  */
 public function mail_message_compose($args)
 {
     // set the submitted event ID as attachment
     if (!empty($args['param']['calendar_event'])) {
         $this->load_driver();
         list($cal, $id) = explode(':', $args['param']['calendar_event'], 2);
         if ($event = $this->driver->get_event(array('id' => $id, 'calendar' => $cal))) {
             $filename = asciiwords($event['title']);
             if (empty($filename)) {
                 $filename = 'event';
             }
             // save ics to a temp file and register as attachment
             $tmp_path = tempnam($this->rc->config->get('temp_dir'), 'rcmAttmntCal');
             file_put_contents($tmp_path, $this->get_ical()->export(array($event), '', false, array($this->driver, 'get_attachment_body')));
             $args['attachments'][] = array('path' => $tmp_path, 'name' => $filename . '.ics', 'mimetype' => 'text/calendar');
             $args['param']['subject'] = $event['title'];
         }
     }
     return $args;
 }
Example #6
0
 /**
  * Setter for application task
  *
  * @param string Task to set
  */
 public function set_task($task)
 {
     $task = asciiwords($task);
     if ($this->user && $this->user->ID) {
         $task = !$task ? 'mail' : $task;
     } else {
         $task = 'login';
     }
     $this->task = $task;
     $this->comm_path = $this->url(array('task' => $this->task));
     if ($this->output) {
         $this->output->set_env('task', $this->task);
     }
 }
 /**
  * Helper method to build a calendar list item (HTML content and js data)
  */
 public function calendar_list_item($id, $prop, &$jsenv, $activeonly = false)
 {
     // enrich calendar properties with settings from the driver
     if (!$prop['virtual']) {
         unset($prop['user_id']);
         $prop['alarms'] = $this->cal->driver->alarms;
         $prop['attendees'] = $this->cal->driver->attendees;
         $prop['freebusy'] = $this->cal->driver->freebusy;
         $prop['attachments'] = $this->cal->driver->attachments;
         $prop['undelete'] = $this->cal->driver->undelete;
         $prop['feedurl'] = $this->cal->get_url(array('_cal' => $this->cal->ical_feed_hash($id) . '.ics', 'action' => 'feed'));
         $jsenv[$id] = $prop;
     }
     $classes = array('calendar', 'cal-' . asciiwords($id, true));
     $title = $prop['title'] ?: ($prop['name'] != $prop['listname'] || strlen($prop['name']) > 25 ? html_entity_decode($prop['name'], ENT_COMPAT, RCMAIL_CHARSET) : '');
     if ($prop['virtual']) {
         $classes[] = 'virtual';
     } else {
         if ($prop['readonly']) {
             $classes[] = 'readonly';
         }
     }
     if ($prop['subscribed']) {
         $classes[] = 'subscribed';
     }
     if ($prop['subscribed'] === 2) {
         $classes[] = 'partial';
     }
     if ($prop['class']) {
         $classes[] = $prop['class'];
     }
     $content = '';
     if (!$activeonly || $prop['active']) {
         $label_id = 'cl:' . $id;
         $content = html::div(join(' ', $classes), html::span(array('class' => 'calname', 'id' => $label_id, 'title' => $title), $prop['editname'] ? Q($prop['editname']) : $prop['listname']) . ($prop['virtual'] ? '' : html::tag('input', array('type' => 'checkbox', 'name' => '_cal[]', 'value' => $id, 'checked' => $prop['active'], 'aria-labelledby' => $label_id), '') . html::span('actions', ($prop['removable'] ? html::a(array('href' => '#', 'class' => 'remove', 'title' => $this->cal->gettext('removelist')), ' ') : '') . html::a(array('href' => '#', 'class' => 'quickview', 'title' => $this->cal->gettext('quickview'), 'role' => 'checkbox', 'aria-checked' => 'false'), '') . (isset($prop['subscribed']) ? html::a(array('href' => '#', 'class' => 'subscribed', 'title' => $this->cal->gettext('calendarsubscribe'), 'role' => 'checkbox', 'aria-checked' => $prop['subscribed'] ? 'true' : 'false'), ' ') : '')) . html::span(array('class' => 'handle', 'style' => "background-color: #" . ($prop['color'] ?: 'f00')), ' ')));
     }
     return $content;
 }
Example #8
0
*/
// suppress php notices
@ini_set('error_reporting', E_ALL & ~E_NOTICE);
// include the converter class file
require_once 'vcard_convert.php';
require_once 'utils.php';
if (!empty($_FILES['_vcards'])) {
    // instantiate a parser object
    $conv = new vcard_convert(array('mailonly' => !empty($_POST['_mailonly']), 'phoneonly' => !empty($_POST['_phoneonly']), 'accesscode' => preg_replace('/[^1-9]/', '', $_POST['_accesscode'])));
    // check for errors
    if ($err = $_FILES['_vcards']['error']) {
        $GLOBALS['error_msg'] = $err == UPLOAD_ERR_INI_SIZE || $err == UPLOAD_ERR_FORM_SIZE ? "The uploaded file was too big! Maximum file size allowed: " . show_bytes(parse_bytes(ini_get('upload_max_filesize'))) : "Upload failed, please try again";
    } else {
        if ($conv->fromFile($_FILES['_vcards']['tmp_name'])) {
            $ext = $_POST['_format'] == 'gmail' ? 'csv' : ($_POST['_format'] == 'img' ? 'zip' : $_POST['_format']);
            $fname = asciiwords(preg_replace('/\\.[a-z]+$/i', '', $_FILES['_vcards']['name']));
            header(sprintf('Content-Type: text/%s', $ext));
            header(sprintf('Content-Disposition: attachment; filename="%s.%s"', $fname, $ext));
            if ($_POST['_format'] == 'ldif') {
                print $conv->toLdif();
                exit;
            } else {
                if ($_POST['_format'] == 'ldap') {
                    // Clean the input dn modifier from dangerous chars
                    $dnID = substr(preg_replace('/[^\\da-z=,_ -]/i', '', $_POST['_dn']), 0, 255);
                    print $conv->toLdif($dnID ? $dnID : "", null, $_POST['_encoding']);
                    exit;
                } else {
                    if ($_POST['_format'] == 'gmail') {
                        print $conv->toGmail();
                        exit;
 /**
  *
  */
 function tasklists($attrib = array())
 {
     $lists = $this->plugin->driver->get_lists();
     $li = '';
     foreach ((array) $lists as $id => $prop) {
         if ($attrib['activeonly'] && !$prop['active']) {
             continue;
         }
         unset($prop['user_id']);
         $prop['alarms'] = $this->plugin->driver->alarms;
         $prop['undelete'] = $this->plugin->driver->undelete;
         $prop['sortable'] = $this->plugin->driver->sortable;
         $prop['attachments'] = $this->plugin->driver->attachments;
         $jsenv[$id] = $prop;
         $html_id = html_identifier($id);
         $class = 'tasks-' . asciiwords($id, true);
         if (!$prop['editable']) {
             $class .= ' readonly';
         }
         if ($prop['class_name']) {
             $class .= ' ' . $prop['class_name'];
         }
         $li .= html::tag('li', array('id' => 'rcmlitasklist' . $html_id, 'class' => $class), html::tag('input', array('type' => 'checkbox', 'name' => '_list[]', 'value' => $id, 'checked' => $prop['active'])) . html::span('handle', ' ') . html::span('listname', $prop['name']));
     }
     $this->rc->output->set_env('tasklists', $jsenv);
     $this->rc->output->add_gui_object('folderlist', $attrib['id']);
     return html::tag('ul', $attrib, $li, html::$common_attrib);
 }
Example #10
0
 /**
  *
  */
 function calendar_list($attrib = array())
 {
     $li = '';
     foreach ($this->cal->get_calendars() as $id => $prop) {
         $driver = $this->cal->get_driver_by_cal($id);
         if ($attrib['activeonly'] && !$prop['active']) {
             continue;
         }
         unset($prop['user_id']);
         $prop['alarms'] = $driver->alarms;
         $prop['attendees'] = $driver->attendees;
         $prop['freebusy'] = $driver->freebusy;
         $prop['attachments'] = $driver->attachments;
         $prop['undelete'] = $driver->undelete;
         $prop['feedurl'] = $this->cal->get_url(array('_cal' => $this->cal->ical_feed_hash($id) . '.ics', 'action' => 'feed'));
         if (!$prop['virtual']) {
             $jsenv[$id] = $prop;
         }
         $html_id = html_identifier($id);
         $class = 'cal-' . asciiwords($id, true);
         $title = $prop['name'] != $prop['listname'] ? html_entity_decode($prop['name'], ENT_COMPAT, RCMAIL_CHARSET) : '';
         if ($prop['virtual']) {
             $class .= ' virtual';
         } else {
             if ($prop['readonly']) {
                 $class .= ' readonly';
             }
         }
         if ($prop['class_name']) {
             $class .= ' ' . $prop['class_name'];
         }
         $disabled = array();
         if (!$prop['unsubscribe']) {
             $disabled = array('disabled' => 'disabled');
         }
         $li .= html::tag('li', array('id' => 'rcmlical' . $html_id, 'class' => $class), ($prop['virtual'] ? '' : html::tag('input', array_merge($disabled, array('type' => 'checkbox', 'name' => '_cal[]', 'value' => $id, 'checked' => $prop['active'])), '') . html::span('handle', ' ')) . html::span(array('class' => 'calname', 'title' => $title), $prop['listname']));
     }
     $this->rc->output->set_env('calendars', $jsenv);
     $this->rc->output->add_gui_object('folderlist', $attrib['id']);
     return html::tag('ul', $attrib, $li, html::$common_attrib);
 }
Example #11
0
 /**
  * Add UI element to copy event invitations or updates to the calendar
  */
 public function mail_messagebody_html($p)
 {
     // load iCalendar functions (if necessary)
     if (!empty($this->ics_parts)) {
         $this->get_ical();
     }
     $html = '';
     foreach ($this->ics_parts as $mime_id) {
         $part = $this->message->mime_parts[$mime_id];
         $charset = $part->ctype_parameters['charset'] ? $part->ctype_parameters['charset'] : RCMAIL_CHARSET;
         $events = $this->ical->import($this->message->get_part_content($mime_id), $charset);
         $title = $this->gettext('title');
         $date = rcube_utils::anytodatetime($this->message->headers->date);
         // successfully parsed events?
         if (empty($events)) {
             continue;
         }
         // show a box for every event in the file
         foreach ($events as $idx => $event) {
             // Begin mod by Rosali (Google sends the ics inline and attached -> avoid duplicates with same UID - https://issues.kolab.org/show_bug.cgi?id=3585)
             $uid = $event['uid'] ? $event['uid'] : md5(serialize($event));
             if (isset($this->ics_parts_filtered[$uid])) {
                 continue;
             }
             $this->ics_parts_filtered[$uid] = 1;
             // End mod by Rosali
             if ($event['_type'] != 'event' && $event['_type'] != 'task') {
                 // skip non-event objects (#2928) // Mod by Rosali (don't skip tasks)
                 continue;
             }
             // define buttons according to method
             if ($this->ical->method == 'REPLY') {
                 $driver = $this->get_default_driver();
                 $existing = $driver->get_event($event['uid']);
                 $calendar_saveto = new html_hiddenfield(array('class' => 'calendar-saveto', 'value' => $existing['calendar']));
                 // Mod by Rosali (always pass calendar to GUI)
                 if ($calendar_saveto) {
                     $title = $this->gettext('itipreply');
                     $buttons = html::tag('input', array('type' => 'button', 'class' => 'button', 'onclick' => "rcube_calendar.add_event_from_mail('" . JQ($mime_id . ':' . $idx) . "', this)", 'value' => $this->gettext('updateattendeestatus'))) . $calendar_saveto->show();
                 }
             } else {
                 if ($this->ical->method == 'REQUEST') {
                     $emails = $this->get_user_emails();
                     $title = $event['sequence'] > 0 ? $this->gettext('itipupdate') : $this->gettext('itipinvitation');
                     // add (hidden) buttons and activate them from asyncronous request
                     foreach (array('accepted', 'tentative', 'declined') as $method) {
                         $rsvp_buttons .= html::tag('input', array('type' => 'button', 'class' => "button {$method}", 'onclick' => "rcube_calendar.add_event_from_mail('" . JQ($mime_id . ':' . $idx) . "', this, '{$method}')", 'value' => $this->gettext('itip' . $method)));
                     }
                     $import_button = html::tag('input', array('type' => 'button', 'class' => 'button', 'onclick' => "rcube_calendar.add_event_from_mail('" . JQ($mime_id . ':' . $idx) . "', this)", 'value' => $this->gettext('importtocalendar')));
                     // check my status
                     $status = 'unknown';
                     foreach ($event['attendees'] as $attendee) {
                         if ($attendee['email'] && in_array(strtolower($attendee['email']), $emails)) {
                             $status = !empty($attendee['status']) ? strtoupper($attendee['status']) : 'NEEDS-ACTION';
                             break;
                         }
                     }
                     $dom_id = asciiwords($event['uid'], true);
                     $buttons = html::div(array('id' => 'rsvp-' . $dom_id, 'style' => 'display:none'), $rsvp_buttons);
                     $buttons .= html::div(array('id' => 'import-' . $dom_id, 'style' => 'display:none'), $import_button);
                     $buttons_pre = html::div(array('id' => 'loading-' . $dom_id, 'class' => 'rsvp-status loading'), $this->gettext('loading'));
                     $changed = is_object($event['changed']) ? $event['changed'] : $date;
                     $script = json_serialize(array('uid' => $event['uid'], 'changed' => $changed ? $changed->format('U') : 0, 'sequence' => intval($event['sequence']), 'fallback' => $status));
                     $this->rc->output->add_script("rcube_calendar.fetch_event_rsvp_status({$script})", 'docready');
                 } else {
                     if ($this->ical->method == 'CANCEL') {
                         $title = $this->gettext('itipcancellation');
                         // create buttons to be activated from async request checking existence of this event in local calendars
                         $button_import = html::tag('input', array('type' => 'button', 'class' => 'button', 'onclick' => "rcube_calendar.add_event_from_mail('" . JQ($mime_id . ':' . $idx) . "', this)", 'value' => $this->gettext('importtocalendar')));
                         $button_remove = html::tag('input', array('type' => 'button', 'class' => 'button', 'onclick' => "rcube_calendar.remove_event_from_mail('" . JQ($event['uid']) . "', '" . JQ($event['title']) . "')", 'value' => $this->gettext('removefromcalendar')));
                         $dom_id = asciiwords($event['uid'], true);
                         $buttons = html::div(array('id' => 'rsvp-' . $dom_id, 'style' => 'display:none'), $button_remove);
                         $buttons .= html::div(array('id' => 'import-' . $dom_id, 'style' => 'display:none'), $button_import);
                         $buttons_pre = html::div(array('id' => 'loading-' . $dom_id, 'class' => 'rsvp-status loading'), $this->gettext('loading'));
                         $changed = is_object($event['changed']) ? $event['changed'] : $date;
                         $script = json_serialize(array('uid' => $event['uid'], 'changed' => $changed ? $changed->format('U') : 0, 'sequence' => intval($event['sequence']), 'fallback' => 'CANCELLED'));
                         $this->rc->output->add_script("rcube_calendar.fetch_event_rsvp_status({$script})", 'docready');
                     } else {
                         // get a list of writeable calendars
                         // Begin mod by Rosali (https://gitlab.awesome-it.de/kolab/roundcube-plugins/issues/33)
                         $driver = $this->get_default_driver();
                         $calendars = $driver->list_calendars(false, true);
                         $calendar_select = new html_select(array('name' => 'calendar', 'class' => 'calendar-saveto', 'is_escaped' => true));
                         // Mod by Rosali (calendar selector can exist multiple times - can't be referenced by ID)
                         $numcals = 0;
                         foreach ($calendars as $calendar) {
                             $driver = $this->get_driver_by_cal($calendar['calendar_id']);
                             if ($driver->readonly !== true) {
                                 $calendar_select->add($calendar['name'], $calendar['id']);
                                 $numcals++;
                             }
                         }
                     }
                 }
             }
             if ($numcals > 0) {
                 $buttons = html::tag('input', array('type' => 'button', 'class' => 'button', 'onclick' => "rcube_calendar.add_event_from_mail('" . JQ($mime_id . ':' . $idx) . "', this)", 'value' => $this->gettext('importtocalendar'))) . $calendar_select->show($this->rc->config->get('calendar_default_calendar'));
             }
             // show event details with buttons
             if ($buttons) {
                 $html .= html::div('calendar-invitebox', $this->ui->event_details_table($event, $title) . $buttons_pre . html::div('rsvp-buttons', $buttons));
             }
             // Emd mod by Rosli
             // limit listing
             if ($idx >= 3) {
                 break;
             }
         }
     }
     // prepend event boxes to message body
     if ($html) {
         $this->ui->init();
         $p['content'] = $html . $p['content'];
         $this->rc->output->add_label('calendar.savingdata', 'calendar.deleteventconfirm', 'calendar.declinedeleteconfirm');
     }
     return $p;
 }
 /**
  * Build inline UI elements for iTip messages
  */
 public function mail_itip_inline_ui($event, $method, $mime_id, $task, $message_date = null, $preview_url = null)
 {
     $buttons = array();
     $dom_id = asciiwords($event['uid'], true);
     $rsvp_status = 'unknown';
     // pass some metadata about the event and trigger the asynchronous status check
     $changed = is_object($event['changed']) ? $event['changed'] : $message_date;
     $metadata = array('uid' => $event['uid'], '_instance' => $event['_instance'], 'changed' => $changed ? $changed->format('U') : 0, 'sequence' => intval($event['sequence']), 'method' => $method, 'task' => $task);
     // create buttons to be activated from async request checking existence of this event in local calendars
     $buttons[] = html::div(array('id' => 'loading-' . $dom_id, 'class' => 'rsvp-status loading'), $this->gettext('loading'));
     // on iTip REPLY we have two options:
     if ($method == 'REPLY') {
         $title = $this->gettext('itipreply');
         foreach ($event['attendees'] as $attendee) {
             if (!empty($attendee['email']) && $attendee['role'] != 'ORGANIZER' && (empty($event['_sender']) || ($attendee['email'] == $event['_sender'] || $attendee['email'] == $event['_sender_utf']))) {
                 $metadata['attendee'] = $attendee['email'];
                 $rsvp_status = strtoupper($attendee['status']);
                 if ($attendee['delegated-to']) {
                     $metadata['delegated-to'] = $attendee['delegated-to'];
                 }
                 break;
             }
         }
         // 1. update the attendee status on our copy
         $update_button = html::tag('input', array('type' => 'button', 'class' => 'button', 'onclick' => "rcube_libcalendaring.add_from_itip_mail('" . rcube::JQ($mime_id) . "', '{$task}')", 'value' => $this->gettext('updateattendeestatus')));
         // 2. accept or decline a new or delegate attendee
         $accept_buttons = html::tag('input', array('type' => 'button', 'class' => "button accept", 'onclick' => "rcube_libcalendaring.add_from_itip_mail('" . rcube::JQ($mime_id) . "', '{$task}')", 'value' => $this->gettext('acceptattendee')));
         $accept_buttons .= html::tag('input', array('type' => 'button', 'class' => "button decline", 'onclick' => "rcube_libcalendaring.decline_attendee_reply('" . rcube::JQ($mime_id) . "', '{$task}')", 'value' => $this->gettext('declineattendee')));
         $buttons[] = html::div(array('id' => 'update-' . $dom_id, 'style' => 'display:none'), $update_button);
         $buttons[] = html::div(array('id' => 'accept-' . $dom_id, 'style' => 'display:none'), $accept_buttons);
     } else {
         if ($method == 'REQUEST') {
             $emails = $this->lib->get_user_emails();
             $title = $event['sequence'] > 0 ? $this->gettext('itipupdate') : $this->gettext('itipinvitation');
             $metadata['rsvp'] = true;
             $metadata['sensitivity'] = $event['sensitivity'];
             if (is_object($event['start'])) {
                 $metadata['date'] = $event['start']->format('U');
             }
             // check for X-KOLAB-INVITATIONTYPE property and only show accept/decline buttons
             if (self::get_custom_property($event, 'X-KOLAB-INVITATIONTYPE') == 'CONFIRMATION') {
                 $this->rsvp_actions = array('accepted', 'declined');
                 $metadata['nosave'] = true;
             }
             // 1. display RSVP buttons (if the user was invited)
             foreach ($this->rsvp_actions as $method) {
                 $rsvp_buttons .= html::tag('input', array('type' => 'button', 'class' => "button {$method}", 'onclick' => "rcube_libcalendaring.add_from_itip_mail('" . rcube::JQ($mime_id) . "', '{$task}', '{$method}', '{$dom_id}')", 'value' => $this->gettext('itip' . $method)));
             }
             // add button to open calendar/preview
             if (!empty($preview_url)) {
                 $msgref = $this->lib->ical_message->folder . '/' . $this->lib->ical_message->uid . '#' . $mime_id;
                 $rsvp_buttons .= html::tag('input', array('type' => 'button', 'class' => "button preview", 'onclick' => "rcube_libcalendaring.open_itip_preview('" . rcube::JQ($preview_url) . "', '" . rcube::JQ($msgref) . "')", 'value' => $this->gettext('openpreview')));
             }
             // 2. update the local copy with minor changes
             $update_button = html::tag('input', array('type' => 'button', 'class' => 'button', 'onclick' => "rcube_libcalendaring.add_from_itip_mail('" . rcube::JQ($mime_id) . "', '{$task}')", 'value' => $this->gettext('updatemycopy')));
             // 3. Simply import the event without replying
             $import_button = html::tag('input', array('type' => 'button', 'class' => 'button', 'onclick' => "rcube_libcalendaring.add_from_itip_mail('" . rcube::JQ($mime_id) . "', '{$task}')", 'value' => $this->gettext('importtocalendar')));
             // check my status
             foreach ($event['attendees'] as $attendee) {
                 if ($attendee['email'] && in_array(strtolower($attendee['email']), $emails)) {
                     $metadata['attendee'] = $attendee['email'];
                     $metadata['rsvp'] = $attendee['rsvp'] || $attendee['role'] != 'NON-PARTICIPANT';
                     $rsvp_status = !empty($attendee['status']) ? strtoupper($attendee['status']) : 'NEEDS-ACTION';
                     break;
                 }
             }
             // add itip reply message controls
             $rsvp_buttons .= html::div('itip-reply-controls', $this->itip_rsvp_options_ui($dom_id, $metadata['nosave']));
             $buttons[] = html::div(array('id' => 'rsvp-' . $dom_id, 'class' => 'rsvp-buttons', 'style' => 'display:none'), $rsvp_buttons);
             $buttons[] = html::div(array('id' => 'update-' . $dom_id, 'style' => 'display:none'), $update_button);
             // prepare autocompletion for delegation dialog
             if (in_array('delegated', $this->rsvp_actions)) {
                 $this->rc->autocomplete_init();
             }
         } else {
             if ($method == 'CANCEL') {
                 $title = $this->gettext('itipcancellation');
                 $event_prop = array_filter(array('uid' => $event['uid'], '_instance' => $event['_instance'], '_savemode' => $event['_savemode']));
                 // 1. remove the event from our calendar
                 $button_remove = html::tag('input', array('type' => 'button', 'class' => 'button', 'onclick' => "rcube_libcalendaring.remove_from_itip(" . rcube_output::json_serialize($event_prop) . ", '{$task}', '" . rcube::JQ($event['title']) . "')", 'value' => $this->gettext('removefromcalendar')));
                 // 2. update our copy with status=cancelled
                 $button_update = html::tag('input', array('type' => 'button', 'class' => 'button', 'onclick' => "rcube_libcalendaring.add_from_itip_mail('" . rcube::JQ($mime_id) . "', '{$task}')", 'value' => $this->gettext('updatemycopy')));
                 $buttons[] = html::div(array('id' => 'rsvp-' . $dom_id, 'style' => 'display:none'), $button_remove . $button_update);
                 $rsvp_status = 'CANCELLED';
                 $metadata['rsvp'] = true;
             }
         }
     }
     // append generic import button
     if ($import_button) {
         $buttons[] = html::div(array('id' => 'import-' . $dom_id, 'style' => 'display:none'), $import_button);
     }
     // pass some metadata about the event and trigger the asynchronous status check
     $metadata['fallback'] = $rsvp_status;
     $metadata['rsvp'] = intval($metadata['rsvp']);
     $this->rc->output->add_script("rcube_libcalendaring.fetch_itip_object_status(" . rcube_output::json_serialize($metadata) . ")", 'docready');
     // get localized texts from the right domain
     foreach (array('savingdata', 'deleteobjectconfirm', 'declinedeleteconfirm', 'declineattendee', 'cancel', 'itipdelegated', 'declineattendeeconfirm', 'itipcomment', 'delegateinvitation', 'delegateto', 'delegatersvpme', 'delegateinvalidaddress') as $label) {
         $this->rc->output->command('add_label', "itip.{$label}", $this->gettext($label));
     }
     // show event details with buttons
     return $this->itip_object_details_table($event, $title) . html::div(array('class' => 'itip-buttons', 'id' => 'itip-buttons-' . asciiwords($metadata['uid'], true)), join('', $buttons));
 }
Example #13
0
 /**
  * Setter for application task
  *
  * @param string Task to set
  */
 public function set_task($task)
 {
     $task = asciiwords($task);
     $this->task = $task ? $task : 'mail';
     $this->comm_path = $this->url(array('task' => $this->task));
     if ($this->output) {
         $this->output->set_env('task', $this->task);
     }
 }
Example #14
0
 private function _gen_folder_list($arrFolders, $command, $nestLevel = 0, &$folderTotal = 0)
 {
     $rcmail = rcmail::get_instance();
     $maxlength = 35;
     $realnames = false;
     $out = '';
     foreach ($arrFolders as $key => $folder) {
         $title = null;
         if (($folder_class = rcmail_folder_classname($folder['id'])) && !$realnames) {
             $foldername = rcube_label($folder_class);
         } else {
             $foldername = $folder['name'];
             // shorten the folder name to a given length
             if ($maxlength && $maxlength > 1) {
                 $fname = abbreviate_string($foldername, $maxlength);
                 if ($fname != $foldername) {
                     $title = $foldername;
                 }
                 $foldername = $fname;
             }
         }
         // make folder name safe for ids and class names
         $folder_id = asciiwords($folder['id'], true, '_');
         $classes = array();
         // set special class for Sent, Drafts, Trash and Junk
         if ($folder['id'] == $rcmail->config->get('sent_mbox')) {
             $classes[] = 'sent';
         } else {
             if ($folder['id'] == $rcmail->config->get('drafts_mbox')) {
                 $classes[] = 'drafts';
             } else {
                 if ($folder['id'] == $rcmail->config->get('trash_mbox')) {
                     $classes[] = 'trash';
                 } else {
                     if ($folder['id'] == $rcmail->config->get('junk_mbox')) {
                         $classes[] = 'junk';
                     } else {
                         if ($folder['id'] == 'INBOX') {
                             $classes[] = 'inbox';
                         } else {
                             $classes[] = '_' . asciiwords($folder_class ? $folder_class : strtolower($folder['id']), true);
                         }
                     }
                 }
             }
         }
         if ($folder['virtual']) {
             $classes[] = 'virtual';
         }
         $out .= html::tag('li', array('class' => join(' ', $classes)), html::a(array('href' => $command, 'onclick' => "rcm_set_dest_folder('" . JQ($folder['id']) . "')", 'class' => 'active', 'title' => $title), str_repeat('  ', $nestLevel) . Q($foldername)));
         if (!empty($folder['folders'])) {
             $out .= $this->_gen_folder_list($folder['folders'], $command, $nestLevel + 1, $folderTotal);
         }
         $folderTotal++;
     }
     if ($nestLevel == 0) {
         if ($folderTotal > 5) {
             $out = html::tag('ul', array('class' => 'toolbarmenu folders scrollable'), $out);
             $out = html::tag('div', array('class' => 'scroll_up_pas'), '') . $out . html::tag('div', array('class' => 'scroll_down_act'), '');
             $out = html::tag('div', array('class' => 'popupmenu'), $out);
         } else {
             $out = html::tag('ul', array('class' => 'popupmenu toolbarmenu folders'), $out);
         }
     }
     return $out;
 }
Example #15
0
 /**
  * Object constructor
  *
  * @param array   $p            LDAP connection properties
  * @param boolean $debug        Enables debug mode
  * @param string  $mail_domain  Current user mail domain name
  */
 function __construct($p, $debug = false, $mail_domain = null)
 {
     $this->prop = $p;
     $fetch_attributes = array('objectClass');
     // check if groups are configured
     if (is_array($p['groups']) && count($p['groups'])) {
         $this->groups = true;
         // set member field
         if (!empty($p['groups']['member_attr'])) {
             $this->prop['member_attr'] = strtolower($p['groups']['member_attr']);
         } else {
             if (empty($p['member_attr'])) {
                 $this->prop['member_attr'] = 'member';
             }
         }
         // set default name attribute to cn
         if (empty($this->prop['groups']['name_attr'])) {
             $this->prop['groups']['name_attr'] = 'cn';
         }
         if (empty($this->prop['groups']['scope'])) {
             $this->prop['groups']['scope'] = 'sub';
         }
         // extend group objectclass => member attribute mapping
         if (!empty($this->prop['groups']['class_member_attr'])) {
             $this->group_types = array_merge($this->group_types, $this->prop['groups']['class_member_attr']);
         }
         // add group name attrib to the list of attributes to be fetched
         $fetch_attributes[] = $this->prop['groups']['name_attr'];
     }
     if (is_array($p['group_filters'])) {
         $this->groups = $this->groups || count($p['group_filters']);
         foreach ($p['group_filters'] as $k => $group_filter) {
             // set default name attribute to cn
             if (empty($group_filter['name_attr']) && empty($this->prop['groups']['name_attr'])) {
                 $this->prop['group_filters'][$k]['name_attr'] = $group_filter['name_attr'] = 'cn';
             }
             if ($group_filter['name_attr']) {
                 $fetch_attributes[] = $group_filter['name_attr'];
             }
         }
     }
     // fieldmap property is given
     if (is_array($p['fieldmap'])) {
         foreach ($p['fieldmap'] as $rf => $lf) {
             $this->fieldmap[$rf] = $this->_attr_name(strtolower($lf));
         }
     } else {
         if (!empty($p)) {
             // read deprecated *_field properties to remain backwards compatible
             foreach ($p as $prop => $value) {
                 if (preg_match('/^(.+)_field$/', $prop, $matches)) {
                     $this->fieldmap[$matches[1]] = $this->_attr_name(strtolower($value));
                 }
             }
         }
     }
     // use fieldmap to advertise supported coltypes to the application
     foreach ($this->fieldmap as $colv => $lfv) {
         list($col, $type) = explode(':', $colv);
         list($lf, $limit, $delim) = explode(':', $lfv);
         if ($limit == '*') {
             $limit = null;
         } else {
             $limit = max(1, intval($limit));
         }
         if (!is_array($this->coltypes[$col])) {
             $subtypes = $type ? array($type) : null;
             $this->coltypes[$col] = array('limit' => $limit, 'subtypes' => $subtypes, 'attributes' => array($lf));
         } elseif ($type) {
             $this->coltypes[$col]['subtypes'][] = $type;
             $this->coltypes[$col]['attributes'][] = $lf;
             $this->coltypes[$col]['limit'] += $limit;
         }
         if ($delim) {
             $this->coltypes[$col]['serialized'][$type] = $delim;
         }
         $this->fieldmap[$colv] = $lf;
     }
     // support for composite address
     if ($this->coltypes['street'] && $this->coltypes['locality']) {
         $this->coltypes['address'] = array('limit' => max(1, $this->coltypes['locality']['limit'] + $this->coltypes['address']['limit']), 'subtypes' => array_merge((array) $this->coltypes['address']['subtypes'], (array) $this->coltypes['locality']['subtypes']), 'childs' => array()) + (array) $this->coltypes['address'];
         foreach (array('street', 'locality', 'zipcode', 'region', 'country') as $childcol) {
             if ($this->coltypes[$childcol]) {
                 $this->coltypes['address']['childs'][$childcol] = array('type' => 'text');
                 unset($this->coltypes[$childcol]);
                 // remove address child col from global coltypes list
             }
         }
         // at least one address type must be specified
         if (empty($this->coltypes['address']['subtypes'])) {
             $this->coltypes['address']['subtypes'] = array('home');
         }
     } else {
         if ($this->coltypes['address']) {
             $this->coltypes['address'] += array('type' => 'textarea', 'childs' => null, 'size' => 40);
             // 'serialized' means the UI has to present a composite address field
             if ($this->coltypes['address']['serialized']) {
                 $childprop = array('type' => 'text');
                 $this->coltypes['address']['type'] = 'composite';
                 $this->coltypes['address']['childs'] = array('street' => $childprop, 'locality' => $childprop, 'zipcode' => $childprop, 'country' => $childprop);
             }
         }
     }
     // make sure 'required_fields' is an array
     if (!is_array($this->prop['required_fields'])) {
         $this->prop['required_fields'] = (array) $this->prop['required_fields'];
     }
     // make sure LDAP_rdn field is required
     if (!empty($this->prop['LDAP_rdn']) && !in_array($this->prop['LDAP_rdn'], $this->prop['required_fields']) && !in_array($this->prop['LDAP_rdn'], array_keys((array) $this->prop['autovalues']))) {
         $this->prop['required_fields'][] = $this->prop['LDAP_rdn'];
     }
     foreach ($this->prop['required_fields'] as $key => $val) {
         $this->prop['required_fields'][$key] = $this->_attr_name(strtolower($val));
     }
     // Build sub_fields filter
     if (!empty($this->prop['sub_fields']) && is_array($this->prop['sub_fields'])) {
         $this->sub_filter = '';
         foreach ($this->prop['sub_fields'] as $class) {
             if (!empty($class)) {
                 $class = is_array($class) ? array_pop($class) : $class;
                 $this->sub_filter .= '(objectClass=' . $class . ')';
             }
         }
         if (count($this->prop['sub_fields']) > 1) {
             $this->sub_filter = '(|' . $this->sub_filter . ')';
         }
     }
     $this->sort_col = is_array($p['sort']) ? $p['sort'][0] : $p['sort'];
     $this->debug = $debug;
     $this->mail_domain = $mail_domain;
     // initialize cache
     $rcube = rcube::get_instance();
     if ($cache_type = $rcube->config->get('ldap_cache', 'db')) {
         $cache_ttl = $rcube->config->get('ldap_cache_ttl', '10m');
         $cache_name = 'LDAP.' . asciiwords($this->prop['name']);
         $this->cache = $rcube->get_cache($cache_name, $cache_type, $cache_ttl);
     }
     // determine which attributes to fetch
     $this->prop['list_attributes'] = array_unique($fetch_attributes);
     $this->prop['attributes'] = array_merge(array_values($this->fieldmap), $fetch_attributes);
     foreach ($rcube->config->get('contactlist_fields') as $col) {
         $this->prop['list_attributes'] = array_merge($this->prop['list_attributes'], $this->_map_field($col));
     }
     // initialize ldap wrapper object
     $this->ldap = new rcube_ldap_generic($this->prop);
     $this->ldap->config_set(array('cache' => $this->cache, 'debug' => $this->debug));
     $this->_connect();
 }
 /**
  * Object constructor
  *
  * @param array 	    LDAP connection properties
  * @param boolean 	Enables debug mode
  * @param string 	Current user mail domain name
  * @param integer User-ID
  */
 function __construct($p, $debug = false, $mail_domain = NULL)
 {
     $this->prop = $p;
     if (isset($p['searchonly'])) {
         $this->searchonly = $p['searchonly'];
     }
     // check if groups are configured
     if (is_array($p['groups']) && count($p['groups'])) {
         $this->groups = true;
         // set member field
         if (!empty($p['groups']['member_attr'])) {
             $this->prop['member_attr'] = strtolower($p['groups']['member_attr']);
         } else {
             if (empty($p['member_attr'])) {
                 $this->prop['member_attr'] = 'member';
             }
         }
         // set default name attribute to cn
         if (empty($this->prop['groups']['name_attr'])) {
             $this->prop['groups']['name_attr'] = 'cn';
         }
         if (empty($this->prop['groups']['scope'])) {
             $this->prop['groups']['scope'] = 'sub';
         }
     }
     // fieldmap property is given
     if (is_array($p['fieldmap'])) {
         foreach ($p['fieldmap'] as $rf => $lf) {
             $this->fieldmap[$rf] = $this->_attr_name(strtolower($lf));
         }
     } else {
         if (!empty($p)) {
             // read deprecated *_field properties to remain backwards compatible
             foreach ($p as $prop => $value) {
                 if (preg_match('/^(.+)_field$/', $prop, $matches)) {
                     $this->fieldmap[$matches[1]] = $this->_attr_name(strtolower($value));
                 }
             }
         }
     }
     // use fieldmap to advertise supported coltypes to the application
     foreach ($this->fieldmap as $colv => $lfv) {
         list($col, $type) = explode(':', $colv);
         list($lf, $limit, $delim) = explode(':', $lfv);
         if ($limit == '*') {
             $limit = null;
         } else {
             $limit = max(1, intval($limit));
         }
         if (!is_array($this->coltypes[$col])) {
             $subtypes = $type ? array($type) : null;
             $this->coltypes[$col] = array('limit' => $limit, 'subtypes' => $subtypes);
         } elseif ($type) {
             $this->coltypes[$col]['subtypes'][] = $type;
             $this->coltypes[$col]['limit'] += $limit;
         }
         if ($delim) {
             $this->coltypes[$col]['serialized'][$type] = $delim;
         }
         if ($type && !$this->fieldmap[$col]) {
             $this->fieldmap[$col] = $lf;
         }
         $this->fieldmap[$colv] = $lf;
     }
     // support for composite address
     if ($this->fieldmap['street'] && $this->fieldmap['locality']) {
         $this->coltypes['address'] = array('limit' => max(1, $this->coltypes['locality']['limit'] + $this->coltypes['address']['limit']), 'subtypes' => array_merge((array) $this->coltypes['address']['subtypes'], (array) $this->coltypes['locality']['subtypes']), 'childs' => array()) + (array) $this->coltypes['address'];
         foreach (array('street', 'locality', 'zipcode', 'region', 'country') as $childcol) {
             if ($this->fieldmap[$childcol]) {
                 $this->coltypes['address']['childs'][$childcol] = array('type' => 'text');
                 unset($this->coltypes[$childcol]);
                 // remove address child col from global coltypes list
             }
         }
         // at least one address type must be specified
         if (empty($this->coltypes['address']['subtypes'])) {
             $this->coltypes['address']['subtypes'] = array('home');
         }
     } else {
         if ($this->coltypes['address']) {
             $this->coltypes['address'] += array('type' => 'textarea', 'childs' => null, 'size' => 40);
             // 'serialized' means the UI has to present a composite address field
             if ($this->coltypes['address']['serialized']) {
                 $childprop = array('type' => 'text');
                 $this->coltypes['address']['type'] = 'composite';
                 $this->coltypes['address']['childs'] = array('street' => $childprop, 'locality' => $childprop, 'zipcode' => $childprop, 'country' => $childprop);
             }
         }
     }
     // make sure 'required_fields' is an array
     if (!is_array($this->prop['required_fields'])) {
         $this->prop['required_fields'] = (array) $this->prop['required_fields'];
     }
     // make sure LDAP_rdn field is required
     if (!empty($this->prop['LDAP_rdn']) && !in_array($this->prop['LDAP_rdn'], $this->prop['required_fields'])) {
         $this->prop['required_fields'][] = $this->prop['LDAP_rdn'];
     }
     foreach ($this->prop['required_fields'] as $key => $val) {
         $this->prop['required_fields'][$key] = $this->_attr_name(strtolower($val));
     }
     // Build sub_fields filter
     if (!empty($this->prop['sub_fields']) && is_array($this->prop['sub_fields'])) {
         $this->sub_filter = '';
         foreach ($this->prop['sub_fields'] as $attr => $class) {
             if (!empty($class)) {
                 $class = is_array($class) ? array_pop($class) : $class;
                 $this->sub_filter .= '(objectClass=' . $class . ')';
             }
         }
         if (count($this->prop['sub_fields']) > 1) {
             $this->sub_filter = '(|' . $this->sub_filter . ')';
         }
     }
     $this->sort_col = is_array($p['sort']) ? $p['sort'][0] : $p['sort'];
     $this->debug = $debug;
     $this->mail_domain = $mail_domain;
     // initialize cache
     $rcmail = rcmail::get_instance();
     $this->cache = $rcmail->get_cache('LDAP.' . asciiwords($this->prop['name']), 'db', 600);
     $this->_connect();
 }
 /**
  * Convert the given string into a valid HTML identifier
  * Same functionality as done in app.js with rcube_webmail.html_identifier()
  */
 public static function html_identifier($str, $encode = false)
 {
     if ($encode) {
         return rtrim(strtr(base64_encode($str), '+/', '-_'), '=');
     } else {
         return asciiwords($str, true, '_');
     }
 }
Example #18
0
 /**
  * Register this plugin to be responsible for a specific task
  *
  * @param string Task name (only characters [a-z0-9_.-] are allowed)
  */
 public function register_task($task)
 {
     if ($task != asciiwords($task)) {
         raise_error(array('code' => 526, 'type' => 'php', 'file' => __FILE__, 'line' => __LINE__, 'message' => "Invalid task name: {$task}. Only characters [a-z0-9_.-] are allowed"), true, false);
     } else {
         if (in_array(rcmail::$main_tasks, $task)) {
             raise_error(array('code' => 526, 'type' => 'php', 'file' => __FILE__, 'line' => __LINE__, 'message' => "Cannot register taks {$task}; already taken by another plugin or the application itself"), true, false);
         } else {
             rcmail::$main_tasks[] = $task;
         }
     }
 }