diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..723ef36 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea \ No newline at end of file diff --git a/composer.json b/composer.json index 51d3149..528e8a5 100644 --- a/composer.json +++ b/composer.json @@ -1,10 +1,10 @@ { - "name": "ss88/easy_unsubscribe", + "name": "stuzer05/roundcube-easy-unsubscribe", "type": "roundcube-plugin", "description": "Displays a small icon after the subject line when viewing an email, so you can very quickly unsubscribe.", "license": "GPL-3.0+", "keywords": ["unsubscribe","subscription", "newsletter", "mailer"], - "homepage": "https://github.com/SS88UK/roundcube-easy-unsubscribe", + "homepage": "https://gitea.stuzer.link/stuzer05/roundcube-easy-unsubscribe", "require": { "roundcube/plugin-installer": ">=0.1.6" } diff --git a/easy_unsubscribe.css b/easy_unsubscribe.css index 44be9a4..0a96e72 100644 --- a/easy_unsubscribe.css +++ b/easy_unsubscribe.css @@ -1,8 +1,12 @@ -.easy_unsubscribe_link img { height: 13px; margin-left: 10px; vertical-align: middle; opacity: 0.5; transition:all 0.3s ease; } -.easy_unsubscribe_link:hover img { opacity:1; } +.easy_unsubscribe_link img { + height: 20px; + margin-left: 10px; + vertical-align: middle; + opacity: 0.5; + transition: all 0.3s ease; + cursor: pointer; +} -/** - * Tooltip Styles - */ - -.tooltip,[data-tooltip]{position:relative;cursor:pointer}.tooltip:after,.tooltip:before,[data-tooltip]:after,[data-tooltip]:before{position:absolute;visibility:hidden;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";filter:alpha(Opacity=0);opacity:0;-webkit-transition:opacity .2s ease-in-out,visibility .2s ease-in-out,-webkit-transform .2s cubic-bezier(.71,1.7,.77,1.24);-moz-transition:opacity .2s ease-in-out,visibility .2s ease-in-out,-moz-transform .2s cubic-bezier(.71,1.7,.77,1.24);transition:opacity .2s ease-in-out,visibility .2s ease-in-out,transform .2s cubic-bezier(.71,1.7,.77,1.24);-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);transform:translate3d(0,0,0);pointer-events:none}.tooltip:focus:after,.tooltip:focus:before,.tooltip:hover:after,.tooltip:hover:before,[data-tooltip]:focus:after,[data-tooltip]:focus:before,[data-tooltip]:hover:after,[data-tooltip]:hover:before{visibility:visible;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";filter:alpha(Opacity=100);opacity:1}.tooltip:before,[data-tooltip]:before{z-index:1001;border:6px solid transparent;background:0 0;content:""}.tooltip:after,[data-tooltip]:after{z-index:1000;padding:5px 10px;width:160px;background-color:#000;background-color:hsla(0,0%,20%,.9);color:#fff;content:attr(data-tooltip);font-size:11px;line-height:11px}.tooltip-top:after,.tooltip-top:before,.tooltip:after,.tooltip:before,[data-tooltip]:after,[data-tooltip]:before{bottom:100%;left:50%}.tooltip-top:before,.tooltip:before,[data-tooltip]:before{margin-left:-6px;margin-bottom:-12px;border-top-color:#000;border-top-color:hsla(0,0%,20%,.9)}.tooltip-right:after,.tooltip-right:before{bottom:50%;left:100%}.tooltip-right:before{margin-bottom:0;margin-left:-12px;border-top-color:transparent;border-right-color:#000;border-right-color:hsla(0,0%,20%,.9)}.tooltip-right:focus:after,.tooltip-right:focus:before,.tooltip-right:hover:after,.tooltip-right:hover:before{-webkit-transform:translateX(12px);-moz-transform:translateX(12px);transform:translateX(12px)}.tooltip-left:before,.tooltip-right:before{top:3px}.tooltip-left:after,.tooltip-right:after{margin-left:0;margin-bottom:-10px} +.easy_unsubscribe_link:hover img { + opacity: 1; +} \ No newline at end of file diff --git a/easy_unsubscribe.php b/easy_unsubscribe.php index 33fbbd7..7690c08 100644 --- a/easy_unsubscribe.php +++ b/easy_unsubscribe.php @@ -7,6 +7,9 @@ class easy_unsubscribe extends rcube_plugin { private $unsubscribe_img; function init() { + ini_set('display_errors', '1'); + ini_set('display_startup_errors', '1'); + error_reporting(E_ALL); $rcmail = rcmail::get_instance(); $layout = $rcmail->config->get('layout'); @@ -20,41 +23,64 @@ class easy_unsubscribe extends rcube_plugin { $this->add_texts('localization/'); $rcmail->output->add_label('easy_unsubscribe.confirm'); - } public function storage_init($p) { - + $p['fetch_body'] = true; $p['fetch_headers'] = trim($p['fetch_headers'] . ' ' . strtoupper('List-Unsubscribe')); return $p; } - - public function message_headers($p) { - if($this->message_headers_done===false) { + public function decodeMimeHeader($header) { + $elements = imap_mime_header_decode($header); + + return array_reduce($elements, function ($carry, $element) { + return $carry . $element->text; + }, ''); + } + + public function extractUnsubscribeUrls($content) { + $pattern = '/https?:\/\/[^\s"\'<>]+\/[^\s"\'<>]*unsubscribe[^\s"\'<>]*/i'; + preg_match_all($pattern, $content, $matches); + return $matches[0]; + } + + + public function message_headers($p) { + if($this->message_headers_done === false) { $this->message_headers_done = true; if(!isset($p['headers']->others['list-unsubscribe'])) return $p; - - $ListUnsubscribe = $p['headers']->others['list-unsubscribe']; + $urls = []; + + $rcmail = rcmail::get_instance(); + $body = $rcmail->storage->get_body($p['uid']); + + $urls = array_merge($urls, $this->extractUnsubscribeUrls($body)); + + $ListUnsubscribe = $this->decodeMimeHeader($p['headers']->others['list-unsubscribe']); if (preg_match_all('/<(.+)>/mU', $ListUnsubscribe, $items, PREG_PATTERN_ORDER)) { - foreach ( $items[1] as $uri ) { - - $this->unsubscribe_img .= '' . $this->gettext('unsubscribe') . ''; - + $urls[] = $uri; } } + $urls = array_unique($urls); + + foreach ($urls as $uri) { + if (str_contains($uri, 'mailto')) continue; + if (!str_contains($uri, '?')) continue; + + $this->unsubscribe_img .= '' . $this->gettext('unsubscribe') . ''; + } + } if(isset($p['output']['subject'])) { - $p['output']['subject']['value'] = $p['output']['subject']['value'] . $this->unsubscribe_img; $p['output']['subject']['html'] = 1; - } return $p; diff --git a/icon.png b/icon.png index 9349467..b662466 100644 Binary files a/icon.png and b/icon.png differ diff --git a/localization/en_US.inc b/localization/en_US.inc index ccdd683..9a7665a 100644 --- a/localization/en_US.inc +++ b/localization/en_US.inc @@ -2,6 +2,5 @@ $labels = array(); -$labels['click_to_unsubscribe'] = "Click to unsubscribe"; $labels['confirm'] = "Are you sure you want to unsubscribe?"; $labels['unsubscribe'] = "Unsubscribe"; diff --git a/localization/es_ES.inc b/localization/es_ES.inc index 29c45d4..0e5a113 100644 --- a/localization/es_ES.inc +++ b/localization/es_ES.inc @@ -2,6 +2,5 @@ $labels = array(); -$labels['click_to_unsubscribe'] = "Haz click para anular la suscripción"; $labels['confirm'] = "¿Estás seguro de que deseas anular la suscripción?"; $labels['unsubscribe'] = "Anular suscripción"; diff --git a/localization/ru_RU.inc b/localization/ru_RU.inc index 964f96c..aa797aa 100644 --- a/localization/ru_RU.inc +++ b/localization/ru_RU.inc @@ -2,6 +2,5 @@ $labels = array(); -$labels['click_to_unsubscribe'] = "Нажмите, чтобы отписаться"; $labels['confirm'] = "Вы уверены, что хотите отказаться от подписки?"; $labels['unsubscribe'] = "Отписаться";