Fix various iCloud vCard issues, added fallback for external photos (#1489993)
| | |
| | | - Fix some mime-type to extension mapping checks in Installer (#1489983) |
| | | - Fix errors when using localStorage in Safari's private browsing mode (#1489996) |
| | | - Fix bug where $Forwarded flag was being set even if server didn't support it (#1490000) |
| | | - Fix various iCloud vCard issues, added fallback for external photos (#1489993) |
| | | |
| | | RELEASE 1.0.2 |
| | | ------------- |
| | |
| | | $attr = array('src' => $attr); |
| | | } |
| | | return self::tag('img', $attr + array('alt' => ''), null, array_merge(self::$common_attrib, |
| | | array('src','alt','width','height','border','usemap','onclick'))); |
| | | array('src','alt','width','height','border','usemap','onclick','onerror'))); |
| | | } |
| | | |
| | | /** |
| | |
| | | public function load($vcard, $charset = RCUBE_CHARSET, $detect = false) |
| | | { |
| | | self::$values_decoded = false; |
| | | $this->raw = self::vcard_decode($vcard); |
| | | $this->raw = self::vcard_decode(self::cleanup($vcard)); |
| | | |
| | | // resolve charset parameters |
| | | if ($charset == null) { |
| | |
| | | |
| | | if (preg_match('/^END:VCARD$/i', $line)) { |
| | | // parse vcard |
| | | $obj = new rcube_vcard(self::cleanup($vcard_block), $charset, true, self::$fieldmap); |
| | | $obj = new rcube_vcard($vcard_block, $charset, true, self::$fieldmap); |
| | | // FN and N is required by vCard format (RFC 2426) |
| | | // on import we can be less restrictive, let's addressbook decide |
| | | if (!empty($obj->displayname) || !empty($obj->surname) || !empty($obj->firstname) || !empty($obj->email)) { |
| | |
| | | // Cleanup |
| | | $vcard = preg_replace(array( |
| | | // convert special types (like Skype) to normal type='skype' classes with this simple regex ;) |
| | | '/item(\d+)\.(TEL|EMAIL|URL)([^:]*?):(.*?)item\1.X-ABLabel:(?:_\$!<)?([\w-() ]*)(?:>!\$_)?./s', |
| | | '/^item\d*\.X-AB.*$/m', // remove cruft like item1.X-AB* |
| | | '/^item\d*\./m', // remove item1.ADR instead of ADR |
| | | '/item(\d+)\.(TEL|EMAIL|URL)([^:]*?):(.*?)item\1.X-ABLabel:(?:_\$!<)?([\w-() ]*)(?:>!\$_)?./si', |
| | | '/^item\d*\.X-AB.*$/mi', // remove cruft like item1.X-AB* |
| | | '/^item\d*\./mi', // remove item1.ADR instead of ADR |
| | | '/\n+/', // remove empty lines |
| | | '/^(N:[^;\R]*)$/m', // if N doesn't have any semicolons, add some |
| | | ), |
| | |
| | | } |
| | | $photo_img = $RCMAIL->url($url); |
| | | } |
| | | else |
| | | else { |
| | | $ff_value = '-del-'; // will disable delete-photo action |
| | | } |
| | | |
| | | $img = html::img(array('src' => $photo_img, 'border' => 1, 'alt' => $RCMAIL->gettext('contactphoto'))); |
| | | $content = html::div($attrib, $img); |
| | | $content = html::div($attrib, html::img(array( |
| | | 'src' => $photo_img, |
| | | 'alt' => $RCMAIL->gettext('contactphoto'), |
| | | 'onerror' => 'this.src = rcmail.env.photo_placeholder', |
| | | ))); |
| | | |
| | | if ($CONTACT_COLTYPES['photo'] && ($RCMAIL->action == 'edit' || $RCMAIL->action == 'add')) { |
| | | $RCMAIL->output->add_gui_object('contactphoto', $attrib['id']); |
| | |
| | | if ($plugin['url']) { |
| | | $RCMAIL->output->redirect($plugin['url']); |
| | | } |
| | | else { |
| | | |
| | | $data = $plugin['data']; |
| | | |
| | | // detect if photo data is an URL |
| | | if (strlen($data) < 1024 && filter_var($data, FILTER_VALIDATE_URL)) { |
| | | $RCMAIL->output->redirect($data); |
| | | } |
| | | |
| | | // deliver alt image |
| | |
| | | '_task' => 'addressbook', |
| | | '_action' => 'photo', |
| | | '_email' => $MESSAGE->sender['mailto'], |
| | | '_alt' => $placeholder |
| | | '_alt' => $placeholder, |
| | | )); |
| | | |
| | | $attrib['onerror'] = "this.src = '" . ($placeholder ? $placeholder : 'program/resources/blank.gif') . "'"; |
| | | } |
| | | else { |
| | | $photo_img = $placeholder ? $placeholder : 'program/resources/blank.gif'; |
| | |
| | | $this->assertEquals("http://domain.tld", $vcard['website:other'][0], "Decode dummy backslash character"); |
| | | } |
| | | |
| | | /** |
| | | * Some Apple vCard quirks (#1489993) |
| | | */ |
| | | function test_parse_six() |
| | | { |
| | | $vcard = new rcube_vcard("BEGIN:VCARD\n" |
| | | . "VERSION:3.0\n" |
| | | . "N:;;;;\n" |
| | | . "FN:Apple Computer AG\n" |
| | | . "ITEM1.ADR;type=WORK;type=pref:;;Birgistrasse 4a;Wallisellen-Zürich;;8304;Switzerland\n" |
| | | . "PHOTO;ENCODING=B:aHR0cDovL3Rlc3QuY29t\n" |
| | | . "END:VCARD" |
| | | ); |
| | | |
| | | $result = $vcard->get_assoc(); |
| | | |
| | | $this->assertCount(1, $result['address:work'], "ITEM1.-prefixed entry"); |
| | | } |
| | | |
| | | function test_import() |
| | | { |
| | | $input = file_get_contents($this->_srcpath('apple.vcf')); |