| | |
| | | protected $footer = ''; |
| | | protected $body = ''; |
| | | protected $base_path = ''; |
| | | protected $assets_path; |
| | | protected $assets_dir = RCUBE_INSTALL_PATH; |
| | | protected $devel_mode = false; |
| | | |
| | | // deprecated names of templates used before 0.5 |
| | |
| | | $skin = $this->config->get('skin'); |
| | | $this->set_skin($skin); |
| | | $this->set_env('skin', $skin); |
| | | |
| | | $this->set_assets_path($this->config->get('assets_path'), $this->config->get('assets_dir')); |
| | | |
| | | if (!empty($_REQUEST['_extwin'])) |
| | | $this->set_env('extwin', 1); |
| | |
| | | if ($addtojs || isset($this->js_env[$name])) { |
| | | $this->js_env[$name] = $value; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Parse and set assets path |
| | | * |
| | | * @param string Assets path (relative or absolute URL) |
| | | */ |
| | | public function set_assets_path($path, $fs_dir = null) |
| | | { |
| | | if (empty($path)) { |
| | | return; |
| | | } |
| | | |
| | | $path = rtrim($path, '/') . '/'; |
| | | |
| | | // handle relative assets path |
| | | if (!preg_match('|^https?://|', $path) && $path[0] != '/') { |
| | | // save the path to search for asset files later |
| | | $this->assets_dir = $path; |
| | | |
| | | $base = preg_replace('/[?#&].*$/', '', $_SERVER['REQUEST_URI']); |
| | | $base = rtrim($base, '/'); |
| | | |
| | | // remove url token if exists |
| | | if ($len = intval($this->config->get('use_secure_urls'))) { |
| | | $_base = explode('/', $base); |
| | | $last = count($_base) - 1; |
| | | $length = $len > 1 ? $len : 16; // as in rcube::get_secure_url_token() |
| | | |
| | | // we can't use real token here because it |
| | | // does not exists in unauthenticated state, |
| | | // hope this will not produce false-positive matches |
| | | if ($last > -1 && preg_match('/^[a-f0-9]{' . $length . '}$/', $_base[$last])) { |
| | | $path = '../' . $path; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // set filesystem path for assets |
| | | if ($fs_dir) { |
| | | if ($fs_dir[0] != '/') { |
| | | $fs_dir = realpath(RCUBE_INSTALL_PATH . $fs_dir); |
| | | } |
| | | // ensure the path ends with a slash |
| | | $this->assets_dir = rtrim($fs_dir, '/') . '/'; |
| | | } |
| | | |
| | | $this->assets_path = $path; |
| | | $this->set_env('assets_path', $path); |
| | | } |
| | | |
| | | /** |
| | |
| | | * @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 = null, $add_path = null) |
| | |
| | | } |
| | | |
| | | foreach ($skin_paths as $skin_path) { |
| | | $path = realpath($skin_path . $file); |
| | | if (is_file($path)) { |
| | | $path = realpath(RCUBE_INSTALL_PATH . $skin_path . $file); |
| | | |
| | | if ($path && is_file($path)) { |
| | | return $skin_path . $file; |
| | | } |
| | | |
| | | if ($this->assets_dir != RCUBE_INSTALL_PATH) { |
| | | $path = realpath($this->assets_dir . $skin_path . $file); |
| | | |
| | | if ($path && is_file($path)) { |
| | | return $skin_path . $file; |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | /** |
| | | * Redirect to a certain url |
| | | * |
| | | * @param mixed $p Either a string with the action or url parameters as key-value pairs |
| | | * @param int $delay Delay in seconds |
| | | * @param mixed $p Either a string with the action or url parameters as key-value pairs |
| | | * @param int $delay Delay in seconds |
| | | * @param bool $secure Redirect to secure location (see rcmail::url()) |
| | | */ |
| | | public function redirect($p = array(), $delay = 1) |
| | | public function redirect($p = array(), $delay = 1, $secure = false) |
| | | { |
| | | if ($this->env['extwin']) |
| | | $p['extwin'] = 1; |
| | | $location = $this->app->url($p); |
| | | $location = $this->app->url($p, false, false, $secure); |
| | | header('Location: ' . $location); |
| | | exit; |
| | | } |
| | |
| | | { |
| | | $plugin = false; |
| | | $realname = $name; |
| | | $plugin_skin_paths = array(); |
| | | |
| | | $this->template_name = $realname; |
| | | |
| | | $temp = explode('.', $name, 2); |
| | |
| | | $skin_dir = $plugin . '/skins/' . $this->config->get('skin'); |
| | | |
| | | // 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->url . $plugin . '/' . $skin_path; |
| | | } |
| | |
| | | $plugin_skin_paths[] = $this->app->plugins->url . $skin_dir; |
| | | } |
| | | |
| | | // add plugin skin paths to search list |
| | | // prepend plugin skin paths to search list |
| | | $this->skin_paths = array_merge($plugin_skin_paths, $this->skin_paths); |
| | | } |
| | | |
| | | // find skin template |
| | | $path = false; |
| | | foreach ($this->skin_paths as $skin_path) { |
| | | $path = "$skin_path/templates/$name.html"; |
| | | $path = RCUBE_INSTALL_PATH . "$skin_path/templates/$name.html"; |
| | | |
| | | // fallback to deprecated template names |
| | | if (!is_readable($path) && $this->deprecated_templates[$realname]) { |
| | | $path = "$skin_path/templates/" . $this->deprecated_templates[$realname] . ".html"; |
| | | $path = RCUBE_INSTALL_PATH . "$skin_path/templates/" . $this->deprecated_templates[$realname] . ".html"; |
| | | |
| | | if (is_readable($path)) { |
| | | rcube::raise_error(array( |
| | |
| | | // read template file |
| | | if (!$path || ($templ = @file_get_contents($path)) === false) { |
| | | rcube::raise_error(array( |
| | | 'code' => 501, |
| | | 'code' => 404, |
| | | 'type' => 'php', |
| | | 'line' => __LINE__, |
| | | 'file' => __FILE__, |
| | | 'message' => 'Error loading template for '.$realname |
| | | ), true, $write); |
| | | |
| | | $this->skin_paths = array_slice($this->skin_paths, count($plugin_skin_paths)); |
| | | return false; |
| | | } |
| | | |
| | |
| | | // make sure all <form> tags have a valid request token |
| | | $output = preg_replace_callback('/<form\s+([^>]+)>/Ui', array($this, 'alter_form_tag'), $output); |
| | | $this->footer = preg_replace_callback('/<form\s+([^>]+)>/Ui', array($this, 'alter_form_tag'), $this->footer); |
| | | |
| | | // remove plugin skin paths from current context |
| | | $this->skin_paths = array_slice($this->skin_paths, count($plugin_skin_paths)); |
| | | |
| | | if (!$write) { |
| | | return $output; |
| | |
| | | exit; |
| | | } |
| | | |
| | | /** |
| | | * Modify path by adding URL prefix if configured |
| | | */ |
| | | public function asset_url($path) |
| | | { |
| | | // iframe content can't be in a different domain |
| | | // @TODO: check if assests are on a different domain |
| | | |
| | | if (!$this->assets_path || in_array($path[0], array('?', '/', '.')) || strpos($path, '://')) { |
| | | return $path; |
| | | } |
| | | |
| | | return $this->assets_path . $path; |
| | | } |
| | | |
| | | |
| | | /***** Template parsing methods *****/ |
| | | |
| | |
| | | } |
| | | |
| | | /** |
| | | * Callback function for preg_replace_callback in write() |
| | | * Callback function for preg_replace_callback in fix_paths() |
| | | * |
| | | * @return string Parsed string |
| | | */ |
| | |
| | | } |
| | | |
| | | /** |
| | | * Correct paths of asset files according to assets_path |
| | | */ |
| | | protected function fix_assets_paths($output) |
| | | { |
| | | return preg_replace_callback( |
| | | '!(src|href|background)=(["\']?)([a-z0-9/_.?=-]+)(["\'\s>])!i', |
| | | array($this, 'assets_callback'), $output); |
| | | } |
| | | |
| | | /** |
| | | * Callback function for preg_replace_callback in fix_assets_paths() |
| | | * |
| | | * @return string Parsed string |
| | | */ |
| | | protected function assets_callback($matches) |
| | | { |
| | | $file = $this->asset_url($matches[3]); |
| | | |
| | | return $matches[1] . '=' . $matches[2] . $file . $matches[4]; |
| | | } |
| | | |
| | | /** |
| | | * Modify file by adding mtime indicator |
| | | */ |
| | | protected function file_mod($file) |
| | |
| | | // use minified file if exists (not in development mode) |
| | | if (!$this->devel_mode && !preg_match('/\.min\.' . $ext . '$/', $file)) { |
| | | $minified_file = substr($file, 0, strlen($ext) * -1) . 'min.' . $ext; |
| | | if ($fs = @filemtime($minified_file)) { |
| | | if ($fs = @filemtime($this->assets_dir . $minified_file)) { |
| | | return $minified_file . '?s=' . $fs; |
| | | } |
| | | } |
| | | |
| | | if ($fs = @filemtime($file)) { |
| | | if ($fs = @filemtime($this->assets_dir . $file)) { |
| | | $file .= '?s=' . $fs; |
| | | } |
| | | |
| | |
| | | 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); |
| | | $path = realpath(RCUBE_INSTALL_PATH . $path); |
| | | } |
| | | |
| | | if (is_readable($path)) { |
| | |
| | | |
| | | $output = $this->parse_with_globals($this->fix_paths($output)); |
| | | |
| | | if ($this->assets_path) { |
| | | $output = $this->fix_assets_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']) { |
| | |
| | | } |
| | | |
| | | $attrib['name'] = $attrib['id']; |
| | | $attrib['src'] = $attrib['src'] ? $this->abs_url($attrib['src'], true) : 'program/resources/blank.gif'; |
| | | $attrib['src'] = $attrib['src'] ? $this->abs_url($attrib['src'], true) : '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']); |
| | | $this->set_env('blankpage', $this->asset_url($attrib['src'])); |
| | | } |
| | | |
| | | return html::iframe($attrib); |
| | |
| | | { |
| | | $images = preg_split('/[\s\t\n,]+/', $attrib['images'], -1, PREG_SPLIT_NO_EMPTY); |
| | | $images = array_map(array($this, 'abs_url'), $images); |
| | | $images = array_map(array($this, 'asset_url'), $images); |
| | | |
| | | if (empty($images) || $this->app->task == 'logout') |
| | | if (empty($images) || $_REQUEST['_task'] == 'logout') { |
| | | return; |
| | | } |
| | | |
| | | $this->add_script('var images = ' . self::json_serialize($images) .'; |
| | | for (var i=0; i<images.length; i++) { |