Thomas Bruederli
2012-11-27 60226a75d8e4a3ee9504da6eab6d8f329bb32e7b
Separate the very application-specific output classes from the Roundcube framework; add autoloader for rmail* classes
2 files added
2 files renamed
7 files modified
438 ■■■■■ changed files
program/include/bc.php 4 ●●●● patch | view | raw | blame | history
program/include/iniset.php 22 ●●●●● patch | view | raw | blame | history
program/include/rcmail.php 20 ●●●●● patch | view | raw | blame | history
program/include/rcmail_output.php 120 ●●●●● patch | view | raw | blame | history
program/include/rcmail_output_html.php 24 ●●●● patch | view | raw | blame | history
program/include/rcmail_output_json.php 8 ●●●● patch | view | raw | blame | history
program/include/rcmail_string_replacer.php 54 ●●●●● patch | view | raw | blame | history
program/lib/Roundcube/rcube_output.php 123 ●●●●● patch | view | raw | blame | history
program/lib/Roundcube/rcube_string_replacer.php 8 ●●●● patch | view | raw | blame | history
program/lib/Roundcube/rcube_utils.php 53 ●●●●● patch | view | raw | blame | history
program/steps/mail/func.inc 2 ●●● patch | view | raw | blame | history
program/include/bc.php
@@ -31,7 +31,7 @@
define('RCUBE_INPUT_POST', rcube_utils::INPUT_POST);
define('RCUBE_INPUT_GPC',  rcube_utils::INPUT_GPC);
define('JS_OBJECT_NAME',   rcmail::JS_OBJECT_NAME);
define('JS_OBJECT_NAME',   rcmail_output::JS_OBJECT_NAME);
define('RCMAIL_CHARSET',   RCUBE_CHARSET);
function get_table_name($table)
@@ -126,7 +126,7 @@
function rcmail_get_edit_field($col, $value, $attrib, $type='text')
{
  return rcube_utils::get_edit_field($col, $value, $attrib, $type);
  return rcube_output::get_edit_field($col, $value, $attrib, $type);
}
function rcmail_mod_css_styles($source, $container_id, $allow_remote=false)
program/include/iniset.php
@@ -72,8 +72,26 @@
// include Roundcube Framework
require_once 'Roundcube/bootstrap.php';
// backward compatybility (to be removed)
require_once INSTALL_PATH . 'program/include/rcmail.php';
// register autoloader for rcmail app classes
spl_autoload_register('rcmail_autoload');
// backward compatybility (to be removed)
require_once INSTALL_PATH . 'program/include/bc.php';
/**
 * PHP5 autoloader routine for dynamic class loading
 */
function rcmail_autoload($classname)
{
    if (strpos($classname, 'rcmail') === 0) {
        $filepath = INSTALL_PATH . "program/include/$classname.php";
        if (is_readable($filepath)) {
            include_once $filepath;
            return true;
        }
    }
    return false;
}
program/include/rcmail.php
@@ -56,8 +56,6 @@
  private $action_map = array();
  const JS_OBJECT_NAME = 'rcmail';
  const ERROR_STORAGE          = -2;
  const ERROR_INVALID_REQUEST  = 1;
  const ERROR_INVALID_HOST     = 2;
