/**
  * Callback function used to build mailto: links around e-mail strings
  *
  * This also adds an onclick-handler to open the Rouncube compose message screen on such links
  *
  * @param array Matches result from preg_replace_callback
  * @return int Index of saved string value
  * @see rcube_string_replacer::mailto_callback()
  */
 public function mailto_callback($matches)
 {
     $href = $matches[1];
     $suffix = $this->parse_url_brackets($href);
     $i = $this->add(html::a(array('href' => 'mailto:' . $href, 'onclick' => "return " . rcmail_output::JS_OBJECT_NAME . ".command('compose','" . rcube::JQ($href) . "',this)"), rcube::Q($href)) . $suffix);
     return $i >= 0 ? $this->get_replacement($i) : '';
 }
Esempio n. 2
0
 /**
  * This callback function adds a box below the message content
  * if there is a vcard attachment available
  */
 function html_output($p)
 {
     $attach_script = false;
     foreach ($this->vcard_parts as $part) {
         $vcards = rcube_vcard::import($this->message->get_part_content($part, null, true));
         // successfully parsed vcards?
         if (empty($vcards)) {
             continue;
         }
         // remove part's body
         if (in_array($part, $this->vcard_bodies)) {
             $p['content'] = '';
         }
         foreach ($vcards as $idx => $vcard) {
             // skip invalid vCards
             if (empty($vcard->email) || empty($vcard->email[0])) {
                 continue;
             }
             $display = $vcard->displayname . ' <' . $vcard->email[0] . '>';
             // add box below message body
             $p['content'] .= html::p(array('class' => 'vcardattachment'), html::a(array('href' => "#", 'onclick' => "return plugin_vcard_save_contact('" . rcube::JQ($part . ':' . $idx) . "')", 'title' => $this->gettext('addvcardmsg')), html::span(null, rcube::Q($display))));
         }
         $attach_script = true;
     }
     if ($attach_script) {
         $this->include_script('vcardattach.js');
         $this->include_stylesheet($this->local_skin_path() . '/style.css');
     }
     return $p;
 }
 /**
  * Callback function when HTML page is rendered
  * We'll add an overlay box here.
  */
 function render_page($p)
 {
     if ($_SESSION['plugin.newuserdialog'] && $p['template'] == 'mail') {
         $this->add_texts('localization');
         $rcmail = rcmail::get_instance();
         $identity = $rcmail->user->get_identity();
         $identities_level = intval($rcmail->config->get('identities_level', 0));
         // compose user-identity dialog
         $table = new html_table(array('cols' => 2));
         $table->add('title', $this->gettext('name'));
         $table->add(null, html::tag('input', array('type' => 'text', 'name' => '_name', 'value' => $identity['name'], 'disabled' => $identities_level == 4)));
         $table->add('title', $this->gettext('email'));
         $table->add(null, html::tag('input', array('type' => 'text', 'name' => '_email', 'value' => rcube_utils::idn_to_utf8($identity['email']), 'disabled' => in_array($identities_level, array(1, 3, 4)))));
         $table->add('title', $this->gettext('organization'));
         $table->add(null, html::tag('input', array('type' => 'text', 'name' => '_organization', 'value' => $identity['organization'], 'disabled' => $identities_level == 4)));
         $table->add('title', $this->gettext('signature'));
         $table->add(null, html::tag('textarea', array('name' => '_signature', 'rows' => '3'), $identity['signature']));
         // add overlay input box to html page
         $rcmail->output->add_footer(html::tag('form', array('id' => 'newuserdialog', 'action' => $rcmail->url('plugin.newusersave'), 'method' => 'post'), html::p('hint', rcube::Q($this->gettext('identitydialoghint'))) . $table->show() . html::p(array('class' => 'formbuttons'), html::tag('input', array('type' => 'submit', 'class' => 'button mainaction', 'value' => $this->gettext('save'))))));
         $title = rcube::JQ($this->gettext('identitydialogtitle'));
         $script = "\n\$('#newuserdialog').show()\n  .dialog({modal:true, resizable:false, closeOnEscape:false, width:450, title:'{$title}'})\n  .submit(function() {\n    var i, request = {}, form = \$(this).serializeArray();\n    for (i in form)\n      request[form[i].name] = form[i].value;\n\n      rcmail.http_post('plugin.newusersave', request, true);\n      return false;\n  });\n\n\$('input[name=_name]').focus();\nrcube_webmail.prototype.new_user_dialog_close = function() { \$('#newuserdialog').dialog('close'); }\n";
         // disable keyboard events for messages list (#1486726)
         $rcmail->output->add_script($script, 'docready');
         $this->include_stylesheet('newuserdialog.css');
     }
 }
 /**
  * Callback function used to build mailto: links around e-mail strings
  *
  * This also adds an onclick-handler to open the Rouncube compose message screen on such links
  *
  * @param array Matches result from preg_replace_callback
  * @return int Index of saved string value
  * @see rcube_string_replacer::mailto_callback()
  */
 public function mailto_callback($matches)
 {
     $href = $matches[1];
     $suffix = $this->parse_url_brackets($href);
     $email = $href;
     if (strpos($email, '?')) {
         list($email, ) = explode('?', $email);
     }
     // skip invalid emails
     if (!rcube_utils::check_email($email, false)) {
         return $matches[1];
     }
     $i = $this->add(html::a(array('href' => 'mailto:' . $href, 'onclick' => "return " . rcmail_output::JS_OBJECT_NAME . ".command('compose','" . rcube::JQ($href) . "',this)"), rcube::Q($href)) . $suffix);
     return $i >= 0 ? $this->get_replacement($i) : '';
 }
