- Apply fixes fom trunk up to r5414
1 files added
29 files modified
| | |
| | | CHANGELOG Roundcube Webmail |
| | | =========================== |
| | | |
| | | - Add option to skip alternative email addresses in autocompletion |
| | | - Fix inconsistent behaviour of Compose button in Drafts folder, add Edit button for drafts |
| | | - Fix problem with parsing HTML message body with non-unicode characters (#1487813) |
| | | - Add option to define matching method for addressbook search (#1486564, #1487907) |
| | | - Make email recipients separator configurable |
| | | - Fix so folders with \Noinferiors attribute aren't listed in parent selector |
| | | - Fix handling of curly brackets in URLs (#1488168) |
| | |
| | | // available placeholders: {street}, {locality}, {zipcode}, {country}, {region} |
| | | $rcmail_config['address_template'] = '{street}<br/>{locality} {zipcode}<br/>{country} {region}'; |
| | | |
| | | // Matching mode for addressbook search (including autocompletion) |
| | | // 0 - partial (*abc*), default |
| | | // 1 - strict (abc) |
| | | // 2 - prefix (abc*) |
| | | // Note: For LDAP sources fuzzy_search must be enabled to use 'partial' or 'prefix' mode |
| | | $rcmail_config['addressbook_search_mode'] = 0; |
| | | |
| | | // ---------------------------------- |
| | | // USER PREFERENCES |
| | | // ---------------------------------- |
| | |
| | | // Enables spell checking before sending a message. |
| | | $rcmail_config['spellcheck_before_send'] = false; |
| | | |
| | | // Skip alternative email addresses in autocompletion (show one address per contact) |
| | | $rcmail_config['autocomplete_single'] = false; |
| | | |
| | | // end of config file |
| | |
| | | /** |
| | | * ACL plugin script |
| | | * |
| | | * @version 0.6.2 |
| | | * @version 0.6.3 |
| | | * @author Aleksander Machniak <alec@alec.pl> |
| | | */ |
| | | |
| | |
| | | /** |
| | | * Folders Access Control Lists Management (RFC4314, RFC2086) |
| | | * |
| | | * @version 0.6.2 |
| | | * @version 0.6.3 |
| | | * @author Aleksander Machniak <alec@alec.pl> |
| | | * |
| | | * |
| | |
| | | $users = array(); |
| | | |
| | | if ($this->init_ldap()) { |
| | | $this->ldap->set_pagesize((int)$this->rc->config->get('autocomplete_max', 15)); |
| | | $result = $this->ldap->search('*', $search); |
| | | $max = (int) $this->rc->config->get('autocomplete_max', 15); |
| | | $mode = (int) $this->rc->config->get('addressbook_search_mode'); |
| | | |
| | | $this->ldap->set_pagesize($max); |
| | | $result = $this->ldap->search('*', $search, $mode); |
| | | |
| | | foreach ($result->records as $record) { |
| | | $user = $record['uid']; |
New file |
| | |
| | | <?php |
| | | |
| | | $labels['basic'] = 'Attēlot paziņojumu pie jaunas vēstules saņemšanas'; |
| | | $labels['desktop'] = 'Attēlot darbvirsmas paziņojumu pie jaunas vēstules saņemšanas'; |
| | | $labels['sound'] = 'Atskaņot skaņas signālu pie jaunas vēstules saņemšanas'; |
| | | $labels['test'] = 'Test'; |
| | | $labels['title'] = 'Jauns E-pasts!'; |
| | | $labels['body'] = 'Jūs esat saņēmis jaunu e-pastu.'; |
| | | $labels['testbody'] = 'Šis ir testa paziņojums.'; |
| | | $labels['desktopdisabled'] = 'Darbvirsmas paziņojumi ir atslēgti Jūsu pārlūkprogrammā.'; |
| | | $labels['desktopunsupported'] = 'Jūsu pārlūkprogramma neatbalsta darbvirsmas paziņojumus.'; |
| | | |
| | | ?> |
| | |
| | | * |
| | | * @param array List of fields to search in |
| | | * @param string Search value |
| | | * @param int Matching mode: |
| | | * 0 - partial (*abc*), |
| | | * 1 - strict (=), |
| | | * 2 - prefix (abc*) |
| | | * @param boolean True if results are requested, False if count only |
| | | * @param boolean True to skip the count query (select only) |
| | | * @param array List of fields that cannot be empty |
| | | * @return object rcube_result_set List of contact records and 'count' value |
| | | */ |
| | | abstract function search($fields, $value, $strict=false, $select=true, $nocount=false, $required=array()); |
| | | abstract function search($fields, $value, $mode=0, $select=true, $nocount=false, $required=array()); |
| | | |
| | | /** |
| | | * Count number of available contacts in database |
| | |
| | | { |
| | | $out = array(); |
| | | foreach ($data as $c => $values) { |
| | | if (strpos($c, $col) === 0) { |
| | | if ($c === $col || strpos($c, $col.':') === 0) { |
| | | if ($flat) { |
| | | $out = array_merge($out, (array)$values); |
| | | } |
| | |
| | | * |
| | | * @param mixed $fields The field name of array of field names to search in |
| | | * @param mixed $value Search value (or array of values when $fields is array) |
| | | * @param boolean $strict True for strict (=), False for partial (LIKE) matching |
| | | * @param int $mode Matching mode: |
| | | * 0 - partial (*abc*), |
| | | * 1 - strict (=), |
| | | * 2 - prefix (abc*) |
| | | * @param boolean $select True if results are requested, False if count only |
| | | * @param boolean $nocount True to skip the count query (select only) |
| | | * @param array $required List of fields that cannot be empty |
| | | * |
| | | * @return object rcube_result_set Contact records and 'count' value |
| | | */ |
| | | function search($fields, $value, $strict=false, $select=true, $nocount=false, $required=array()) |
| | | function search($fields, $value, $mode=0, $select=true, $nocount=false, $required=array()) |
| | | { |
| | | if (!is_array($fields)) |
| | | $fields = array($fields); |
| | |
| | | $required = array($required); |
| | | |
| | | $where = $and_where = array(); |
| | | $mode = intval($mode); |
| | | |
| | | foreach ($fields as $idx => $col) { |
| | | // direct ID search |
| | |
| | | // fulltext search in all fields |
| | | else if ($col == '*') { |
| | | $words = array(); |
| | | foreach (explode(" ", self::normalize_string($value)) as $word) |
| | | foreach (explode(" ", self::normalize_string($value)) as $word) { |
| | | switch ($mode) { |
| | | case 1: // strict |
| | | $words[] = '(' . $this->db->ilike('words', $word.' %') |
| | | . ' OR ' . $this->db->ilike('words', '% '.$word.' %') |
| | | . ' OR ' . $this->db->ilike('words', '% '.$word) . ')'; |
| | | break; |
| | | case 2: // prefix |
| | | $words[] = '(' . $this->db->ilike('words', $word.'%') |
| | | . ' OR ' . $this->db->ilike('words', '% '.$word.'%') . ')'; |
| | | break; |
| | | default: // partial |
| | | $words[] = $this->db->ilike('words', '%'.$word.'%'); |
| | | } |
| | | } |
| | | $where[] = '(' . join(' AND ', $words) . ')'; |
| | | } |
| | | else { |
| | | $val = is_array($value) ? $value[$idx] : $value; |
| | | // table column |
| | | if (in_array($col, $this->table_cols)) { |
| | | if ($strict) { |
| | | switch ($mode) { |
| | | case 1: // strict |
| | | $where[] = $this->db->quoteIdentifier($col).' = '.$this->db->quote($val); |
| | | } |
| | | else { |
| | | break; |
| | | case 2: // prefix |
| | | $where[] = $this->db->ilike($col, $val.'%'); |
| | | break; |
| | | default: // partial |
| | | $where[] = $this->db->ilike($col, '%'.$val.'%'); |
| | | } |
| | | } |
| | | // vCard field |
| | | else { |
| | | if (in_array($col, $this->fulltext_cols)) { |
| | | foreach (explode(" ", self::normalize_string($val)) as $word) |
| | | foreach (explode(" ", self::normalize_string($val)) as $word) { |
| | | switch ($mode) { |
| | | case 1: // strict |
| | | $words[] = '(' . $this->db->ilike('words', $word.' %') |
| | | . ' OR ' . $this->db->ilike('words', '% '.$word.' %') |
| | | . ' OR ' . $this->db->ilike('words', '% '.$word) . ')'; |
| | | break; |
| | | case 2: // prefix |
| | | $words[] = '(' . $this->db->ilike('words', $word.'%') |
| | | . ' OR ' . $this->db->ilike('words', ' '.$word.'%') . ')'; |
| | | break; |
| | | default: // partial |
| | | $words[] = $this->db->ilike('words', '%'.$word.'%'); |
| | | } |
| | | } |
| | | $where[] = '(' . join(' AND ', $words) . ')'; |
| | | } |
| | | if (is_array($value)) |
| | |
| | | $search = $post_search[$colname]; |
| | | foreach ((array)$row[$col] as $value) { |
| | | // composite field, e.g. address |
| | | if (is_array($value)) { |
| | | $value = implode($value); |
| | | } |
| | | $value = mb_strtolower($value); |
| | | if (($strict && $value == $search) || (!$strict && strpos($value, $search) !== false)) { |
| | | $found[$colname] = true; |
| | | foreach ((array)$value as $val) { |
| | | $val = mb_strtolower($val); |
| | | switch ($mode) { |
| | | case 1: |
| | | $got = ($val == $search); |
| | | break; |
| | | case 2: |
| | | $got = ($search == substr($val, 0, strlen($search))); |
| | | break; |
| | | default: |
| | | $got = (strpos($val, $search) !== false); |
| | | break; |
| | | } |
| | | |
| | | if ($got) { |
| | | $found[$colname] = true; |
| | | break 2; |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | */ |
| | | function get_mailbox_name() |
| | | { |
| | | return $this->conn->connected() ? $this->mailbox : ''; |
| | | return $this->mailbox; |
| | | } |
| | | |
| | | |
| | |
| | | * |
| | | * @param mixed $fields The field name of array of field names to search in |
| | | * @param mixed $value Search value (or array of values when $fields is array) |
| | | * @param boolean $strict True for strict, False for partial (fuzzy) matching |
| | | * @param int $mode Matching mode: |
| | | * 0 - partial (*abc*), |
| | | * 1 - strict (=), |
| | | * 2 - prefix (abc*) |
| | | * @param boolean $select True if results are requested, False if count only |
| | | * @param boolean $nocount (Not used) |
| | | * @param array $required List of fields that cannot be empty |
| | | * |
| | | * @return array Indexed list of contact records and 'count' value |
| | | */ |
| | | function search($fields, $value, $strict=false, $select=true, $nocount=false, $required=array()) |
| | | function search($fields, $value, $mode=0, $select=true, $nocount=false, $required=array()) |
| | | { |
| | | $mode = intval($mode); |
| | | |
| | | // special treatment for ID-based search |
| | | if ($fields == 'ID' || $fields == $this->primary_key) |
| | | { |
| | |
| | | array_values($this->fieldmap), 0, (int)$this->prop['sizelimit'], (int)$this->prop['timelimit']); |
| | | |
| | | // get all entries of this page and post-filter those that really match the query |
| | | $search = mb_strtolower($value); |
| | | $this->result = new rcube_result_set(0); |
| | | $entries = ldap_get_entries($this->conn, $this->ldap_result); |
| | | |
| | | for ($i = 0; $i < $entries['count']; $i++) { |
| | | $rec = $this->_ldap2result($entries[$i]); |
| | | if (stripos($rec['name'] . $rec['email'], $value) !== false) { |
| | | foreach (array('email', 'name') as $f) { |
| | | $val = mb_strtolower($rec[$f]); |
| | | switch ($mode) { |
| | | case 1: |
| | | $got = ($val == $search); |
| | | break; |
| | | case 2: |
| | | $got = ($search == substr($val, 0, strlen($search))); |
| | | break; |
| | | default: |
| | | $got = (strpos($val, $search) !== false); |
| | | break; |
| | | } |
| | | |
| | | if ($got) { |
| | | $this->result->add($rec); |
| | | $this->result->count++; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | // use AND operator for advanced searches |
| | | $filter = is_array($value) ? '(&' : '(|'; |
| | | $wc = !$strict && $this->prop['fuzzy_search'] ? '*' : ''; |
| | | // set wildcards |
| | | $wp = $ws = ''; |
| | | if (!empty($this->prop['fuzzy_search']) && $mode != 1) { |
| | | $ws = '*'; |
| | | if (!$mode) { |
| | | $wp = '*'; |
| | | } |
| | | } |
| | | |
| | | if ($fields == '*') |
| | | { |
| | |
| | | if (is_array($this->prop['search_fields'])) |
| | | { |
| | | foreach ($this->prop['search_fields'] as $field) { |
| | | $filter .= "($field=$wc" . $this->_quote_string($value) . "$wc)"; |
| | | $filter .= "($field=$wp" . $this->_quote_string($value) . "$ws)"; |
| | | } |
| | | } |
| | | } |
| | |
| | | foreach ((array)$fields as $idx => $field) { |
| | | $val = is_array($value) ? $value[$idx] : $value; |
| | | if ($f = $this->_map_field($field)) { |
| | | $filter .= "($f=$wc" . $this->_quote_string($val) . "$wc)"; |
| | | $filter .= "($f=$wp" . $this->_quote_string($val) . "$ws)"; |
| | | } |
| | | } |
| | | } |
| | |
| | | |
| | | $groups = array(); |
| | | if ($search) { |
| | | $search = strtolower($search); |
| | | $search = mb_strtolower($search); |
| | | foreach ($group_cache as $group) { |
| | | if (strstr(strtolower($group['name']), $search)) |
| | | if (strpos(mb_strtolower($group['name']), $search) !== false) |
| | | $groups[] = $group; |
| | | } |
| | | } |
| | |
| | | $groups[$group_id]['email'][] = $ldap_data[$i][$email_attr][$j]; |
| | | } |
| | | |
| | | $group_sortnames[] = strtolower($ldap_data[$i][$sort_attr][0]); |
| | | $group_sortnames[] = mb_strtolower($ldap_data[$i][$sort_attr][0]); |
| | | } |
| | | |
| | | // recursive call can exit here |
| | |
| | | public function reload() |
| | | { |
| | | if ($this->key && $this->memcache) |
| | | $this->mc_read($this->key); |
| | | $data = $this->mc_read($this->key); |
| | | else if ($this->key) |
| | | $this->db_read($this->key); |
| | | $data = $this->db_read($this->key); |
| | | |
| | | if ($data) |
| | | session_decode($data); |
| | | } |
| | | |
| | | |
| | |
| | | |
| | | if (this.task == 'mail') { |
| | | url += '&_mbox='+urlencode(this.env.mailbox); |
| | | |
| | | if (this.env.mailbox == this.env.drafts_mailbox) { |
| | | var uid; |
| | | if (uid = this.get_single_uid()) |
| | | url += '&_draft_uid='+uid; |
| | | } |
| | | else if (props) |
| | | if (props) |
| | | url += '&_to='+urlencode(props); |
| | | } |
| | | // modify url if we're in addressbook |
| | |
| | | $labels['nosubject'] = '(no subject)'; |
| | | $labels['showimages'] = 'Display images'; |
| | | $labels['alwaysshow'] = 'Always show images from $sender'; |
| | | $labels['isdraft'] = 'This is a draft message.'; |
| | | |
| | | $labels['htmltoggle'] = 'HTML'; |
| | | $labels['plaintoggle'] = 'Plain text'; |
| | |
| | | $labels['reqdsn'] = 'Always request a delivery status notification'; |
| | | $labels['replysamefolder'] = 'Place replies in the folder of the message being replied to'; |
| | | $labels['defaultaddressbook'] = 'Add new contacts to the selected addressbook'; |
| | | $labels['autocompletesingle'] = 'Skip alternative email addresses in autocompletion'; |
| | | $labels['spellcheckbeforesend'] = 'Check spelling before sending a message'; |
| | | $labels['spellcheckoptions'] = 'Spellcheck Options'; |
| | | $labels['spellcheckignoresyms'] = 'Ignore words with symbols'; |
| | |
| | | $labels['addtodict'] = 'Dodaj do słownika'; |
| | | $labels['dateformat'] = 'Format daty'; |
| | | $labels['timeformat'] = 'Format czasu'; |
| | | $labels['isdraft'] = 'To jest kopia robocza wiadomoÅci.'; |
| | | $labels['autocompletesingle'] = 'Nie pokazuj alternatywnych adresów przy autouzupeÅnianiu'; |
| | | |
| | | ?> |
| | |
| | | // Check if contact exists, if so, we'll need it's ID |
| | | // Note: Some addressbooks allows empty email address field |
| | | if (!empty($a_record['email'])) |
| | | $result = $TARGET->search('email', $a_record['email'], true, true, true); |
| | | $result = $TARGET->search('email', $a_record['email'], 1, true, true); |
| | | else if (!empty($a_record['name'])) |
| | | $result = $TARGET->search('name', $a_record['name'], true, true, true); |
| | | $result = $TARGET->search('name', $a_record['name'], 1, true, true); |
| | | else |
| | | $result = new rcube_result_set(); |
| | | |
| | |
| | | |
| | | if (!$replace && $email) { |
| | | // compare e-mail address |
| | | $existing = $CONTACTS->search('email', $email, false, false); |
| | | $existing = $CONTACTS->search('email', $email, 1, false); |
| | | if (!$existing->count && $vcard->displayname) { // compare display name |
| | | $existing = $CONTACTS->search('name', $vcard->displayname, false, false); |
| | | $existing = $CONTACTS->search('name', $vcard->displayname, 1, false); |
| | | } |
| | | if ($existing->count) { |
| | | $IMPORT_STATS->skipped++; |
| | |
| | | { |
| | | $CONTACTS->set_page(1); |
| | | $CONTACTS->set_pagesize(count($cid) + 2); // +2 to skip counting query |
| | | $recipients = $CONTACTS->search($CONTACTS->primary_key, $cid, false, true, true, 'email'); |
| | | $recipients = $CONTACTS->search($CONTACTS->primary_key, $cid, 0, true, true, 'email'); |
| | | } |
| | | } |
| | | |
| | |
| | | // show notice if existing contacts with same e-mail are found |
| | | $existing = false; |
| | | foreach ($CONTACTS->get_col_values('email', $a_record, true) as $email) { |
| | | if ($email && ($res = $CONTACTS->search('email', $email, false, false, true)) && $res->count) { |
| | | if ($email && ($res = $CONTACTS->search('email', $email, 1, false, true)) && $res->count) { |
| | | $OUTPUT->show_message('contactexists', 'notice', null, false); |
| | | break; |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | // Values matching mode |
| | | $mode = (int) $RCMAIL->config->get('addressbook_search_mode'); |
| | | |
| | | // get sources list |
| | | $sources = $RCMAIL->get_address_sources(); |
| | | $search_set = array(); |
| | |
| | | $source->set_pagesize(9999); |
| | | |
| | | // get contacts count |
| | | $result = $source->search($fields, $search, false, false); |
| | | $result = $source->search($fields, $search, $mode, false); |
| | | |
| | | if (!$result->count) { |
| | | continue; |
| | |
| | | } |
| | | |
| | | // check for existing contacts |
| | | $existing = $CONTACTS->search('email', $contact['email'], true, false); |
| | | $existing = $CONTACTS->search('email', $contact['email'], 1, false); |
| | | |
| | | if ($done = $existing->count) |
| | | $OUTPUT->show_message('contactexists', 'warning'); |
| | |
| | | |
| | | |
| | | $MAXNUM = (int)$RCMAIL->config->get('autocomplete_max', 15); |
| | | $mode = (int) $RCMAIL->config->get('addressbook_search_mode'); |
| | | $single = (bool) $RCMAIL->config->get('autocomplete_single'); |
| | | $search = get_input_value('_search', RCUBE_INPUT_GPC, true); |
| | | $source = get_input_value('_source', RCUBE_INPUT_GPC); |
| | | $sid = get_input_value('_id', RCUBE_INPUT_GPC); |
| | |
| | | if (!empty($book_types) && strlen($search)) { |
| | | $contacts = array(); |
| | | $books_num = count($book_types); |
| | | $search_lc = mb_strtolower($search); |
| | | |
| | | foreach ($book_types as $id) { |
| | | $abook = $RCMAIL->get_address_book($id); |
| | | $abook->set_pagesize($MAXNUM); |
| | | |
| | | if ($result = $abook->search(array('email','name'), $search, false, true, true, 'email')) { |
| | | if ($result = $abook->search(array('email','name'), $search, $mode, true, true, 'email')) { |
| | | while ($sql_arr = $result->iterate()) { |
| | | // Contact can have more than one e-mail address |
| | | $email_arr = (array)$abook->get_col_values('email', $sql_arr, true); |
| | | $email_cnt = count($email_arr); |
| | | foreach ($email_arr as $email) { |
| | | if (empty($email)) |
| | | continue; |
| | | $contact = format_email_recipient($email, $sql_arr['name']); |
| | | // skip entries that don't match |
| | | if ($email_cnt > 1 && stripos($contact, $search) === false) { |
| | | if (empty($email)) { |
| | | continue; |
| | | } |
| | | |
| | | $contact = format_email_recipient($email, $sql_arr['name']); |
| | | |
| | | // skip entries that don't match |
| | | if ($email_cnt > 1 && strpos(mb_strtolower($contact), $search_lc) === false) { |
| | | continue; |
| | | } |
| | | |
| | | // skip duplicates |
| | | if (!in_array($contact, $contacts)) { |
| | | $contacts[] = $contact; |
| | | if (count($contacts) >= $MAXNUM) |
| | | break 2; |
| | | } |
| | | |
| | | // skip redundant entries (show only first email address) |
| | | if ($single) { |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // also list matching contact groups |
| | | if ($abook->groups) { |
| | | if ($abook->groups && count($contacts) < $MAXNUM) { |
| | | foreach ($abook->list_groups($search) as $group) { |
| | | $abook->reset(); |
| | | $abook->set_group($group['ID']); |
| | |
| | | if (!$p['skip_washer_style_callback']) |
| | | $washer->add_callback('style', 'rcmail_washtml_callback'); |
| | | |
| | | // Remove non-UTF8 characters (#1487813) |
| | | $html = rc_utf8_clean($html); |
| | | |
| | | $html = $washer->wash($html); |
| | | $REMOTE_OBJECTS = $washer->extlinks; |
| | | |
| | |
| | | return $out; |
| | | } |
| | | |
| | | function rcmail_remote_objects_msg($attrib) |
| | | function rcmail_remote_objects_msg() |
| | | { |
| | | global $MESSAGE, $RCMAIL; |
| | | |
| | | if (!$attrib['id']) |
| | | $attrib['id'] = 'rcmremoteobjmsg'; |
| | | $attrib['id'] = 'remote-objects-message'; |
| | | $attrib['class'] = 'notice'; |
| | | $attrib['style'] = 'display: none'; |
| | | |
| | | $msg = Q(rcube_label('blockedimages')) . ' '; |
| | | $msg .= html::a(array('href' => "#loadimages", 'onclick' => JS_OBJECT_NAME.".command('load-images')"), Q(rcube_label('showimages'))); |
| | |
| | | |
| | | $RCMAIL->output->add_gui_object('remoteobjectsmsg', $attrib['id']); |
| | | return html::div($attrib, $msg); |
| | | } |
| | | |
| | | function rcmail_message_buttons() |
| | | { |
| | | global $MESSAGE, $RCMAIL, $CONFIG; |
| | | |
| | | $mbox = $RCMAIL->imap->get_mailbox_name(); |
| | | $delim = $RCMAIL->imap->get_hierarchy_delimiter(); |
| | | $dbox = $CONFIG['drafts_mbox']; |
| | | |
| | | // the message is not a draft |
| | | if ($mbox != $dbox && strpos($mbox, $dbox.$delim) !== 0) { |
| | | return ''; |
| | | } |
| | | |
| | | $attrib['id'] = 'message-buttons'; |
| | | $attrib['class'] = 'notice'; |
| | | |
| | | $msg = Q(rcube_label('isdraft')) . ' '; |
| | | $msg .= html::a(array('href' => "#edit", 'onclick' => JS_OBJECT_NAME.".command('edit')"), Q(rcube_label('edit'))); |
| | | |
| | | return html::div($attrib, $msg); |
| | | } |
| | | |
| | | function rcmail_message_objects($attrib) |
| | | { |
| | | global $RCMAIL, $MESSAGE; |
| | | |
| | | if (!$attrib['id']) |
| | | $attrib['id'] = 'message-objects'; |
| | | |
| | | $content = array( |
| | | rcmail_message_buttons(), |
| | | rcmail_remote_objects_msg(), |
| | | ); |
| | | |
| | | $plugin = $RCMAIL->plugins->exec_hook('message_objects', |
| | | array('content' => $content, 'message' => $MESSAGE)); |
| | | |
| | | $content = implode("\n", $plugin['content']); |
| | | |
| | | return html::div($attrib, $content); |
| | | } |
| | | |
| | | function rcmail_contact_exists($email) |
| | |
| | | $OUTPUT->add_handlers(array( |
| | | 'messageattachments' => 'rcmail_message_attachments', |
| | | 'mailboxname' => 'rcmail_mailbox_name_display', |
| | | 'blockedobjects' => 'rcmail_remote_objects_msg')); |
| | | 'messageobjects' => 'rcmail_message_objects', |
| | | )); |
| | | |
| | | |
| | | if ($RCMAIL->action=='print' && $OUTPUT->template_exists('messageprint')) |
| | |
| | | ); |
| | | } |
| | | |
| | | if (!isset($no_override['autocomplete_single'])) { |
| | | $field_id = 'rcmfd_autocomplete_single'; |
| | | $checkbox = new html_checkbox(array('name' => '_autocomplete_single', 'id' => $field_id, 'value' => 1)); |
| | | |
| | | $blocks['main']['options']['autocomplete_single'] = array( |
| | | 'title' => html::label($field_id, Q(rcube_label('autocompletesingle'))), |
| | | 'content' => $checkbox->show($config['autocomplete_single']?1:0), |
| | | ); |
| | | } |
| | | |
| | | break; |
| | | |
| | | // Special IMAP folders |
| | |
| | | case 'addressbook': |
| | | $a_user_prefs = array( |
| | | 'default_addressbook' => get_input_value('_default_addressbook', RCUBE_INPUT_POST, true), |
| | | 'autocomplete_single' => isset($_POST['_autocomplete_single']) ? TRUE : FALSE, |
| | | ); |
| | | |
| | | break; |
| | |
| | | } |
| | | |
| | | #message div.notice, |
| | | #remote-objects-message |
| | | #message-objects div.notice |
| | | { |
| | | background: url(images/display/icons.png) 6px 3px no-repeat; |
| | | background-color: #F7FDCB; |
| | |
| | | } |
| | | |
| | | #message div.error, |
| | | #message div.warning |
| | | #message div.warning, |
| | | #message-objects div.warning, |
| | | #message-objects div.error |
| | | { |
| | | background: url(images/display/icons.png) 6px -97px no-repeat; |
| | | background-color: #EF9398; |
| | | border: 1px solid #DC5757; |
| | | } |
| | | |
| | | #message div.confirmation |
| | | #message div.confirmation, |
| | | #message-objects div.confirmation |
| | | { |
| | | background: url(images/display/icons.png) 6px -47px no-repeat; |
| | | background-color: #A6EF7B; |
| | | border: 1px solid #76C83F; |
| | | } |
| | | |
| | | #message div.loading |
| | | #message div.loading, |
| | | #message-objects div.loading |
| | | { |
| | | background: url(images/display/loading.gif) 6px 3px no-repeat; |
| | | background-color: #EBEBEB; |
| | |
| | | #message div.error, |
| | | #message div.warning, |
| | | #message div.confirmation, |
| | | #remote-objects-message |
| | | #message-objects div.notice, |
| | | #message-objects div.error, |
| | | #message-objects div.warning, |
| | | #message-objects div.confirmation |
| | | { |
| | | background-image: url(images/display/icons.gif); |
| | | } |
| | |
| | | margin: 8px; |
| | | } |
| | | |
| | | #remote-objects-message |
| | | #message-objects div |
| | | { |
| | | display: none; |
| | | margin: 8px; |
| | | min-height: 20px; |
| | | padding: 10px 10px 6px 46px; |
| | | } |
| | | |
| | | #remote-objects-message a |
| | | #message-objects div a |
| | | { |
| | | color: #666666; |
| | | padding-left: 10px; |
| | | } |
| | | |
| | | #remote-objects-message a:hover |
| | | #message-objects div a:hover |
| | | { |
| | | color: #333333; |
| | | } |
| | |
| | | <roundcube:object name="messageHeaders" class="headers-table" cellspacing="0" cellpadding="2" addicon="/images/icons/silhouette.png" summary="Message headers" /> |
| | | <roundcube:object name="messageFullHeaders" id="full-headers" /> |
| | | <roundcube:object name="messageAttachments" id="attachment-list" /> |
| | | |
| | | <roundcube:object name="blockedObjects" id="remote-objects-message" /> |
| | | <roundcube:object name="messageObjects" id="message-objects" /> |
| | | <roundcube:object name="messageBody" id="messagebody" /> |
| | | </div> |
| | | <div class="boxfooter"> |
| | |
| | | <roundcube:object name="messageAttachments" id="attachment-list" /> |
| | | </div> |
| | | |
| | | <roundcube:object name="blockedObjects" id="remote-objects-message" /> |
| | | <roundcube:object name="messageObjects" id="message-objects" /> |
| | | <roundcube:object name="messageBody" id="messagebody" /> |
| | | |
| | | </body> |
| | |
| | | } |
| | | |
| | | /** |
| | | * Test washtml class on non-unicode characters (#1487813) |
| | | */ |
| | | function test_washtml_utf8() |
| | | { |
| | | $part = $this->get_html_part('src/invalidchars.html'); |
| | | $washed = rcmail_print_body($part); |
| | | |
| | | $this->assertPattern('/<p>ÑОЌвПл<\/p>/', $washed, "Remove non-unicode characters from HTML message body"); |
| | | } |
| | | |
| | | /** |
| | | * Test links pattern replacements in plaintext messages |
| | | */ |
| | | function test_plaintext() |