[TikiWiki-commits] [Git][tikiwiki/tiki][master] [ENH] Tracker Email Folder field: add ability to search for emails to be moved to tracker item

"Victor Emanouilov \(@kroky\) via TikiWiki-cvs" <[email protected]> Mon, 06 Jul 2026 12:48:13 +0000
Newsgroups gmane.comp.cms.tiki.cvs
Message-ID <6a4ba40da185f_3819a898569e@gitlab-sidekiq-low-urgency-cpu-bound-v2-fd48bd9cc-d59z7.mail>

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


Commits:
c0c18d0a by Josaphat Imani at 2026-07-06T12:29:29+00:00
[ENH] Tracker Email Folder field: add ability to search for emails to be moved to tracker item
---
* [ENH] Tracker folder: search emails to move to tracker item

See merge request tikiwiki/tiki!10249

- - - - -


5 changed files:

- lib/core/Tracker/Field/EmailFolder.php
- lib/cypht/modules/tiki/setup.php
- lib/cypht/modules/tiki/site.js
- lib/cypht/modules/tiki/tracker_modules.php
- templates/trackeroutput/email_folder.tpl


Changes:

=====================================
lib/core/Tracker/Field/EmailFolder.php
=====================================
@@ -296,13 +296,14 @@ class Tracker_Field_EmailFolder extends Tracker_Field_Files implements \Tracker\
         }
 
         if ($compose_page = $this->getOption('composePage')) {
-            $compose_path = smarty_modifier_sefurl($compose_page);
-            if (preg_match("/tiki-index\.php\?page=.*/", $compose_path)) {
-                $compose_path = "tiki-index.php?page_id=" . TikiLib::lib('tiki')->get_page_id_from_name($compose_page);
+            $base_webmail_path = smarty_modifier_sefurl($compose_page);
+            if (preg_match("/tiki-index\.php\?page=.*/", $base_webmail_path)) {
+                $base_webmail_path = "tiki-index.php?page_id=" . TikiLib::lib('tiki')->get_page_id_from_name($compose_page);
             }
         } else {
-            $compose_path = "tiki-webmail.php";
+            $base_webmail_path = "tiki-webmail.php";
         }
+        $compose_path = $base_webmail_path;
         if (str_contains($compose_path, '?')) {
             $compose_path .= '&';
         } else {
@@ -310,6 +311,18 @@ class Tracker_Field_EmailFolder extends Tracker_Field_Files implements \Tracker\
         }
         $compose_path .= "page=compose&list_path=tracker_folder_" . $this->getItemId() . "_" . $this->getConfiguration('fieldId') . "&list_parent=tracker_" . $this->getTrackerDefinition()->getConfiguration('trackerId');
 
+        $search_path = $base_webmail_path;
+        if (str_contains($search_path, '?')) {
+            $search_path .= '&';
+        } else {
+            $search_path .= '?';
+        }
+        $search_path .= "page=search&list_path=tracker_folder_" . $this->getItemId() . "_" . $this->getConfiguration('fieldId')
+            . "&list_parent=tracker_" . $this->getTrackerDefinition()->getConfiguration('trackerId')
+            . "&target_tracker_item_id=" . $this->getItemId()
+            . "&target_tracker_field_id=" . $this->getConfiguration('fieldId')
+            . "&target_tracker_folder=inbox";
+
         TikiLib::lib('header')->add_js_module('import "@tiki/tracker-fields/emailFolder";');
 
         return $this->renderTemplate('trackeroutput/email_folder.tpl', $context, [
@@ -320,6 +333,7 @@ class Tracker_Field_EmailFolder extends Tracker_Field_Files implements \Tracker\
                 return $this->folderHandle($folder);
             }, preg_split('/\s*,\s*/', $this->getOption('openedFolders'))),
             'compose_path' => $compose_path,
+            'search_path' => $search_path,
             'itemId' => $this->getItemId(),
         ]);
     }


