[TikiWiki-commits] [Git][tikiwiki/tiki][master] [NEW] Webmail: add module to show unread emails

"Victor Emanouilov \(@kroky\) via TikiWiki-cvs" <[email protected]>
Newsgroups gmane.comp.cms.tiki.cvs
Message-ID <690e015465c91_2c709c7082377@gitlab-sidekiq-low-urgency-cpu-bound-v2-75f5bb84f4-xtz4c.mail>

Victor Emanouilov pushed to branch master at Tiki Wiki CMS Groupware / Tiki


Commits:
fc87f2b3 by Josaphat Imani at 2025-11-07T14:15:55+00:00
[NEW] Webmail: add module to show unread emails
---
* Add user preference for source

* Enhance cypht integration in commands and modules

* Add add pref to the module

* [NEW] Webmail: add module to show unread emails

See merge request tikiwiki/tiki!8650

- - - - -


5 changed files:

- lib/core/Tiki/Command/WebmailUnreadGlobalCommand.php
- lib/core/Tiki/Command/WebmailUnreadPagesCommand.php
- lib/cypht/integration/Tiki_Hm_Functions.php
- + modules/mod-func-webmail_unread_messages.php
- + templates/modules/mod-webmail_unread_messages.tpl


Changes:

=====================================
lib/core/Tiki/Command/WebmailUnreadGlobalCommand.php
=====================================
@@ -50,9 +50,6 @@ class WebmailUnreadGlobalCommand extends Command
 
         require_once $tikipath . '/lib/cypht/integration/Tiki_Hm_Functions.php';
 
-        $init = Tiki_Hm_Functions::initCyphtForBackend('servers');
-        extract($init, EXTR_PREFIX_ALL, 'cypht');
-
         $userlib = TikiLib::lib('user');
         $monitorlib = TikiLib::lib('monitor');
         $activitylib = TikiLib::lib('activity');