Esempio n. 5
0
 /**
  * This callback function adds a box below the message content
  * if there is a vcard attachment available
  */
 function html_output($p)
 {
     $attach_script = false;
     foreach ($this->ics_parts as $part) {
         $icscontent = $this->message->get_part_content($part['part'], null, true);
         $file_name = $part['uid'];
         $file = '../../../cache/import/' . $file_name . '.ics';
         file_put_contents($file, $icscontent);
         // add box below message body
         $p['content'] .= html::p(array('class' => 'icalattachments'), html::a(array('href' => "#", 'class' => rcube::JQ($file_name), 'title' => $this->gettext('addicalinvitemsg')), html::span(null, rcube::Q($this->gettext('addicalinvitemsg')))));
         $attach_script = true;
     }
     if ($attach_script) {
         $this->include_stylesheet($this->local_skin_path() . '/style.css');
     }
     return $p;
 }
 /**
  * Callback function for parsing an xml command tag
  * and turn it into real html content
  *
  * @param  array Matches array of preg_replace_callback
  * @return string Tag/Object content
  */
 protected function xml_command($matches)
 {
     $command = strtolower($matches[1]);
     $attrib = html::parse_attrib_string($matches[2]);
     // empty output if required condition is not met
     if (!empty($attrib['condition']) && !$this->check_condition($attrib['condition'])) {
         return '';
     }
     // execute command
     switch ($command) {
         // return a button
         case 'button':
             if ($attrib['name'] || $attrib['command']) {
                 return $this->button($attrib);
             }
             break;
             // frame
         // frame
         case 'frame':
             return $this->frame($attrib);
             break;
             // show a label
         // show a label
         case 'label':
             if ($attrib['expression']) {
                 $attrib['name'] = $this->eval_expression($attrib['expression']);
             }
             if ($attrib['name'] || $attrib['command']) {
                 // @FIXME: 'noshow' is useless, remove?
                 if ($attrib['noshow']) {
                     return '';
                 }
                 $vars = $attrib + array('product' => $this->config->get('product_name'));
                 unset($vars['name'], $vars['command']);
                 $label = $this->app->gettext($attrib + array('vars' => $vars));
                 $quoting = !empty($attrib['quoting']) ? strtolower($attrib['quoting']) : (rcube_utils::get_boolean((string) $attrib['html']) ? 'no' : '');
                 switch ($quoting) {
                     case 'no':
                     case 'raw':
                         break;
                     case 'javascript':
                     case 'js':
                         $label = rcube::JQ($label);
                         break;
                     default:
                         $label = html::quote($label);
                         break;
                 }
                 return $label;
             }
             break;
             // include a file
         // include a file
         case 'include':
             $old_base_path = $this->base_path;
             if (!empty($attrib['skin_path'])) {
                 $attrib['skinpath'] = $attrib['skin_path'];
             }
             if ($path = $this->get_skin_file($attrib['file'], $skin_path, $attrib['skinpath'])) {
                 $this->base_path = preg_replace('!plugins/\\w+/!', '', $skin_path);
                 // set base_path to core skin directory (not plugin's skin)
                 $path = realpath($path);
             }
             if (is_readable($path)) {
                 if ($this->config->get('skin_include_php')) {
                     $incl = $this->include_php($path);
                 } else {
                     $incl = file_get_contents($path);
                 }
                 $incl = $this->parse_conditions($incl);
                 $incl = $this->parse_xml($incl);
                 $incl = $this->fix_paths($incl);
                 $this->base_path = $old_base_path;
                 return $incl;
             }
             break;
         case 'plugin.include':
             $hook = $this->app->plugins->exec_hook("template_plugin_include", $attrib);
             return $hook['content'];
             // define a container block
         // define a container block
         case 'container':
             if ($attrib['name'] && $attrib['id']) {
                 $this->command('gui_container', $attrib['name'], $attrib['id']);
                 // let plugins insert some content here
                 $hook = $this->app->plugins->exec_hook("template_container", $attrib);
                 return $hook['content'];
             }
             break;
             // return code for a specific application object
         // return code for a specific application object
         case 'object':
             $object = strtolower($attrib['name']);
             $content = '';
             // we are calling a class/method
             if (($handler = $this->object_handlers[$object]) && is_array($handler)) {
                 if (is_object($handler[0]) && method_exists($handler[0], $handler[1]) || is_string($handler[0]) && class_exists($handler[0])) {
                     $content = call_user_func($handler, $attrib);
                 }
             } else {
                 if (function_exists($handler)) {
                     $content = call_user_func($handler, $attrib);
                 } else {
                     if ($object == 'doctype') {
                         $content = html::doctype($attrib['value']);
                     } else {
                         if ($object == 'logo') {
                             $attrib += array('alt' => $this->xml_command(array('', 'object', 'name="productname"')));
                             if ($logo = $this->config->get('skin_logo')) {
                                 if (is_array($logo)) {
                                     if ($template_logo = $logo[$this->template_name]) {
                                         $attrib['src'] = $template_logo;
                                     } elseif ($template_logo = $logo['*']) {
                                         $attrib['src'] = $template_logo;
                                     }
                                 } else {
                                     $attrib['src'] = $logo;
                                 }
                             }
                             $content = html::img($attrib);
                         } else {
                             if ($object == 'productname') {
                                 $name = $this->config->get('product_name', 'Roundcube Webmail');
                                 $content = html::quote($name);
                             } else {
                                 if ($object == 'version') {
                                     $ver = (string) RCMAIL_VERSION;
                                     if (is_file(RCUBE_INSTALL_PATH . '.svn/entries')) {
                                         if (preg_match('/Revision:\\s(\\d+)/', @shell_exec('svn info'), $regs)) {
                                             $ver .= ' [SVN r' . $regs[1] . ']';
                                         }
                                     } else {
                                         if (is_file(RCUBE_INSTALL_PATH . '.git/index')) {
                                             if (preg_match('/Date:\\s+([^\\n]+)/', @shell_exec('git log -1'), $regs)) {
                                                 if ($date = date('Ymd.Hi', strtotime($regs[1]))) {
                                                     $ver .= ' [GIT ' . $date . ']';
                                                 }
                                             }
                                         }
                                     }
                                     $content = html::quote($ver);
                                 } else {
                                     if ($object == 'steptitle') {
                                         $content = html::quote($this->get_pagetitle());
                                     } else {
                                         if ($object == 'pagetitle') {
                                             if ($this->devel_mode && !empty($_SESSION['username'])) {
                                                 $title = $_SESSION['username'] . ' :: ';
                                             } else {
                                                 if ($prod_name = $this->config->get('product_name')) {
                                                     $title = $prod_name . ' :: ';
                                                 } else {
                                                     $title = '';
                                                 }
                                             }
                                             $title .= $this->get_pagetitle();
                                             $content = html::quote($title);
                                         }
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
             // exec plugin hooks for this template object
             $hook = $this->app->plugins->exec_hook("template_object_{$object}", $attrib + array('content' => $content));
             return $hook['content'];
             // return code for a specified eval expression
         // return code for a specified eval expression
         case 'exp':
             return html::quote($this->eval_expression($attrib['expression']));
             // return variable
         // return variable
         case 'var':
             $var = explode(':', $attrib['name']);
             $name = $var[1];
             $value = '';
             switch ($var[0]) {
                 case 'env':
                     $value = $this->env[$name];
                     break;
                 case 'config':
                     $value = $this->config->get($name);
                     if (is_array($value) && $value[$_SESSION['storage_host']]) {
                         $value = $value[$_SESSION['storage_host']];
                     }
                     break;
                 case 'request':
                     $value = rcube_utils::get_input_value($name, rcube_utils::INPUT_GPC);
                     break;
                 case 'session':
                     $value = $_SESSION[$name];
                     break;
                 case 'cookie':
                     $value = htmlspecialchars($_COOKIE[$name]);
                     break;
                 case 'browser':
                     $value = $this->browser->{$name};
                     break;
             }
             if (is_array($value)) {
                 $value = implode(', ', $value);
             }
             return html::quote($value);
         case 'form':
             return $this->form_tag($attrib);
     }
     return '';
 }
Esempio n. 7
0
 /**
  * Handler for template_object_messagebody hook.
  * This callback function adds a box below the message content
  * if there is a key/cert attachment available
  */
 function message_output($p)
 {
     foreach ($this->keys_parts as $part) {
         // remove part's body
         if (in_array($part, $this->keys_bodies)) {
             $p['content'] = '';
         }
         // add box below message body
         $p['content'] .= html::p(array('class' => 'enigmaattachment'), html::a(array('href' => "#", 'onclick' => "return " . rcmail_output::JS_OBJECT_NAME . ".enigma_import_attachment('" . rcube::JQ($part) . "')", 'title' => $this->enigma->gettext('keyattimport')), html::span(null, $this->enigma->gettext('keyattfound'))));
         $attach_scripts = true;
     }
     if ($attach_scripts) {
         // add css and js script
         $this->add_css();
         $this->add_js();
     }
     return $p;
 }
Esempio n. 8
0
 /**
  * Handler for template_object_messagebody hook.
  * This callback function adds a box below the message content
  * if there is a key/cert attachment available
  */
 function message_output($p)
 {
     $attach_script = false;
     foreach ($this->keys_parts as $part) {
         // remove part's body
         if (in_array($part, $this->keys_bodies)) {
             $p['content'] = '';
         }
         $style = "margin:0 1em; padding:0.2em 0.5em; border:1px solid #999; width: auto" . " border-radius:4px; -moz-border-radius:4px; -webkit-border-radius:4px";
         // add box below message body
         $p['content'] .= html::p(array('style' => $style), html::a(array('href' => "#", 'onclick' => "return " . rcmail_output::JS_OBJECT_NAME . ".enigma_import_attachment('" . rcube::JQ($part) . "')", 'title' => $this->gettext('keyattimport')), html::img(array('src' => $this->url('skins/classic/key_add.png'), 'style' => "vertical-align:middle"))) . ' ' . html::span(null, $this->gettext('keyattfound')));
         $attach_script = true;
     }
     if ($attach_script) {
         $this->include_script('enigma.js');
     }
     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));
 }