| | |
| | | */ |
| | | public $action = ''; |
| | | public $comm_path = './'; |
| | | public $filename = ''; |
| | | |
| | | private $address_books = array(); |
| | | private $action_map = array(); |
| | |
| | | /** |
| | | * This implements the 'singleton' design pattern |
| | | * |
| | | * @param string Environment name to run (e.g. live, dev, test) |
| | | * @return rcmail The one and only instance |
| | | */ |
| | | static function get_instance() |
| | | static function get_instance($env = '') |
| | | { |
| | | if (!self::$instance || !is_a(self::$instance, 'rcmail')) { |
| | | self::$instance = new rcmail(); |
| | | self::$instance = new rcmail($env); |
| | | self::$instance->startup(); // init AFTER object was linked with self::$instance |
| | | } |
| | | |
| | |
| | | protected function startup() |
| | | { |
| | | $this->init(self::INIT_WITH_DB | self::INIT_WITH_PLUGINS); |
| | | |
| | | // set filename if not index.php |
| | | if (($basename = basename($_SERVER['SCRIPT_FILENAME'])) && $basename != 'index.php') |
| | | $this->filename = $basename; |
| | | |
| | | // start session |
| | | $this->session_init(); |
| | |
| | | setlocale(LC_ALL, $lang . '.utf8', $lang . '.UTF-8', 'en_US.utf8', 'en_US.UTF-8'); |
| | | |
| | | // workaround for http://bugs.php.net/bug.php?id=18556 |
| | | if (in_array($lang, array('tr_TR', 'ku', 'az_AZ'))) { |
| | | if (version_compare(PHP_VERSION, '5.5.0', '<') && in_array($lang, array('tr_TR', 'ku', 'az_AZ'))) { |
| | | setlocale(LC_CTYPE, 'en_US.utf8', 'en_US.UTF-8'); |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | if (!$contacts) { |
| | | // there's no default, just return |
| | | if ($default) { |
| | | return null; |
| | | } |
| | | |
| | | self::raise_error(array( |
| | | 'code' => 700, 'type' => 'php', |
| | | 'file' => __FILE__, 'line' => __LINE__, |
| | |
| | | } |
| | | |
| | | return $contacts; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Return identifier of the address book object |
| | | * |
| | | * @param rcube_addressbook Addressbook source object |
| | | * |
| | | * @return string Source identifier |
| | | */ |
| | | public function get_address_book_id($object) |
| | | { |
| | | foreach ($this->address_books as $index => $book) { |
| | | if ($book === $object) { |
| | | return $index; |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | $list[$id] = array( |
| | | 'id' => $id, |
| | | 'name' => html::quote($prop['name']), |
| | | 'groups' => is_array($prop['groups']), |
| | | 'groups' => !empty($prop['groups']) || !empty($prop['group_filters']), |
| | | 'readonly' => !$prop['writable'], |
| | | 'hidden' => $prop['hidden'], |
| | | 'autocomplete' => in_array($id, $autocomplete) |
| | |
| | | } |
| | | |
| | | return $list; |
| | | } |
| | | |
| | | /** |
| | | * Getter for compose responses. |
| | | * These are stored in local config and user preferences. |
| | | * |
| | | * @param boolean True to sort the list alphabetically |
| | | * @param boolean True if only this user's responses shall be listed |
| | | * @return array List of the current user's stored responses |
| | | */ |
| | | public function get_compose_responses($sorted = false, $user_only = false) |
| | | { |
| | | $responses = array(); |
| | | |
| | | if (!$user_only) { |
| | | foreach ($this->config->get('compose_responses_static', array()) as $response) { |
| | | if (empty($response['key'])) |
| | | $response['key'] = substr(md5($response['name']), 0, 16); |
| | | $response['static'] = true; |
| | | $response['class'] = 'readonly'; |
| | | $k = $sorted ? '0000-' . strtolower($response['name']) : $response['key']; |
| | | $responses[$k] = $response; |
| | | } |
| | | } |
| | | |
| | | foreach ($this->config->get('compose_responses', array()) as $response) { |
| | | if (empty($response['key'])) |
| | | $response['key'] = substr(md5($response['name']), 0, 16); |
| | | $k = $sorted ? strtolower($response['name']) : $response['key']; |
| | | $responses[$k] = $response; |
| | | } |
| | | |
| | | // sort list by name |
| | | if ($sorted) { |
| | | ksort($responses, SORT_LOCALE_STRING); |
| | | } |
| | | |
| | | return array_values($responses); |
| | | } |
| | | |
| | | |
| | |
| | | $this->output->set_env('action', $this->action); |
| | | $this->output->set_env('comm_path', $this->comm_path); |
| | | $this->output->set_charset(RCUBE_CHARSET); |
| | | |
| | | if ($this->user && $this->user->ID) |
| | | $this->output->set_env('user_id', $this->user->get_hash()); |
| | | |
| | | // add some basic labels to client |
| | | $this->output->add_label('loading', 'servererror', 'requesttimedout', 'refreshing'); |
| | |
| | | $port = $config['default_port']; |
| | | } |
| | | |
| | | /* Modify username with domain if required |
| | | Inspired by Marco <P0L0_notspam_binware.org> |
| | | */ |
| | | // Check if we need to add domain |
| | | if (!empty($config['username_domain']) && strpos($username, '@') === false) { |
| | | if (is_array($config['username_domain']) && isset($config['username_domain'][$host])) |
| | | $username .= '@'.rcube_utils::parse_host($config['username_domain'][$host], $host); |
| | | else if (is_string($config['username_domain'])) |
| | | $username .= '@'.rcube_utils::parse_host($config['username_domain'], $host); |
| | | // Check if we need to add/force domain to username |
| | | if (!empty($config['username_domain'])) { |
| | | $domain = is_array($config['username_domain']) ? $config['username_domain'][$host] : $config['username_domain']; |
| | | |
| | | if ($domain = rcube_utils::parse_host((string)$domain, $host)) { |
| | | $pos = strpos($username, '@'); |
| | | |
| | | // force configured domains |
| | | if (!empty($config['username_domain_forced']) && $pos !== false) { |
| | | $username = substr($username, 0, $pos) . '@' . $domain; |
| | | } |
| | | // just add domain if not specified |
| | | else if ($pos === false) { |
| | | $username .= '@' . $domain; |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (!isset($config['login_lc'])) { |
| | |
| | | $p['_task'] = $task; |
| | | unset($p['task']); |
| | | |
| | | $url = './'; |
| | | $url = './' . $this->filename; |
| | | $delm = '?'; |
| | | foreach (array_reverse($p) as $key => $val) { |
| | | if ($val !== '' && $val !== null) { |
| | |
| | | foreach ($this->address_books as $book) { |
| | | if (is_object($book) && is_a($book, 'rcube_addressbook')) |
| | | $book->close(); |
| | | } |
| | | |
| | | // before closing the database connection, write session data |
| | | if ($_SERVER['REMOTE_ADDR'] && is_object($this->session)) { |
| | | $this->session->write_close(); |
| | | } |
| | | |
| | | // write performance stats to logs/console |
| | |
| | | /** |
| | | * Write login data (name, ID, IP address) to the 'userlogins' log file. |
| | | */ |
| | | public function log_login() |
| | | public function log_login($user = null, $failed_login = false, $error_code = 0) |
| | | { |
| | | if (!$this->config->get('log_logins')) { |
| | | return; |
| | | } |
| | | |
| | | $user_name = $this->get_user_name(); |
| | | $user_id = $this->get_user_id(); |
| | | // failed login |
| | | if ($failed_login) { |
| | | $message = sprintf('Failed login for %s from %s in session %s (error: %d)', |
| | | $user, rcube_utils::remote_ip(), session_id(), $error_code); |
| | | } |
| | | // successful login |
| | | else { |
| | | $user_name = $this->get_user_name(); |
| | | $user_id = $this->get_user_id(); |
| | | |
| | | if (!$user_id) { |
| | | return; |
| | | if (!$user_id) { |
| | | return; |
| | | } |
| | | |
| | | $message = sprintf('Successful login for %s (ID: %d) from %s in session %s', |
| | | $user_name, $user_id, rcube_utils::remote_ip(), session_id()); |
| | | } |
| | | |
| | | self::write_log('userlogins', |
| | | sprintf('Successful login for %s (ID: %d) from %s in session %s', |
| | | $user_name, $user_id, rcube_utils::remote_ip(), session_id())); |
| | | // log login |
| | | self::write_log('userlogins', $message); |
| | | } |
| | | |
| | | |
| | |
| | | } |
| | | else { |
| | | $js_mailboxlist = array(); |
| | | $out = html::tag('ul', $attrib, $rcmail->render_folder_tree_html($a_mailboxes, $mbox_name, $js_mailboxlist, $attrib), html::$common_attrib); |
| | | $tree = $rcmail->render_folder_tree_html($a_mailboxes, $mbox_name, $js_mailboxlist, $attrib); |
| | | |
| | | $rcmail->output->include_script('treelist.js'); |
| | | $rcmail->output->add_gui_object('mailboxlist', $attrib['id']); |
| | | if ($type != 'js') { |
| | | $out = html::tag('ul', $attrib, $tree, html::$common_attrib); |
| | | |
| | | $rcmail->output->include_script('treelist.js'); |
| | | $rcmail->output->add_gui_object('mailboxlist', $attrib['id']); |
| | | $rcmail->output->set_env('unreadwrap', $attrib['unreadwrap']); |
| | | $rcmail->output->set_env('collapsed_folders', (string)$rcmail->config->get('collapsed_folders')); |
| | | } |
| | | |
| | | $rcmail->output->set_env('mailboxes', $js_mailboxlist); |
| | | $rcmail->output->set_env('unreadwrap', $attrib['unreadwrap']); |
| | | $rcmail->output->set_env('collapsed_folders', (string)$rcmail->config->get('collapsed_folders')); |
| | | |
| | | // we can't use object keys in javascript because they are unordered |
| | | // we need sorted folders list for folder-selector widget |
| | | $rcmail->output->set_env('mailboxes_list', array_keys($js_mailboxlist)); |
| | | } |
| | | |
| | | return $out; |
| | |
| | | $realnames = (bool)$attrib['realnames']; |
| | | $msgcounts = $this->storage->get_cache('messagecount'); |
| | | $collapsed = $this->config->get('collapsed_folders'); |
| | | $realnames = $this->config->get('show_real_foldernames'); |
| | | |
| | | $out = ''; |
| | | foreach ($arrFolders as $folder) { |
| | |
| | | $jslist[$folder['id']] = array( |
| | | 'id' => $folder['id'], |
| | | 'name' => $foldername, |
| | | 'virtual' => $folder['virtual'] |
| | | 'virtual' => $folder['virtual'], |
| | | ); |
| | | |
| | | if (!empty($folder_class)) { |
| | | $jslist[$folder['id']]['class'] = $folder_class; |
| | | } |
| | | |
| | | if (!empty($folder['folders'])) { |
| | | $out .= html::tag('ul', array('style' => ($is_collapsed ? "display:none;" : null)), |
| | |
| | | */ |
| | | public function localize_foldername($name, $with_path = true) |
| | | { |
| | | $realnames = $this->config->get('show_real_foldernames'); |
| | | |
| | | // try to localize path of the folder |
| | | if ($with_path) { |
| | | if ($with_path && !$realnames) { |
| | | $storage = $this->get_storage(); |
| | | $delimiter = $storage->get_hierarchy_delimiter(); |
| | | $path = explode($delimiter, $name); |
| | |
| | | } |
| | | } |
| | | |
| | | if ($folder_class = $this->folder_classname($name)) { |
| | | if (!$realnames && ($folder_class = $this->folder_classname($name))) { |
| | | return $this->gettext($folder_class); |
| | | } |
| | | else { |
| | | return rcube_charset::convert($name, 'UTF7-IMAP'); |
| | | } |
| | | |
| | | return rcube_charset::convert($name, 'UTF7-IMAP'); |
| | | } |
| | | |
| | | |
| | |
| | | |
| | | $rcmail->output->add_script('rcmail.set_quota('.rcube_output::json_serialize($quota).');', 'docready'); |
| | | |
| | | return html::span($attrib, ''); |
| | | return html::span($attrib, ' '); |
| | | } |
| | | |
| | | |
| | |
| | | public function upload_init() |
| | | { |
| | | // Enable upload progress bar |
| | | if (($seconds = $this->config->get('upload_progress')) && ini_get('apc.rfc1867')) { |
| | | $rfc1867 = filter_var(ini_get('apc.rfc1867'), FILTER_VALIDATE_BOOLEAN); |
| | | if ($rfc1867 && ($seconds = $this->config->get('upload_progress'))) { |
| | | if ($field_name = ini_get('apc.rfc1867_name')) { |
| | | $this->output->set_env('upload_progress_name', $field_name); |
| | | $this->output->set_env('upload_progress_time', (int) $seconds); |
| | |
| | | } |
| | | |
| | | $this->output->set_env('max_filesize', $max_filesize); |
| | | $max_filesize = self::show_bytes($max_filesize); |
| | | $max_filesize = $this->show_bytes($max_filesize); |
| | | $this->output->set_env('filesizeerror', $this->gettext(array( |
| | | 'name' => 'filesizeerror', 'vars' => array('size' => $max_filesize)))); |
| | | |