Esempio n. 1
0
 /**
  * Convert the given date to a human readable form
  * This uses the date formatting properties from config
  *
  * @param mixed  Date representation (string, timestamp or DateTime object)
  * @param string Date format to use
  * @param bool   Enables date convertion according to user timezone
  *
  * @return string Formatted date string
  */
 public function format_date($date, $format = null, $convert = true)
 {
     if (is_object($date) && is_a($date, 'DateTime')) {
         $timestamp = $date->format('U');
     } else {
         if (!empty($date)) {
             $timestamp = rcube_strtotime($date);
         }
         if (empty($timestamp)) {
             return '';
         }
         try {
             $date = new DateTime("@" . $timestamp);
         } catch (Exception $e) {
             return '';
         }
     }
     if ($convert) {
         try {
             // convert to the right timezone
             $stz = date_default_timezone_get();
             $tz = new DateTimeZone($this->config->get('timezone'));
             $date->setTimezone($tz);
             date_default_timezone_set($tz->getName());
             $timestamp = $date->format('U');
         } catch (Exception $e) {
         }
     }
     // define date format depending on current time
     if (!$format) {
         $now = time();
         $now_date = getdate($now);
         $today_limit = mktime(0, 0, 0, $now_date['mon'], $now_date['mday'], $now_date['year']);
         $week_limit = mktime(0, 0, 0, $now_date['mon'], $now_date['mday'] - 6, $now_date['year']);
         $pretty_date = $this->config->get('prettydate');
         if ($pretty_date && $timestamp > $today_limit && $timestamp < $now) {
             $format = $this->config->get('date_today', $this->config->get('time_format', 'H:i'));
             $today = true;
         } else {
             if ($pretty_date && $timestamp > $week_limit && $timestamp < $now) {
                 $format = $this->config->get('date_short', 'D H:i');
             } else {
                 $format = $this->config->get('date_long', 'Y-m-d H:i');
             }
         }
     }
     // strftime() format
     if (preg_match('/%[a-z]+/i', $format)) {
         $format = strftime($format, $timestamp);
         if ($stz) {
             date_default_timezone_set($stz);
         }
         return $today ? $this->gettext('today') . ' ' . $format : $format;
     }
     // parse format string manually in order to provide localized weekday and month names
     // an alternative would be to convert the date() format string to fit with strftime()
     $out = '';
     for ($i = 0; $i < strlen($format); $i++) {
         if ($format[$i] == "\\") {
             // skip escape chars
             continue;
         }
         // write char "as-is"
         if ($format[$i] == ' ' || $format[$i - 1] == "\\") {
             $out .= $format[$i];
         } else {
             if ($format[$i] == 'D') {
                 $out .= $this->gettext(strtolower(date('D', $timestamp)));
             } else {
                 if ($format[$i] == 'l') {
                     $out .= $this->gettext(strtolower(date('l', $timestamp)));
                 } else {
                     if ($format[$i] == 'M') {
                         $out .= $this->gettext(strtolower(date('M', $timestamp)));
                     } else {
                         if ($format[$i] == 'F') {
                             $out .= $this->gettext('long' . strtolower(date('M', $timestamp)));
                         } else {
                             if ($format[$i] == 'x') {
                                 $out .= strftime('%x %X', $timestamp);
                             } else {
                                 $out .= date($format[$i], $timestamp);
                             }
                         }
                     }
                 }
             }
         }
     }
     if ($today) {
         $label = $this->gettext('today');
         // replcae $ character with "Today" label (#1486120)
         if (strpos($out, '$') !== false) {
             $out = preg_replace('/\\$/', $label, $out, 1);
         } else {
             $out = $label . ' ' . $out;
         }
     }
     if ($stz) {
         date_default_timezone_set($stz);
     }
     return $out;
 }