@@ -80,15 +77,10 @@ class WebmailUnreadGlobalCommand extends Command
 
             foreach ($config['imap_servers'] as $idx => $mailbox) {
                 $output->writeln(tr('Checking account %0', $mailbox['name']));
-                Hm_IMAP_List::add($mailbox, true);
-
-                $output->writeln(tr('Retrieving messages'));
-                $since = date('j-M-Y', $last_timestamp);
-                list($status, $msg_list) = merge_imap_search_results([$idx], 'ALL', $cypht_session, $cypht_cache, ['INBOX'], 1000, [['SINCE', $since]]);
 
-                Hm_IMAP_List::del($idx);
+                list($msg_count, $msg_list) = Tiki_Hm_Functions::getLastUnreadMessageFromMailbox($idx, $mailbox, $last_timestamp);
 
-                if (empty($msg_list)) {
+                if (! $msg_count) {
                     continue;
                 }
 


=====================================
lib/core/Tiki/Command/WebmailUnreadPagesCommand.php
=====================================
@@ -53,8 +53,6 @@ class WebmailUnreadPagesCommand extends Command
 
         require_once $tikipath . '/lib/cypht/integration/Tiki_Hm_Functions.php';
 
-        $cypht = Tiki_Hm_Functions::initCyphtForBackend('servers');
-
         $tikilib = TikiLib::lib('tiki');
         $parserlib = TikiLib::lib('parser');
         $activitylib = TikiLib::lib('activity');
@@ -91,15 +89,9 @@ class WebmailUnreadPagesCommand extends Command
                 // Store last timestamp in plugin body?
 
                 foreach ($body['imap_servers'] as $idx => $mailbox) {
-                    Hm_IMAP_List::add($mailbox, true);
-
-                    $output->writeln(tr('Retrieving messages'));
-                    $since = date('j-M-Y', $last_timestamp);
-                    list($status, $msg_list) = merge_imap_search_results([$idx], 'ALL', $cypht['session'], $cypht['cache'], ['INBOX'], 1000, [['SINCE', $since]]);
-
-                    Hm_IMAP_List::del($idx);
+                    list($msg_count, $msg_list) = Tiki_Hm_Functions::getLastUnreadMessageFromMailbox($idx, $mailbox, $last_timestamp);
 
-                    if (empty($msg_list)) {
+                    if (! $msg_count) {
                         continue;
                     }
 


=====================================
lib/cypht/integration/Tiki_Hm_Functions.php
=====================================
@@ -149,7 +149,7 @@ class Tiki_Hm_Functions
         static $request = null;
 
         if (defined('APP_PATH') && ! empty($config)) {
-            throw new Exception(tr('Cannot initialize Cypht backend when it is already initialized'));
+            return compact('config', 'session', 'cache', 'module_exec', 'request');
         }
 
         if (is_null($config)) {
@@ -192,4 +192,139 @@ class Tiki_Hm_Functions
 
         return $last_timestamp;
     }
+
+    public static function unreadMessageTrackerItems()
+    {
+        global $user;
+
+        $unreadMessages = [];
+
+        $sourcePref = TikiLib::lib('tiki')->get_user_preference($user, 'unread_emails_source', 'all');
+        if (! in_array($sourcePref, ['all', 'trackers'])) {
+            return $unreadMessages;
+        }
+
+        $items = find_relevant_tracker_items('');
+
+        foreach ($items as $item) {
+            $trackerDefinition = Tracker_Definition::get($item['tracker_id']);
+            $itemData = Tracker_Item::fromId($item['object_id'])->getData();
+            $emailFieldHandler = $trackerDefinition->getFieldFactory()->getHandler($trackerDefinition->getField($item['field_id']), $itemData);
+            $values = $emailFieldHandler->getFieldData();
+
+            $unreadCount = 0;
+            foreach ($values['emails']['inbox'] as $email) {
+                if (! array_key_exists('seen', $email['flags'])) {
+                    ++$unreadCount;
+                }
+            }
+
+            if ($unreadCount > 0) {
+                $unreadMessages[] = [
+                    'name' => $item['title'],
+                    'object_id' => $item['object_id'],
+                    'total' => $unreadCount
+                ];
+            }
+        }
+
+        return $unreadMessages;
+    }
+
+    public static function unreadWebmailMessages()
+    {
+        global $user;
+
+        $userPreferences = TikiLib::lib('tiki')->table('tiki_user_preferences');
+        $user_configs = $userPreferences->fetchAll([], [
+            'prefName' => $userPreferences->exactly('cypht_user_config%'),
+            'user' => $userPreferences->like($user)
+        ]);
+
+        return self::unreadMessageGlobal($user_configs);
+    }
+
+    public static function unreadPagesMessages()
+    {
+        global $user;
+
+        $userPreferences = TikiLib::lib('tiki')->table('tiki_user_preferences');
+        $user_configs = $userPreferences->fetchAll([], [
+            'prefName' => $userPreferences->like('cypht_user_config%'),
+            'user' => $userPreferences->like($user)
+        ]);
+
+        foreach ($user_configs as $key => $user_config) {
+            $page = substr($user_config['prefName'], strlen('cypht_user_config'));
+            if (! ltrim($page, '_')) {
+                unset($user_configs[$key]);
+            }
+        }
+
+        return self::unreadMessageGlobal($user_configs);
+    }
+
+    protected static function unreadMessageGlobal($user_configs)
+    {
+        $init = self::initCyphtForBackend('servers');
+
+        $unreadMessages = [];
+        $existingServers = [];
+
+        foreach ($user_configs as $user_config) {
+            $page = substr($user_config['prefName'], strlen('cypht_user_config'));
+            $page = ltrim($page, '_');
+            $page = $page == '' ? 'Main webmail' : $page;
+
+            $config = json_decode($user_config['value'], true);
+
+            foreach ($config['imap_servers'] as $idx => $mailboxDetails) {
+                $unreadCount = 0;
+
+                if (in_array($mailboxDetails['user'], array_keys($existingServers))) {
+                    $unreadCount = $existingServers[$mailboxDetails['user']];
+                } else {
+                    Hm_IMAP_List::add($mailboxDetails, true);
+
+                    $mailbox = Hm_IMAP_List::get_connected_mailbox($idx, $init['cache']);
+                    if (! $mailbox || ! $mailbox->authed()) {
+                        $unreadCount = 'Unknown';
+                    } else {
+                        list($unreadCount, $_) = $mailbox->get_messages('INBOX', 'DATE', false, 'UNSEEN');
+
+                        Hm_IMAP_List::del($idx);
+                    }
+                }
+
+                if ($unreadCount > 0) {
+                    $unreadMessages[$page][] = [
+                        'name' => $mailboxDetails['name'],
+                        'total' => $unreadCount
+                    ];
+                }
+                $existingServers[$mailboxDetails['user']] = $unreadCount;
+            }
+        }
+
+        return $unreadMessages;
+    }
+
+    public static function getLastUnreadMessageFromMailbox($idx, array $mailbox, $last_timestamp)
+    {
+        $cypht = self::initCyphtForBackend('servers');
+
+        Hm_IMAP_List::add($mailbox, true);
+
+        $mailbox = Hm_IMAP_List::get_connected_mailbox($idx, $cypht['cache']);
+        if (! $mailbox || ! $mailbox->authed()) {
+            return [0, []];
+        }
+
+        $since = date('j-M-Y', $last_timestamp);
+        $messages = $mailbox->get_messages('INBOX', 'DATE', false, 'UNSEEN', 0, 1000, [['SINCE', $since]]);
+
+        Hm_IMAP_List::del($idx);
+
+        return $messages;
+    }
 }


=====================================
modules/mod-func-webmail_unread_messages.php
=====================================
@@ -0,0 +1,79 @@
+<?php
+
+// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project
+//
+// All Rights Reserved. See copyright.txt for details and a complete list of authors.
+// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
+function module_webmail_unread_messages_info()
+{
+    return [
+        'name' => tra('Unread emails'),
+        'description' => tra('Display unread messages per email account/tracker item'),
+        'prefs' => ['feature_webmail'],
+        'params' => [
+            'search_refresh_interval' => [
+                'name' => tra('Data refresh interval'),
+                'description' => tra('For performance reasons, wait n minutes before fetching new data again'),
+                'filter' => 'int',
+                'default' => 2
+            ],
+            'sources' => [
+                'name' => tra('Show '),
+                'description' => tra('Limit sources where to check for unread emails'),
+                'filter' => 'alpha',
+                'default' => 'all',
+                'options' => [
+                    ['text' => '', 'value' => ''],
+                    ['text' => tra('All'), 'value' => 'true'],
+                    ['text' => tra('Trackers'), 'value' => 'trackers'],
+                    ['text' => tra('Pages'), 'value' => 'pages'],
+                    ['text' => tra('Main webmail'), 'value' => 'main_webmail']
+                ]
+            ],
+        ]
+    ];
+}
+
+function module_webmail_unread_messages($mod_reference, $module_params)
+{
+    global $tikipath;
+
+    $info = module_webmail_unread_messages_info();
+    $defaults = [];
+    foreach ($info['params'] as $key => $param) {
+        $defaults[$key] = $param['default'];
+    }
+    $module_params = array_merge($defaults, $module_params);
+
+    $smarty = TikiLib::lib('smarty');
+    $cache = TikiLib::lib('cache');
+    $cacheKey = 'tiki_unread_emails';
+
+    if ($_SESSION['webmail_search_refresh_time'] > time() && $cache->isCached($cacheKey, 'system')) {
+        $webmailUnreadMessages = $cache->getSerialized($cacheKey, 'system');
+    } else {
+        require_once $tikipath . '/lib/cypht/integration/Tiki_Hm_Functions.php';
+
+        $webmailUnreadMessages = [];
+        $sourcePref = $module_params['sources'];
+
+        if (in_array($sourcePref, ['all', 'main_webmail'])) {
+            $webmailUnreadMessages['pages'] = Tiki_Hm_Functions::unreadWebmailMessages();
+        }
+        if (in_array($sourcePref, ['all', 'pages'])) {
+            $pages = Tiki_Hm_Functions::unreadPagesMessages();
+            if (isset($webmailUnreadMessages['pages'])) {
+                $pages = array_merge($webmailUnreadMessages['pages'], $pages);
+            }
+            $webmailUnreadMessages['pages'] = $pages;
+        }
+        if (in_array($sourcePref, ['all', 'trackers'])) {
+            $webmailUnreadMessages['tracker_items'] = Tiki_Hm_Functions::unreadMessageTrackerItems();
+        }
+
+        $_SESSION['webmail_search_refresh_time'] = time() + ($module_params['search_refresh_interval'] * 60);
+        $cache->cacheItem($cacheKey, serialize($webmailUnreadMessages), 'system');
+    }
+
+    $smarty->assign('webmailUnreadMessages', $webmailUnreadMessages);
+}


=====================================
templates/modules/mod-webmail_unread_messages.tpl
=====================================
@@ -0,0 +1,35 @@
+{tikimodule error=$module_params.error title=$tpl_module_title name="unread_email_messages" flip=$module_params.flip decorations=$module_params.decorations nobox=$module_params.nobox notitle=$module_params.notitle}
+<div class="table-responsive">
+<table class="table table-condensed">
+    <tbody>
+        {if isset($webmailUnreadMessages['pages']) && $webmailUnreadMessages['pages']|count > 0}
+            <tr>
+                <th colspan="3" class="fw-bold text-uppercase">{tr}pages{/tr}</th>
+            </tr>
+            {foreach from=$webmailUnreadMessages['pages'] key=page_name item=row_value}
+                <tr>
+                    <td class="small fw-bold" colspan="2">{$page_name|capitalize}</td>
+                </tr>
+                {foreach from=$row_value key=row_name item=row}
+                    <tr>
+                        <td colspan="3" class="small"><a href="{$page_name == 'Main webmail'? 'tiki-webmail.php': $page_name|sefurl:'wikipage'}">{$row['name']}</a></td>
+                        <td><span class="badge text-bg-success">{$row['total']}</span></td>
+                    </tr>
+                {/foreach}
+            {/foreach}
+        {/if}
+        {if isset($webmailUnreadMessages['tracker_items']) && $webmailUnreadMessages['tracker_items']|count > 0}
+            <tr>
+                <th colspan="3" class="fw-bold text-uppercase">{tr}tracker items{/tr}</th>
+            </tr>
+            {foreach from=$webmailUnreadMessages['tracker_items'] item=row}
+                <tr>
+                    <td colspan="3" class="small"><a href="{$row['object_id']|sefurl:'trackeritem'}">{$row['name']|escape}</a></td>
+                    <td><span class="badge text-bg-success">{$row['total']}</span></td>
+                </tr>
+            {/foreach}
+        {/if}
+    </tbody>
+</table>
+</div>
+{/tikimodule}



View it on GitLab: https://gitlab.com/tikiwiki/tiki/-/commit/fc87f2b32df891df845e6eb1849b71e30aaf49c3

-- 
View it on GitLab: https://gitlab.com/tikiwiki/tiki/-/commit/fc87f2b32df891df845e6eb1849b71e30aaf49c3
You're receiving this email because of your account on gitlab.com.

_______________________________________________
TikiWiki-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tikiwiki-cvs
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.