/** * 'contact_photo' hook handler to inject an identicon image */ function contact_photo($args) { // pre-conditions, exit if photo already exists or invalid input if (!empty($args['url']) || !empty($args['data']) || empty($args['record']) && empty($args['email'])) { return $args; } $rcmail = rcmail::get_instance(); // supporting edit/add action may be tricky, let's not do this if ($rcmail->action == 'show' || $rcmail->action == 'photo') { $email = $args['email']; if (!$email && $args['record']) { $addresses = rcube_addressbook::get_col_values('email', $args['record'], true); if (!empty($addresses)) { $email = $addresses[0]; } } if ($email) { require_once __DIR__ . '/identicon_engine.php'; $identicon = new identicon_engine($email); if ($rcmail->action == 'show') { // set photo URL using data-uri if (($icon = $identicon->getBinary()) && ($icon = base64_encode($icon))) { $mimetype = $identicon->getMimetype(); $args['url'] = sprintf('data:%s;base64,%s', $mimetype, $icon); } } else { // send the icon to the browser $identicon = new identicon_engine($email); if ($identicon->sendOutput()) { exit; } } } } return $args; }
/** * Check the given data before saving. * If input not valid, the message to display can be fetched using get_error() * * @param array Assoziative array with data to save * @param boolean Try to fix/complete record automatically * @return boolean True if input is valid, False if not. */ public function validate(&$save_data, $autofix = false) { // validate e-mail addresses if (!parent::validate($save_data, $autofix)) { return false; } // check for name input if (empty($save_data['name'])) { $this->set_error(self::ERROR_VALIDATE, 'nonamewarning'); return false; } // Verify that the required fields are set. $missing = null; $ldap_data = $this->_map_data($save_data); foreach ($this->prop['required_fields'] as $fld) { if (!isset($ldap_data[$fld]) || $ldap_data[$fld] === '') { $missing[$fld] = 1; } } if ($missing) { // try to complete record automatically if ($autofix) { $sn_field = $this->fieldmap['surname']; $fn_field = $this->fieldmap['firstname']; $mail_field = $this->fieldmap['email']; // try to extract surname and firstname from displayname $name_parts = preg_split('/[\\s,.]+/', $save_data['name']); if ($sn_field && $missing[$sn_field]) { $save_data['surname'] = array_pop($name_parts); unset($missing[$sn_field]); } if ($fn_field && $missing[$fn_field]) { $save_data['firstname'] = array_shift($name_parts); unset($missing[$fn_field]); } // try to fix missing e-mail, very often on import // from vCard we have email:other only defined if ($mail_field && $missing[$mail_field]) { $emails = $this->get_col_values('email', $save_data, true); if (!empty($emails) && ($email = array_shift($emails))) { $save_data['email'] = $email; unset($missing[$mail_field]); } } } // TODO: generate message saying which fields are missing if (!empty($missing)) { $this->set_error(self::ERROR_VALIDATE, 'formincomplete'); return false; } } return true; }
/** * Handler for attendee group expansion requests */ public function expand_attendee_group() { $id = rcube_utils::get_input_value('id', rcube_utils::INPUT_POST); $data = rcube_utils::get_input_value('data', rcube_utils::INPUT_POST, true); $result = array('id' => $id, 'members' => array()); $maxnum = 500; // iterate over all autocomplete address books (we don't know the source of the group) foreach ((array) $this->rc->config->get('autocomplete_addressbooks', 'sql') as $abook_id) { if (($abook = $this->rc->get_address_book($abook_id)) && $abook->groups) { foreach ($abook->list_groups($data['name'], 1) as $group) { // this is the matching group to expand if (in_array($data['email'], (array) $group['email'])) { $abook->set_pagesize($maxnum); $abook->set_group($group['ID']); // get all members $res = $abook->list_records($this->rc->config->get('contactlist_fields')); // handle errors (e.g. sizelimit, timelimit) if ($abook->get_error()) { $result['error'] = $this->rc->gettext('expandattendeegrouperror', 'libcalendaring'); $res = false; } else { if ($res->count > $maxnum) { $result['error'] = $this->rc->gettext('expandattendeegroupsizelimit', 'libcalendaring'); $res = false; } } while ($res && ($member = $res->iterate())) { $emails = (array) $abook->get_col_values('email', $member, true); if (!empty($emails) && ($email = array_shift($emails))) { $result['members'][] = array('email' => $email, 'name' => rcube_addressbook::compose_list_name($member)); } } break 2; } } } } $this->rc->output->command('plugin.expand_attendee_callback', $result); }
/** * Check the given data before saving. * If input not valid, the message to display can be fetched using get_error() * * @param array Assoziative array with data to save * @param boolean Try to fix/complete record automatically * @return boolean True if input is valid, False if not. */ function validate(&$save_data, $autofix = false) { // validate e-mail addresses $valid = parent::validate($save_data, $autofix); // require at least one email address or a name // https://code.google.com/p/myroundcube/issues/detail?id=534 /* if($valid && !strlen($save_data['firstname'].$save_data['surname'].$save_data['name']) && !array_filter($this->get_col_values('email', $save_data, true))){ $this->set_error(self::ERROR_VALIDATE, 'noemailwarning'); $valid = false; } */ return $valid; }
/** * Check the given data before saving. * If input not valid, the message to display can be fetched using get_error() * * @param array Assoziative array with data to save * @param boolean Try to fix/complete record automatically * @return boolean True if input is valid, False if not. */ public function validate(&$save_data, $autofix = false) { // validate e-mail addresses $valid = parent::validate($save_data, $autofix); // require at least one e-mail address (syntax check is already done) if ($valid && !array_filter($this->get_col_values('email', $save_data, true))) { $this->set_error(self::ERROR_VALIDATE, 'noemailwarning'); $valid = false; } return $valid; }
/** * Check the given data before saving. * If input not valid, the message to display can be fetched using get_error() * * @param array Assoziative array with data to save * @param boolean Try to fix/complete record automatically * @return boolean True if input is valid, False if not. */ public function validate(&$save_data, $autofix = false) { // validate e-mail addresses $valid = parent::validate($save_data, $autofix); // require at least one email address or a name if ($valid && !strlen($save_data['firstname'] . $save_data['surname'] . $save_data['name']) && !array_filter($this->get_col_values('email', $save_data, true))) { $this->set_error(self::ERROR_VALIDATE, 'noemailwarning'); $valid = false; } return $valid; }
/** * Handler for user login autocomplete request */ function acl_autocomplete() { $this->load_config(); $search = rcube_utils::get_input_value('_search', rcube_utils::INPUT_GPC, true); $reqid = rcube_utils::get_input_value('_reqid', rcube_utils::INPUT_GPC); $users = array(); $keys = array(); if ($this->init_ldap()) { $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']; if (is_array($user)) { $user = array_filter($user); $user = $user[0]; } if ($user) { $display = rcube_addressbook::compose_search_name($record); $user = array('name' => $user, 'display' => $display); $users[] = $user; $keys[] = $display ?: $user['name']; } } if ($this->rc->config->get('acl_groups')) { $prefix = $this->rc->config->get('acl_group_prefix'); $group_field = $this->rc->config->get('acl_group_field', 'name'); $result = $this->ldap->list_groups($search, $mode); foreach ($result as $record) { $group = $record['name']; $group_id = is_array($record[$group_field]) ? $record[$group_field][0] : $record[$group_field]; if ($group) { $users[] = array('name' => ($prefix ? $prefix : '') . $group_id, 'display' => $group, 'type' => 'group'); $keys[] = $group; } } } } if (count($users)) { // sort users index asort($keys, SORT_LOCALE_STRING); // re-sort users according to index foreach ($keys as $idx => $val) { $keys[$idx] = $users[$idx]; } $users = array_values($keys); } $this->rc->output->command('ksearch_query_results', $users, $search, $reqid); $this->rc->output->send(); }
/** * Get vcard data for specified contact */ private function get_contact_vcard($source, $cid, &$filename = null) { $rcmail = rcmail::get_instance(); $source = $rcmail->get_address_book($source); $contact = $source->get_record($cid, true); if ($contact) { $fieldmap = $source ? $source->vcard_map : null; if (empty($contact['vcard'])) { $vcard = new rcube_vcard('', RCUBE_CHARSET, false, $fieldmap); $vcard->reset(); foreach ($contact as $key => $values) { list($field, $section) = explode(':', $key); // avoid unwanted casting of DateTime objects to an array // (same as in rcube_contacts::convert_save_data()) if (is_object($values) && is_a($values, 'DateTime')) { $values = array($values); } foreach ((array) $values as $value) { if (is_array($value) || is_a($value, 'DateTime') || @strlen($value)) { $vcard->set($field, $value, strtoupper($section)); } } } $contact['vcard'] = $vcard->export(); } $name = rcube_addressbook::compose_list_name($contact); $filename = (self::parse_filename($name) ?: 'contact') . '.vcf'; // fix folding and end-of-line chars $vcard = preg_replace('/\\r|\\n\\s+/', '', $contact['vcard']); $vcard = preg_replace('/\\n/', rcube_vcard::$eol, $vcard); return rcube_vcard::rfc2425_fold($vcard) . rcube_vcard::$eol; } }
/** * Get a single birthday calendar event */ public function get_birthday_event($id) { // decode $id list(, $source, $contact_id, $year) = explode(':', rcube_ldap::dn_decode($id)); $rcmail = rcmail::get_instance(); if ($source && $contact_id && ($abook = $rcmail->get_address_book($source))) { $contact = $abook->get_record($contact_id, true); if (is_array($contact) && !empty($contact['birthday'])) { try { if (is_array($contact['birthday'])) { $contact['birthday'] = reset($contact['birthday']); } $bday = $contact['birthday'] instanceof DateTime ? $contact['birthday'] : new DateTime($contact['birthday'], new DateTimezone('UTC')); $birthyear = $bday->format('Y'); } catch (Exception $e) { rcube::raise_error(array('code' => 600, 'type' => 'php', 'file' => __FILE__, 'line' => __LINE__, 'message' => 'BIRTHDAY PARSE ERROR: ' . $e), true, false); return null; } $display_name = rcube_addressbook::compose_display_name($contact); $event_title = $rcmail->gettext(array('name' => 'birthdayeventtitle', 'vars' => array('name' => $display_name)), 'calendar'); $event = array('id' => rcube_ldap::dn_encode('bday:' . $source . ':' . $contact['ID'] . ':' . $year), 'uid' => rcube_ldap::dn_encode('bday:' . $source . ':' . $contact['ID'] . ':' . $birthyear), 'calendar' => self::BIRTHDAY_CALENDAR_ID, 'title' => $event_title, 'description' => '', 'allday' => true, 'start' => $bday, 'recurrence' => array('FREQ' => 'YEARLY', 'INTERVAL' => 1), 'free_busy' => 'free'); $event['end'] = clone $bday; $event['end']->add(new DateInterval('PT1H')); return $event; } } return null; }
function contact_photo($p) { // if no contact photo was found if (!$p['data']) { // TODO: try for every email address of contact record? $emails = rcube_addressbook::get_col_values('email', $p['record'], true); $email = $p['email'] ? $p['email'] : $emails[0]; if ($email) { $this->gravatar_id = md5(strtolower($email)); $url = $this->gravatar_url(); $headers = get_headers($url); if (is_array($headers) && preg_match("/200 OK/", $headers[0])) { $p['url'] = $url; } } } return $p; }