Esempio n. 2
0
 /**
  * Creates a new or updates an existing vcard from save data.
  */
 private function create_vcard_from_save_data($save_data, $vcf = null)
 {
     unset($save_data['vcard']);
     if (!$vcf) {
         // create fresh minimal vcard
         $vcf = new VObject\Component\VCard(array('UID' => $save_data['cuid'], 'REV' => date('c')));
     } else {
         // update revision
         $vcf->REV = date("c");
     }
     // N is mandatory
     if (array_key_exists('kind', $save_data) && $save_data['kind'] === 'group') {
         $vcf->N = $save_data['name'];
     } else {
         $vcf->N = array($save_data['surname'], $save_data['firstname'], $save_data['middlename'], $save_data['prefix'], $save_data['suffix']);
     }
     $new_org_value = array();
     if (array_key_exists("organization", $save_data) && strlen($save_data['organization']) > 0) {
         $new_org_value[] = $save_data['organization'];
     }
     if (array_key_exists("department", $save_data)) {
         if (is_array($save_data['department'])) {
             foreach ($save_data['department'] as $key => $value) {
                 $new_org_value[] = $value;
             }
         } else {
             if (strlen($save_data['department']) > 0) {
                 $new_org_value[] = $save_data['department'];
             }
         }
     }
     if (count($new_org_value) > 0) {
         $vcf->ORG = $new_org_value;
     } else {
         unset($vcf->ORG);
     }
     // normalize date fields to RFC2425 YYYY-MM-DD date values
     foreach ($this->datefields as $key) {
         if (array_key_exists($key, $save_data) && strlen($save_data[$key]) > 0) {
             $val = rcube_strtotime($save_data[$key]);
             $save_data[$key] = date('Y-m-d', $val);
         }
     }
     // due to a bug in earlier versions of RCMCardDAV the PHOTO field was encoded base64 TWICE
     // This was recognized and fixed on 2013-01-09 and should be kept here until reasonable
     // certain that it's been fixed on users data, too.
     if (!array_key_exists('photo', $save_data) && strlen($vcf->PHOTO) > 0) {
         $save_data['photo'] = $vcf->PHOTO;
     }
     if (array_key_exists('photo', $save_data) && strlen($save_data['photo']) > 0 && base64_decode($save_data['photo'], true) !== FALSE) {
         self::$helper->debug("photo is base64 encoded. Decoding...");
         $i = 0;
         while (base64_decode($save_data['photo'], true) !== FALSE && $i++ < 10) {
             self::$helper->debug("Decoding {$i}...");
             $save_data['photo'] = base64_decode($save_data['photo'], true);
         }
         if ($i >= 10) {
             lef::$helper->warn("PHOTO of " . $save_data['uid'] . " does not decode after 10 attempts...");
         }
     }
     // process all simple attributes
     foreach ($this->vcf2rc['simple'] as $vkey => $rckey) {
         if (array_key_exists($rckey, $save_data)) {
             if (strlen($save_data[$rckey]) > 0) {
                 $vcf->{$vkey} = $save_data[$rckey];
             } else {
                 // delete the field
                 unset($vcf->{$vkey});
             }
         }
     }
     // Special handling for PHOTO
     if ($property = $vcf->PHOTO) {
         $property['ENCODING'] = 'B';
         $property['VALUE'] = 'BINARY';
     }
     // process all multi-value attributes
     foreach ($this->vcf2rc['multi'] as $vkey => $rckey) {
         // delete and fully recreate all entries
         // there is no easy way of mapping an address in the existing card
         // to an address in the save data, as subtypes may have changed
         unset($vcf->{$vkey});
         $stmap = array($rckey => 'other');
         foreach ($this->coltypes[$rckey]['subtypes'] as $subtype) {
             $stmap[$rckey . ':' . $subtype] = $subtype;
         }
         foreach ($stmap as $rcqkey => $subtype) {
             if (array_key_exists($rcqkey, $save_data)) {
                 $avalues = is_array($save_data[$rcqkey]) ? $save_data[$rcqkey] : array($save_data[$rcqkey]);
                 foreach ($avalues as $evalue) {
                     if (strlen($evalue) > 0) {
                         $prop = $vcf->add($vkey, $evalue);
                         $this->set_attr_label($vcf, $prop, $rckey, $subtype);
                         // set label
                     }
                 }
             }
         }
     }
     // process address entries
     unset($vcf->ADR);
     foreach ($this->coltypes['address']['subtypes'] as $subtype) {
         $rcqkey = 'address:' . $subtype;
         if (array_key_exists($rcqkey, $save_data)) {
             foreach ($save_data[$rcqkey] as $avalue) {
                 if (strlen($avalue['street']) || strlen($avalue['locality']) || strlen($avalue['region']) || strlen($avalue['zipcode']) || strlen($avalue['country'])) {
                     $prop = $vcf->add('ADR', array('', '', $avalue['street'], $avalue['locality'], $avalue['region'], $avalue['zipcode'], $avalue['country']));
                     $this->set_attr_label($vcf, $prop, 'address', $subtype);
                     // set label
                 }
             }
         }
     }
     return $vcf;
 }