=====================================
lib/cypht/modules/tiki/setup.php
=====================================
@@ -156,6 +156,8 @@ add_handler('compose', 'check_path_redirect_after_sent', true, 'smtp', 'tiki_arc
 add_handler('compose', 'tiki_compose_from_draft', true, 'smtp', 'load_smtp_servers_from_config', 'after');
 add_output('message_list', 'add_multiple_move_to_trackers', true, 'imap', 'imap_custom_controls', 'after');
 add_output('search', 'add_multiple_move_to_trackers', true, 'imap', 'search_move_copy_controls', 'after');
+add_handler('search', 'pass_tracker_target_params', true, 'tiki', 'load_user_data', 'after');
+add_output('search', 'search_form_tracker_target_inputs', true, 'tiki', 'search_form_content', 'after');
 add_output('message_list', 'add_multiple_item_to_trackers', true, 'imap', 'imap_custom_controls', 'after');
 add_handler('ajax_smtp_save_draft', 'tiki_presave_draft', true, 'smtp', 'smtp_save_draft', 'before');
 add_handler('ajax_smtp_save_draft', 'tiki_save_draft', true, 'smtp', 'smtp_save_draft', 'after');
@@ -232,8 +234,10 @@ add_output('info', 'server_status_end', true, 'developer', 'server_status_start'
 add_output('info', 'config_map', true, 'developer', 'server_status_end', 'after');
 
 /* folder list */
+add_handler('ajax_hm_folders', 'pass_tracker_target_params', true, 'tiki', 'load_user_data', 'after');
 add_output('ajax_hm_folders', 'info_page_link', true, 'developer', 'settings_menu_end', 'before');
 add_output('ajax_hm_folders', 'combined_trackers_link', true, 'tiki', 'main_menu_content', 'before');
+add_output('ajax_hm_folders', 'append_tracker_params_to_searches', true, 'tiki', 'search_folders', 'after');
 
 /* sieve filters */
 add_handler('sieve_filters', 'tiki_add_sieve_config_host', true, 'tiki', 'load_imap_servers_from_config', 'after');
@@ -287,6 +291,9 @@ return [
   'allowed_get' => [
     'tiki_download_message' => FILTER_VALIDATE_BOOLEAN,
     'tiki_show_message'  => FILTER_VALIDATE_BOOLEAN,
+    'target_tracker_item_id' => FILTER_SANITIZE_FULL_SPECIAL_CHARS,
+    'target_tracker_field_id' => FILTER_SANITIZE_FULL_SPECIAL_CHARS,
+    'target_tracker_folder' => FILTER_SANITIZE_FULL_SPECIAL_CHARS,
   ],
   'allowed_output' => [
     'operator' => [FILTER_SANITIZE_FULL_SPECIAL_CHARS, false],


=====================================
lib/cypht/modules/tiki/site.js
=====================================
@@ -243,6 +243,17 @@ var tiki_enable_oauth2_over_imap = function (){
 };
 
 var tiki_setup_move_to_trackers = function(callback_handler = null) {
+    const targetTrackerItemId = getParam('target_tracker_item_id');
+    const targetTrackerFieldId = getParam('target_tracker_field_id');
+    const targetTrackerFolder = getParam('target_tracker_folder') || 'inbox';
+    const fixedTrackerTarget = targetTrackerItemId && targetTrackerFieldId
+        ? {
+            itemId: targetTrackerItemId,
+            fieldId: targetTrackerFieldId,
+            folder: targetTrackerFolder,
+        }
+        : null;
+
     const handleMoveSuccess = () => {
         if (getMessageUidParam()) {
             Hm_Message_List.prev_next_links(getMessageUidParam(), getParam('list_parent'), function(links) {
@@ -257,8 +268,35 @@ var tiki_setup_move_to_trackers = function(callback_handler = null) {
         }
     };
 
+    const moveSelectedToFixedTracker = async (ids) => {
+        const autoMove = await promptFutureReplyAutoMove();
+        const listPath = getListPathParam() ?? getPageNameParam();
+        Hm_Ajax.request(
+            [{'name': 'hm_ajax_hook', 'value': 'ajax_move_to_tracker'},
+            {'name': 'tracker_field_id', 'value': fixedTrackerTarget.fieldId},
+            {'name': 'tracker_item_id', 'value': fixedTrackerTarget.itemId},
+            {'name': 'imap_msg_ids', 'value': ids},
+            {'name': 'list_path', 'value': listPath},
+            {'name': 'folder', 'value': fixedTrackerTarget.folder},
+            {'name': 'auto_move', 'value': autoMove}],
+            function() {
+                handleMoveSuccess();
+            },
+            [],
+            false
+        );
+    };
+
     $("#move_to_trackers").on("click", function(e) {
         e.preventDefault();
+        if (fixedTrackerTarget) {
+            const ids = selected_ids();
+            if (! ids || ids.length == 0) {
+                return false;
+            }
+            moveSelectedToFixedTracker(ids);
+            return false;
+        }
         showMoveToTrackerModal(handleMoveSuccess);
         return false;
     });


=====================================
lib/cypht/modules/tiki/tracker_modules.php
=====================================
@@ -1248,6 +1248,96 @@ class Hm_Output_pass_redirect_url extends Hm_Output_Module
     }
 }
 
+/**
+ * Pass tracker target params from GET request into output
+ * @subpackage tiki/handler
+ */
+class Hm_Handler_pass_tracker_target_params extends Hm_Handler_Module
+{
+    public function process()
+    {
+        $item_id = intval($this->request->get['target_tracker_item_id'] ?? 0);
+        $field_id = intval($this->request->get['target_tracker_field_id'] ?? 0);
+        $folder = isset($this->request->get['target_tracker_folder'])
+            ? $this->request->get['target_tracker_folder']
+            : 'inbox';
+
+        $this->out('target_tracker_item_id', $item_id);
+        $this->out('target_tracker_field_id', $field_id);
+        $this->out('target_tracker_folder', $folder);
+    }
+}
+
+/**
+ * Add tracker target params as hidden inputs to the search form
+ * @subpackage tiki/output
+ */
+class Hm_Output_search_form_tracker_target_inputs extends Hm_Output_Module
+{
+    protected function output()
+    {
+        $target_tracker_item_id = $this->get('target_tracker_item_id');
+        $target_tracker_field_id = $this->get('target_tracker_field_id');
+        $target_tracker_folder = $this->get('target_tracker_folder');
+
+        if (! ($target_tracker_item_id && $target_tracker_field_id)) {
+            return;
+        }
+
+        return '<input type="hidden" name="target_tracker_item_id" value="' . $target_tracker_item_id . '" />'
+            . '<input type="hidden" name="target_tracker_field_id" value="' . $target_tracker_field_id . '" />'
+            . '<input type="hidden" name="target_tracker_folder" value="' . $this->html_safe($target_tracker_folder) . '" />';
+    }
+}
+
+/**
+ * Append tracker target params to saved search folder URLs
+ * Runs after Hm_Output_search_folders to inject tracker context into saved search links
+ * @subpackage tiki/output
+ */
+class Hm_Output_append_tracker_params_to_searches extends Hm_Output_Module
+{
+    protected function output()
+    {
+        $target_tracker_item_id = $this->get('target_tracker_item_id', false);
+        $target_tracker_field_id = $this->get('target_tracker_field_id', false);
+        $target_tracker_folder = $this->get('target_tracker_folder', 'inbox');
+
+        if (! ($target_tracker_item_id && $target_tracker_field_id)) {
+            return;
+        }
+
+        $folder_sources = $this->get('folder_sources', []);
+        if (! is_array($folder_sources) || empty($folder_sources)) {
+            return;
+        }
+
+        foreach ($folder_sources as $key => &$source) {
+            if (is_array($source) && count($source) >= 2 && $source[0] === 'search_folders') {
+                $html = $source[1];
+
+                $param_string = '&target_tracker_item_id=' . $target_tracker_item_id
+                    . '&target_tracker_field_id=' . $target_tracker_field_id
+                    . '&target_tracker_folder=' . urlencode($target_tracker_folder);
+
+                // Replace href patterns in search links
+                // Match: href="?page=search..."
+                $html = preg_replace_callback(
+                    '/(href=")([^"]*page=search[^"]*)(")/i',
+                    function ($matches) use ($param_string) {
+                        return $matches[1] . $matches[2] . $param_string . $matches[3];
+                    },
+                    $html
+                );
+
+                $source[1] = $html;
+            }
+        }
+
+        $this->out('folder_sources', $folder_sources);
+    }
+}
+
 /**
  * @subpackage smtp/handler
  */


=====================================
templates/trackeroutput/email_folder.tpl
=====================================
@@ -1,6 +1,7 @@
 <div id="display_f{$field.fieldId|escape}" class="email-folder-field display_f{$field.fieldId|escape}">
     {if $tiki_p_use_webmail eq 'y'}
         <a href="{$data.compose_path}" class="btn btn-secondary btn-sm rounded-pill">{tr}Compose{/tr}</a>
+        <a href="{$data.search_path}" class="btn btn-outline-secondary btn-sm rounded-pill">{tr}Search Emails{/tr}</a>
     {/if}
     {if $data.count eq 0}
         {tr}Emails can be copied or moved here via the Webmail interface.{/tr}



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

-- 
View it on GitLab: https://gitlab.com/tikiwiki/tiki/-/commit/c0c18d0a86cb1b74865f3b98e9c151ec41e315e1
You're receiving this email because of your account on gitlab.com. Manage all notifications: https://gitlab.com/-/profile/notifications | Help: https://gitlab.com/help

_______________________________________________
TikiWiki-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tikiwiki-cvs