@@ -321,17 +319,17 @@
  /**
   * Init output object for GUI and add common scripts.
   * This will instantiate a rcube_output_html object and set
   * This will instantiate a rcmail_output_html object and set
   * environment vars according to the current session and configuration
   *
   * @param boolean True if this request is loaded in a (i)frame
   * @return rcube_output_html Reference to HTML output object
   * @return rcube_output Reference to HTML output object
   */
  public function load_gui($framed = false)
  {
    // init output page
    if (!($this->output instanceof rcube_output_html))
      $this->output = new rcube_output_html($this->task, $framed);
    if (!($this->output instanceof rcmail_output_html))
      $this->output = new rcmail_output_html($this->task, $framed);
    // set refresh interval
    $this->output->set_env('refresh_interval', $this->config->get('refresh_interval', 0));
@@ -357,12 +355,12 @@
  /**
   * Create an output object for JSON responses
   *
   * @return rcube_output_json Reference to JSON output object
   * @return rcube_output Reference to JSON output object
   */
  public function json_init()
  {
    if (!($this->output instanceof rcube_output_json))
      $this->output = new rcube_output_json($this->task);
    if (!($this->output instanceof rcmail_output_json))
      $this->output = new rcmail_output_json($this->task);
    return $this->output;
  }
@@ -1566,7 +1564,7 @@
            $html_name = $this->Q($foldername) . ($unread ? html::span('unreadcount', sprintf($attrib['unreadwrap'], $unread)) : '');
            $link_attrib = $folder['virtual'] ? array() : array(
                'href' => $this->url(array('_mbox' => $folder['id'])),
                'onclick' => sprintf("return %s.command('list','%s',this)", rcmail::JS_OBJECT_NAME, $js_name),
                'onclick' => sprintf("return %s.command('list','%s',this)", rcmail_output::JS_OBJECT_NAME, $js_name),
                'rel' => $folder['id'],
                'title' => $title,
            );
@@ -1579,7 +1577,7 @@
                (!empty($folder['folders']) ? html::div(array(
                    'class' => ($is_collapsed ? 'collapsed' : 'expanded'),
                    'style' => "position:absolute",
                    'onclick' => sprintf("%s.command('collapse-folder', '%s')", rcmail::JS_OBJECT_NAME, $js_name)
                    'onclick' => sprintf("%s.command('collapse-folder', '%s')", rcmail_output::JS_OBJECT_NAME, $js_name)
                ), ' ') : ''));
            $jslist[$folder_id] = array(
program/include/rcmail_output.php
New file
@@ -0,0 +1,120 @@
<?php
/*
 +-----------------------------------------------------------------------+
 | program/include/rcmail_output.php                                     |
 |                                                                       |
 | This file is part of the Roundcube PHP suite                          |
 | Copyright (C) 2005-2012 The Roundcube Dev Team                        |
 |                                                                       |
 | Licensed under the GNU General Public License version 3 or            |
 | any later version with exceptions for skins & plugins.                |
 | See the README file for a full license statement.                     |
 | CONTENTS:                                                             |
 |   Abstract class for output generation                                |
 |                                                                       |
 +-----------------------------------------------------------------------+
 | Author: Thomas Bruederli <roundcube@gmail.com>                        |
 | Author: Aleksander Machniak <alec@alec.pl>                            |
 +-----------------------------------------------------------------------+
*/
/**
 * Class for output generation
 *
 * @package    Core
 * @subpackage View
 */
abstract class rcmail_output extends rcube_output
{
    const JS_OBJECT_NAME = 'rcmail';
    public $type = 'html';
    public $ajax_call = false;
    public $framed = false;
    protected $pagetitle = '';
    protected $object_handlers = array();
    /**
     * Object constructor
     */
    public function __construct($task = null, $framed = false)
    {
        parent::__construct();
    }
    /**
     * Setter for page title
     *
     * @param string $title Page title
     */
    public function set_pagetitle($title)
    {
        $this->pagetitle = $title;
    }
    /**
     * Getter for the current skin path property
     */
    public function get_skin_path()
    {
        return $this->config->get('skin_path');
    }
    /**
     * Delete all stored env variables and commands
     */
    public function reset()
    {
        parent::reset();
        $this->object_handlers = array();
        $this->pagetitle = '';
    }
    /**
     * Call a client method
     *
     * @param string Method to call
     * @param ... Additional arguments
     */
    abstract function command();
    /**
     * Add a localized label to the client environment
     */
    abstract function add_label();
    /**
     * Register a template object handler
     *
     * @param  string Object name
     * @param  string Function name to call
     * @return void
     */
    public function add_handler($obj, $func)
    {
        $this->object_handlers[$obj] = $func;
    }
    /**
     * Register a list of template object handlers
     *
     * @param  array Hash array with object=>handler pairs
     * @return void
     */
    public function add_handlers($arr)
    {
        $this->object_handlers = array_merge($this->object_handlers, $arr);
    }
}
program/include/rcmail_output_html.php
File was renamed from program/lib/Roundcube/rcube_output_html.php
@@ -2,7 +2,7 @@
/*
 +-----------------------------------------------------------------------+
 | program/include/rcubeoutput_html.php                                  |
 | program/include/rcmail_output_html.php                                |
 |                                                                       |
 | This file is part of the Roundcube Webmail client                     |
 | Copyright (C) 2006-2012, The Roundcube Dev Team                       |
@@ -23,10 +23,10 @@
/**
 * Class to create HTML page output using a skin template
 *
 * @package    Framework
 * @package    Core
 * @subpackage View
 */
class rcube_output_html extends rcube_output
class rcmail_output_html extends rcmail_output
{
    public $type = 'html';
@@ -82,10 +82,10 @@
          $this->set_env('extwin', 1);
        // add common javascripts
        $this->add_script('var '.rcmail::JS_OBJECT_NAME.' = new rcube_webmail();', 'head_top');
        $this->add_script('var '.self::JS_OBJECT_NAME.' = new rcube_webmail();', 'head_top');
        // don't wait for page onload. Call init at the bottom of the page (delayed)
        $this->add_script(rcmail::JS_OBJECT_NAME.'.init();', 'docready');
        $this->add_script(self::JS_OBJECT_NAME.'.init();', 'docready');
        $this->scripts_path = 'program/js/';
        $this->include_script('jquery.min.js');
@@ -240,7 +240,7 @@
     */
    public function add_gui_object($obj, $id)
    {
        $this->add_script(rcmail::JS_OBJECT_NAME.".gui_object('$obj', '$id');");
        $this->add_script(self::JS_OBJECT_NAME.".gui_object('$obj', '$id');");
    }
@@ -536,7 +536,7 @@
    {
        $out = '';
        if (!$this->framed && !empty($this->js_env)) {
            $out .= rcmail::JS_OBJECT_NAME . '.set_env('.self::json_serialize($this->js_env).");\n";
            $out .= self::JS_OBJECT_NAME . '.set_env('.self::json_serialize($this->js_env).");\n";
        }
        if (!empty($this->js_labels)) {
            $this->command('add_label', $this->js_labels);
@@ -549,7 +549,7 @@
            $parent = $this->framed || preg_match('/^parent\./', $method);
            $out .= sprintf(
                "%s.%s(%s);\n",
                ($parent ? 'if(window.parent && parent.'.rcmail::JS_OBJECT_NAME.') parent.' : '') . rcmail::JS_OBJECT_NAME,
                ($parent ? 'if(window.parent && parent.'.self::JS_OBJECT_NAME.') parent.' : '') . self::JS_OBJECT_NAME,
                preg_replace('/^parent\./', '', $method),
                implode(',', $args)
            );
@@ -1079,7 +1079,7 @@
        if ($attrib['command']) {
            $this->add_script(sprintf(
                "%s.register_button('%s', '%s', '%s', '%s', '%s', '%s');",
                rcmail::JS_OBJECT_NAME,
                self::JS_OBJECT_NAME,
                $command,
                $attrib['id'],
                $attrib['type'],
@@ -1091,7 +1091,7 @@
            // make valid href to specific buttons
            if (in_array($attrib['command'], rcmail::$main_tasks)) {
                $attrib['href']    = $this->app->url(array('task' => $attrib['command']));
                $attrib['onclick'] = sprintf("return %s.command('switch-task','%s',this,event)", rcmail::JS_OBJECT_NAME, $attrib['command']);
                $attrib['onclick'] = sprintf("return %s.command('switch-task','%s',this,event)", self::JS_OBJECT_NAME, $attrib['command']);
            }
            else if ($attrib['task'] && in_array($attrib['task'], rcmail::$main_tasks)) {
                $attrib['href'] = $this->app->url(array('action' => $attrib['command'], 'task' => $attrib['task']));
@@ -1115,7 +1115,7 @@
        else if ($command && !$attrib['onclick']) {
            $attrib['onclick'] = sprintf(
                "return %s.command('%s','%s',this,event)",
                rcmail::JS_OBJECT_NAME,
                self::JS_OBJECT_NAME,
                $command,
                $attrib['prop']
            );
@@ -1648,7 +1648,7 @@
        if (empty($attrib['form'])) {
            $out = $this->form_tag(array(
                'name' => "rcmqsearchform",
                'onsubmit' => rcmail::JS_OBJECT_NAME . ".command('search'); return false",
                'onsubmit' => self::JS_OBJECT_NAME . ".command('search'); return false",
                'style' => "display:inline"),
                $out);
        }
program/include/rcmail_output_json.php
File was renamed from program/lib/Roundcube/rcube_output_json.php
@@ -2,7 +2,7 @@
/*
 +-----------------------------------------------------------------------+
 | program/include/rcube_output_json.php                                 |
 | program/include/rc,aiö_output_json.php                                |
 |                                                                       |
 | This file is part of the Roundcube Webmail client                     |
 | Copyright (C) 2008-2012, The Roundcube Dev Team                       |
@@ -23,10 +23,10 @@
/**
 * View class to produce JSON responses
 *
 * @package    Framework
 * @package    Core
 * @subpackage View
 */
class rcube_output_json extends rcube_output
class rcmail_output_json extends rcmail_output
{
    protected $texts = array();
    protected $commands = array();
@@ -158,7 +158,7 @@
    {
        $location = $this->app->url($p);
        $this->remote_response(sprintf("window.setTimeout(function(){ %s.redirect('%s',true); }, %d);",
            rcmail::JS_OBJECT_NAME, $location, $delay));
            self::JS_OBJECT_NAME, $location, $delay));
        exit;
    }
program/include/rcmail_string_replacer.php
New file
@@ -0,0 +1,54 @@
<?php
/*
 +-----------------------------------------------------------------------+
 | program/include/rcmail_string_replacer.php                            |
 |                                                                       |
 | This file is part of the Roundcube Webmail client                     |
 | Copyright (C) 2012, The Roundcube Dev Team                            |
 |                                                                       |
 | Licensed under the GNU General Public License version 3 or            |
 | any later version with exceptions for skins & plugins.                |
 | See the README file for a full license statement.                     |
 |                                                                       |
 | PURPOSE:                                                              |
 |   Turn URLs and email addresses into clickable links                  |
 |                                                                       |
 +-----------------------------------------------------------------------+
 | Author: Thomas Bruederli <roundcube@gmail.com>                        |
 +-----------------------------------------------------------------------+
*/
/**
 * Helper class for turning URLs and email addresses in plaintext content
 * into clickable links.
 *
 * @package    Core
 * @subpackage Utils
 */
class rcmail_string_replacer extends rcube_string_replacer
{
    /**
     * 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) : '';
    }
}
program/lib/Roundcube/rcube_output.php
@@ -28,22 +28,17 @@
abstract class rcube_output
{
    public $browser;
    public $type = 'html';
    public $ajax_call = false;
    public $framed = false;
    protected $app;
    protected $config;
    protected $charset = RCUBE_CHARSET;
    protected $charset = RCMAIL_CHARSET;
    protected $env = array();
    protected $pagetitle = '';
    protected $object_handlers = array();
    /**
     * Object constructor
     */
    public function __construct($task = null, $framed = false)
    public function __construct()
    {
        $this->app     = rcube::get_instance();
        $this->config  = $this->app->config;
@@ -61,16 +56,6 @@
            return $this->env;
        return null;
    }
    /**
     * Setter for page title
     *
     * @param string $title Page title
     */
    public function set_pagetitle($title)
    {
        $this->pagetitle = $title;
    }
@@ -94,15 +79,6 @@
    public function get_charset()
    {
        return $this->charset;
    }
    /**
     * Getter for the current skin path property
     */
    public function get_skin_path()
    {
        return $this->config->get('skin_path');
    }
@@ -137,24 +113,7 @@
    public function reset()
    {
        $this->env = array();
        $this->object_handlers = array();
        $this->pagetitle = '';
    }
    /**
     * Call a client method
     *
     * @param string Method to call
     * @param ... Additional arguments
     */
    abstract function command();
    /**
     * Add a localized label to the client environment
     */
    abstract function add_label();
    /**
@@ -182,31 +141,6 @@
     * Send output to the client.
     */
    abstract function send();
    /**
     * Register a template object handler
     *
     * @param  string Object name
     * @param  string Function name to call
     * @return void
     */
    public function add_handler($obj, $func)
    {
        $this->object_handlers[$obj] = $func;
    }
    /**
     * Register a list of template object handlers
     *
     * @param  array Hash array with object=>handler pairs
     * @return void
     */
    public function add_handlers($arr)
    {
        $this->object_handlers = array_merge($this->object_handlers, $arr);
    }
    /**
@@ -266,6 +200,59 @@
    /**
     * Create an edit field for inclusion on a form
     *
     * @param string col field name
     * @param string value field value
     * @param array attrib HTML element attributes for field
     * @param string type HTML element type (default 'text')
     *
     * @return string HTML field definition
     */
    public static function get_edit_field($col, $value, $attrib, $type = 'text')
    {
        static $colcounts = array();
        $fname = '_'.$col;
        $attrib['name']  = $fname . ($attrib['array'] ? '[]' : '');
        $attrib['class'] = trim($attrib['class'] . ' ff_' . $col);
        if ($type == 'checkbox') {
            $attrib['value'] = '1';
            $input = new html_checkbox($attrib);
        }
        else if ($type == 'textarea') {
            $attrib['cols'] = $attrib['size'];
            $input = new html_textarea($attrib);
        }
        else if ($type == 'select') {
            $input = new html_select($attrib);
            $input->add('---', '');
            $input->add(array_values($attrib['options']), array_keys($attrib['options']));
        }
        else if ($attrib['type'] == 'password') {
            $input = new html_passwordfield($attrib);
        }
        else {
            if ($attrib['type'] != 'text' && $attrib['type'] != 'hidden') {
                $attrib['type'] = 'text';
            }
            $input = new html_inputfield($attrib);
        }
        // use value from post
        if (isset($_POST[$fname])) {
            $postvalue = rcube_utils::get_input_value($fname, rcube_utils::INPUT_POST, true);
            $value = $attrib['array'] ? $postvalue[intval($colcounts[$col]++)] : $postvalue;
        }
        $out = $input->show($value);
        return $out;
    }
    /**
     * Convert a variable into a javascript object notation
     *
     * @param mixed Input value
program/lib/Roundcube/rcube_string_replacer.php
@@ -5,7 +5,7 @@
 | program/include/rcube_string_replacer.php                             |
 |                                                                       |
 | This file is part of the Roundcube Webmail client                     |
 | Copyright (C) 2009, The Roundcube Dev Team                            |
 | Copyright (C) 2009-2012, The Roundcube Dev Team                       |
 |                                                                       |
 | Licensed under the GNU General Public License version 3 or            |
 | any later version with exceptions for skins & plugins.                |
@@ -113,11 +113,7 @@
  {
    $href   = $matches[1];
    $suffix = $this->parse_url_brackets($href);
    $i = $this->add(html::a(array(
        'href' => 'mailto:' . $href,
        'onclick' => "return ".rcmail::JS_OBJECT_NAME.".command('compose','".rcube::JQ($href)."',this)",
      ), rcmail::Q($href)) . $suffix);
    $i = $this->add(html::a('mailto:' . $href, rcube::Q($href)) . $suffix);
    return $i >= 0 ? $this->get_replacement($i) : '';
  }
program/lib/Roundcube/rcube_utils.php
@@ -434,59 +434,6 @@
    /**
     * Create an edit field for inclusion on a form
     *
     * @param string col field name
     * @param string value field value
     * @param array attrib HTML element attributes for field
     * @param string type HTML element type (default 'text')
     *
     * @return string HTML field definition
     */
    public static function get_edit_field($col, $value, $attrib, $type = 'text')
    {
        static $colcounts = array();
        $fname = '_'.$col;
        $attrib['name']  = $fname . ($attrib['array'] ? '[]' : '');
        $attrib['class'] = trim($attrib['class'] . ' ff_' . $col);
        if ($type == 'checkbox') {
            $attrib['value'] = '1';
            $input = new html_checkbox($attrib);
        }
        else if ($type == 'textarea') {
            $attrib['cols'] = $attrib['size'];
            $input = new html_textarea($attrib);
        }
        else if ($type == 'select') {
            $input = new html_select($attrib);
            $input->add('---', '');
            $input->add(array_values($attrib['options']), array_keys($attrib['options']));
        }
        else if ($attrib['type'] == 'password') {
            $input = new html_passwordfield($attrib);
        }
        else {
            if ($attrib['type'] != 'text' && $attrib['type'] != 'hidden') {
                $attrib['type'] = 'text';
            }
            $input = new html_inputfield($attrib);
        }
        // use value from post
        if (isset($_POST[$fname])) {
            $postvalue = self::get_input_value($fname, self::INPUT_POST, true);
            $value = $attrib['array'] ? $postvalue[intval($colcounts[$col]++)] : $postvalue;
        }
        $out = $input->show($value);
        return $out;
    }
    /**
     * Replace all css definitions with #container [def]
     * and remove css-inlined scripting
     *
program/steps/mail/func.inc
@@ -790,7 +790,7 @@
  global $RCMAIL;
  // make links and email-addresses clickable
  $replacer = new rcube_string_replacer;
  $replacer = new rcmail_string_replacer;
  // search for patterns like links and e-mail addresses and replace with tokens
  $body = $replacer->replace($body);