Esempio n. 3
0
 /**
  * Setter for address record fields
  *
  * @param string Field name
  * @param string Field value
  * @param string Type/section name
  */
 public function set($field, $value, $type = 'HOME')
 {
     $field = strtolower($field);
     $type_uc = strtoupper($type);
     $typemap = array_flip($this->typemap);
     switch ($field) {
         case 'name':
         case 'displayname':
             $this->raw['FN'][0][0] = $value;
             break;
         case 'surname':
             $this->raw['N'][0][0] = $value;
             break;
         case 'firstname':
             $this->raw['N'][0][1] = $value;
             break;
         case 'middlename':
             $this->raw['N'][0][2] = $value;
             break;
         case 'prefix':
             $this->raw['N'][0][3] = $value;
             break;
         case 'suffix':
             $this->raw['N'][0][4] = $value;
             break;
         case 'nickname':
             $this->raw['NICKNAME'][0][0] = $value;
             break;
         case 'organization':
             $this->raw['ORG'][0][0] = $value;
             break;
         case 'photo':
             if (strpos($value, 'http:') === 0) {
                 // TODO: fetch file from URL and save it locally?
                 $this->raw['PHOTO'][0] = array(0 => $value, 'url' => true);
             } else {
                 $this->raw['PHOTO'][0] = array(0 => $value, 'base64' => (bool) preg_match('![^a-z0-9/=+-]!i', $value));
             }
             break;
         case 'email':
             $this->raw['EMAIL'][] = array(0 => $value, 'type' => array_filter(array('INTERNET', $type_uc)));
             $this->email[] = $value;
             break;
         case 'im':
             // save IM subtypes into extension fields
             $typemap = array_flip($this->immap);
             if ($field = $typemap[strtolower($type)]) {
                 $this->raw[$field][] = array(0 => $value);
             }
             break;
         case 'birthday':
         case 'anniversary':
             if (($val = rcube_strtotime($value)) && ($fn = self::$fieldmap[$field])) {
                 $this->raw[$fn][] = array(0 => date('Y-m-d', $val), 'value' => array('date'));
             }
             break;
         case 'address':
             if ($this->addresstypemap[$type_uc]) {
                 $type = $this->addresstypemap[$type_uc];
             }
             $value = $value[0] ? $value : array('', '', $value['street'], $value['locality'], $value['region'], $value['zipcode'], $value['country']);
             // fall through if not empty
             if (!strlen(join('', $value))) {
                 break;
             }
         default:
             if ($field == 'phone' && $this->phonetypemap[$type_uc]) {
                 $type = $this->phonetypemap[$type_uc];
             }
             if (($tag = self::$fieldmap[$field]) && (is_array($value) || strlen($value))) {
                 $index = count($this->raw[$tag]);
                 $this->raw[$tag][$index] = (array) $value;
                 if ($type) {
                     $this->raw[$tag][$index]['type'] = explode(',', $typemap[$type] ? $typemap[$type] : $type);
                 }
             }
             break;
     }
 }