Thomas Bruederli
2012-11-17 be9aacaa5296dfca63fb3a01c2dc52538d1546aa
program/include/rcube_output_html.php
@@ -23,7 +23,8 @@
/**
 * Class to create HTML page output using a skin template
 *
 * @package View
 * @package    Framework
 * @subpackage View
 */
class rcube_output_html extends rcube_output
{
@@ -202,6 +203,31 @@
                break;
        }
        return $found;
    }
    /**
     * Find the given file in the current skin path stack
     *
     * @param string File name/path to resolve (starting with /)
     * @param string Reference to the base path of the matching skin
     * @param string Additional path to search in
     * @return mixed Relative path to the requested file or False if not found
     */
    public function get_skin_file($file, &$skin_path, $add_path = null)
    {
        $skin_paths = $this->skin_paths;
        if ($add_path)
            array_unshift($skin_paths, $add_path);
        foreach ($skin_paths as $skin_path) {
            $path = realpath($skin_path . $file);
            if (is_file($path)) {
                return $skin_path . $file;
            }
        }
        return false;
    }
@@ -401,13 +427,13 @@
            // apply skin search escalation list to plugin directory
            $plugin_skin_paths = array();
            foreach ($this->skin_paths as $skin_path) {
                $plugin_skin_paths[] = $this->app->plugins->dir . $plugin . '/' . $skin_path;
                $plugin_skin_paths[] = $this->app->plugins->url . $plugin . '/' . $skin_path;
            }
            // add fallback to default skin
            if (is_dir($this->app->plugins->dir . $plugin . '/skins/default')) {
                $skin_dir = $plugin . '/skins/default';
                $plugin_skin_paths[] = $this->app->plugins->dir . $skin_dir;
                $plugin_skin_paths[] = $this->app->plugins->url . $skin_dir;
            }
            // add plugin skin paths to search list
@@ -422,17 +448,20 @@
            // fallback to deprecated template names
            if (!is_readable($path) && $this->deprecated_templates[$realname]) {
                $path = "$skin_path/templates/" . $this->deprecated_templates[$realname] . ".html";
                rcube::raise_error(array(
                    'code' => 502, 'type' => 'php',
                    'file' => __FILE__, 'line' => __LINE__,
                    'message' => "Using deprecated template '" . $this->deprecated_templates[$realname]
                        . "' in $skin_path/templates. Please rename to '$realname'"),
                    true, false);
                if (is_readable($path)) {
                    rcube::raise_error(array(
                        'code' => 502, 'type' => 'php',
                        'file' => __FILE__, 'line' => __LINE__,
                        'message' => "Using deprecated template '" . $this->deprecated_templates[$realname]
                            . "' in $skin_path/templates. Please rename to '$realname'"),
                        true, false);
                }
            }
            if (is_readable($path)) {
                $this->config->set('skin_path', $skin_path);
                $this->base_path = $skin_path;
                $this->base_path = preg_replace('!plugins/\w+/!', '', $skin_path);  // set base_path to core skin directory (not plugin's skin)
                break;
            }
            else {
@@ -468,8 +497,6 @@
        // save some memory
        $output = $hook['content'];
        unset($hook['content']);
        $output = $this->parse_with_globals($this->fix_paths($output));
        // make sure all <form> tags have a valid request token
        $output = preg_replace_callback('/<form\s+([^>]+)>/Ui', array($this, 'alter_form_tag'), $output);
@@ -536,12 +563,17 @@
     * Make URLs starting with a slash point to skin directory
     *
     * @param  string Input string
     * @param  boolean True if URL should be resolved using the current skin path stack
     * @return string
     */
    public function abs_url($str)
    public function abs_url($str, $search_path = false)
    {
        if ($str[0] == '/')
        if ($str[0] == '/') {
            if ($search_path && ($file_url = $this->get_skin_file($str, $skin_path)))
                return $file_url;
            return $this->base_path . $str;
        }
        else
            return $str;
    }
@@ -825,15 +857,9 @@
            // include a file
            case 'include':
                $old_base_path = $this->base_path;
                $skin_paths = $this->skin_paths;
                if ($attrib['skin_path'])
                    array_unshift($skin_paths, $attrib['skin_path']);
                foreach ($skin_paths as $skin_path) {
                    $path = realpath($skin_path . $attrib['file']);
                    if (is_file($path)) {
                        $this->base_path = $skin_path;
                        break;
                    }
                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)) {
@@ -1065,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("%s.command('switch-task','%s',null,event); return false", rcmail::JS_OBJECT_NAME, $attrib['command']);
                $attrib['onclick'] = sprintf("return %s.command('switch-task','%s',this,event)", rcmail::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']));
@@ -1333,6 +1359,8 @@
            $output = substr_replace($output, $css, $pos, 0);
        }
        $output = $this->parse_with_globals($this->fix_paths($output));
        // trigger hook with final HTML content to be sent
        $hook = $this->app->plugins->exec_hook("send_page", array('content' => $output));
        if (!$hook['abort']) {
@@ -1350,21 +1378,25 @@
     * Returns iframe object, registers some related env variables
     *
     * @param array $attrib HTML attributes
     *
     * @param boolean $is_contentframe Register this iframe as the 'contentframe' gui object
     * @return string IFRAME element
     */
    public function frame($attrib)
    public function frame($attrib, $is_contentframe = false)
    {
        static $idcount = 0;
        if (!$attrib['id']) {
            $attrib['id'] = 'rcmframe';
            $attrib['id'] = 'rcmframe' . ++$idcount;
        }
        if (!$attrib['name']) {
            $attrib['name'] = $attrib['id'];
        }
        $attrib['name'] = $attrib['id'];
        $attrib['src'] = $attrib['src'] ? $this->abs_url($attrib['src'], true) : 'program/resources/blank.gif';
        $this->set_env('contentframe', $attrib['id']);
        $this->set_env('blankpage', $attrib['src'] ? $this->abs_url($attrib['src']) : 'program/resources/blank.gif');
        // register as 'contentframe' object
        if ($is_contentframe || $attrib['contentframe']) {
            $this->set_env('contentframe', $attrib['contentframe'] ? $attrib['contentframe'] : $attrib['name']);
            $this->set_env('blankpage', $attrib['src']);
        }
        return html::iframe($attrib);
    }
@@ -1493,7 +1525,6 @@
        $input_task   = new html_hiddenfield(array('name' => '_task', 'value' => 'login'));
        $input_action = new html_hiddenfield(array('name' => '_action', 'value' => 'login'));
        $input_tzone  = new html_hiddenfield(array('name' => '_timezone', 'id' => 'rcmlogintz', 'value' => '_default_'));
        $input_dst    = new html_hiddenfield(array('name' => '_dstactive', 'id' => 'rcmlogindst', 'value' => '_default_'));
        $input_url    = new html_hiddenfield(array('name' => '_url', 'id' => 'rcmloginurl', 'value' => $url));
        $input_user   = new html_inputfield(array('name' => '_user', 'id' => 'rcmloginuser')
            + $attrib + $user_attrib);
@@ -1545,7 +1576,6 @@
        $out  = $input_task->show();
        $out .= $input_action->show();
        $out .= $input_tzone->show();
        $out .= $input_dst->show();
        $out .= $input_url->show();
        $out .= $table->show();
@@ -1558,6 +1588,9 @@
            $out = $this->form_tag(array('name' => $form_name, 'method' => 'post'), $out);
        }
        // include script for timezone detection
        $this->include_script('jstz.min.js');
        return $out;
    }