diff --git a/CHANGELOG b/CHANGELOG index 7938f56ba..44b7be708 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ CHANGELOG Roundcube Webmail =========================== +- Possibility to display QR code for contacts data (#5030) - Added identicon plugin - Widescreen layout aka three column view (#5093) - Unify automatic marking as \Seen in preview pane, full-page and extwin views (#5071) diff --git a/INSTALL b/INSTALL index a27484480..043398e6b 100644 --- a/INSTALL +++ b/INSTALL @@ -24,6 +24,7 @@ REQUIREMENTS - Auth_SASL 1.0.6 or newer - Net_Sieve 1.3.2 or newer (for managesieve plugin) - Crypt_GPG 1.6.0 or newer (for enigma plugin) + - Endroid/QrCode 1.6.0 or newer (https://github.com/endroid/QrCode) * php.ini options (see .htaccess file): - error_reporting E_ALL & ~E_NOTICE & ~E_STRICT - memory_limit > 16MB (increase as suitable to support large attachments) diff --git a/composer.json-dist b/composer.json-dist index 07cec526d..43bd20c9a 100644 --- a/composer.json-dist +++ b/composer.json-dist @@ -30,7 +30,8 @@ "pear-pear.php.net/mail_mime": "~1.10.0", "pear-pear.php.net/net_smtp": "~1.7.1", "pear-pear.php.net/crypt_gpg": "~1.6.0@beta", - "roundcube/net_sieve": "~1.5.0" + "roundcube/net_sieve": "~1.5.0", + "endroid/qrcode": "~1.6.5" }, "require-dev": { "phpunit/phpunit": "*" diff --git a/program/js/app.js b/program/js/app.js index f193496e6..892ee6a63 100644 --- a/program/js/app.js +++ b/program/js/app.js @@ -474,7 +474,7 @@ function rcube_webmail() this.set_page_buttons(); if (this.env.cid) { - this.enable_command('show', 'edit', true); + this.enable_command('show', 'edit', 'qrcode', true); // register handlers for group assignment via checkboxes if (this.gui_objects.editform) { $('input.groupmember').change(function() { @@ -6632,6 +6632,24 @@ function rcube_webmail() this.http_request('search', {_sid: id}, lock); }; + // display a dialog with QR code image + this.qrcode = function() + { + var title = this.get_label('qrcode'), + buttons = [{ + text: this.get_label('close'), + 'class': 'mainaction', + click: function() { + (ref.is_framed() ? parent.$ : $)(this).dialog('destroy'); + } + }], + img = new Image(300, 300); + + img.src = this.url('addressbook/qrcode', {_source: this.env.source, _cid: this.env.cid}); + + return this.show_popup_dialog(img, title, buttons, {width: 310, height: 410}); + }; + /*********************************************************/ /********* user settings methods *********/ diff --git a/program/localization/en_US/labels.inc b/program/localization/en_US/labels.inc index 043ea2ff2..acfe45b92 100644 --- a/program/localization/en_US/labels.inc +++ b/program/localization/en_US/labels.inc @@ -369,6 +369,7 @@ $labels['advsearch'] = 'Advanced Search'; $labels['advanced'] = 'Advanced'; $labels['other'] = 'Other'; $labels['printcontact'] = 'Print contact'; +$labels['qrcode'] = 'QR Code'; $labels['typehome'] = 'Home'; $labels['typework'] = 'Work'; diff --git a/program/steps/addressbook/qrcode.inc b/program/steps/addressbook/qrcode.inc new file mode 100644 index 000000000..73f098956 --- /dev/null +++ b/program/steps/addressbook/qrcode.inc @@ -0,0 +1,75 @@ + | + +-----------------------------------------------------------------------+ +*/ + +// Get contact ID and source ID from request +$cids = rcmail_get_cids(); +$source = key($cids); +$cid = $cids ? array_shift($cids[$source]) : null; + +// read contact record +$abook = rcmail_contact_source($source, true); +$contact = $abook->get_record($cid, true); + +// generate QR code image +if ($data = rcmail_contact_qrcode($contact)) { + header('Content-Type: image/png'); + header('Content-Length: ' . strlen($data)); + echo $data; +} +else { + header('HTTP/1.0 404 Contact not found'); +} + +exit; + + +function rcmail_contact_qrcode($contact) +{ + $vcard = new rcube_vcard(); + + // QR code input is limited, use only common fields + $fields = array('firstname', 'surname', 'middlename', 'nickname', 'organization', + 'prefix', 'suffix', 'phone', 'email', 'jobtitle'); + + foreach ($contact as $field => $value) { + list($field, $section) = explode(':', $field, 2); + if (in_array($field, $fields)) { + foreach ((array) $value as $v) { + $vcard->set($field, $v, $section); + } + } + } + + $data = $vcard->export(); + + $qrCode = new Endroid\QrCode\QrCode(); + $qrCode + ->setText($data) + ->setSize(300) + ->setPadding(0) + ->setErrorCorrection('high') + // ->setLabel('Scan the code') + // ->setLabelFontSize(16) + ->setForegroundColor(array('r' => 0, 'g' => 0, 'b' => 0, 'a' => 0)) + ->setBackgroundColor(array('r' => 255, 'g' => 255, 'b' => 255, 'a' => 0)); + + return $qrCode->get('png'); +} diff --git a/program/steps/addressbook/show.inc b/program/steps/addressbook/show.inc index f8755c48a..da8f5bf90 100644 --- a/program/steps/addressbook/show.inc +++ b/program/steps/addressbook/show.inc @@ -42,6 +42,7 @@ if ($cid && ($record = ($CONTACT_RECORD ?: $CONTACTS->get_record($cid, true)))) // get address book name (for display) rcmail_set_sourcename($CONTACTS); +$OUTPUT->add_label('qrcode'); $OUTPUT->add_handlers(array( 'contacthead' => 'rcmail_contact_head', 'contactdetails' => 'rcmail_contact_details', diff --git a/skins/classic/templates/contact.html b/skins/classic/templates/contact.html index 8be112b49..2022a2ce0 100644 --- a/skins/classic/templates/contact.html +++ b/skins/classic/templates/contact.html @@ -21,6 +21,7 @@

+

diff --git a/skins/larry/templates/contact.html b/skins/larry/templates/contact.html index 59fe6f79f..de42e1a9d 100644 --- a/skins/larry/templates/contact.html +++ b/skins/larry/templates/contact.html @@ -25,6 +25,7 @@
+