So I recently came across a need to implement a call to imap_thread from
PHP-space, and being as PHP did not support a call to imap_thread, so I
implemented one that explicitly did a REFERENCES threading, and returned
the thread tree in the form of a hash with three types of entries...

"#.num" which is the IMAP message ID of the message for threadnode ID #
"#.branch" and "#.next" which correspond to the same things in the C
THREADNODE structure and point to the next #.

The tree is rooted at # == 0.

I'm almost certain there has to be a better way to represent the tree in
PHP, but at first glance references didn't seem to be able to do what I
wanted.  Also, the function I wrote (though it could trivially be
expanded) only called the REFERENCES method, not the ORDEREDSUBJECT
method.

Attached is a patch against the 4.0.4pl1 source tree, but I don't think
that there should be severe difficulties in applying it to any recent
version.  I'm not sure it conforms to all of the PHP coding standards,
but I guess you can consider it a first draft/attempt at a submission.

-Rob

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Rob Siemborski * [EMAIL PROTECTED] * WRCT 88.3fm - Chief Engineer
Andrew Systems Group * Cyert Hall 235 * 412-CMU-TREK
-----BEGIN GEEK CODE BLOCK----
Version: 3.12
GCS/IT/CM/CC/PA d- s+: a-- C++++$ UBLS++++$ P+++$ L++(+++) E W- N- o?
K- w O- M-- V-- PS+ PE++ Y+ PGP t+@ 5+++ R@ tv-- b+ DI+++ G e h r- y?
------END GEEK CODE BLOCK-----

--- php_imap.c.dist     Fri Jan 19 14:22:54 2001
+++ php_imap.c  Thu Mar 15 16:24:03 2001
@@ -146,6 +146,7 @@
        PHP_FE(imap_utf7_encode,        NULL)
        PHP_FE(imap_utf8,               NULL)
        PHP_FE(imap_mime_header_decode, NULL)
+       PHP_FE(imap_thread, NULL)
        {NULL, NULL, NULL}
 };
 
@@ -4132,3 +4133,103 @@
 void mm_fatal(char *str)
 {
 }
+
+/* Added imap_thread functionality */
+/* stealing this from header cclient -rjs3 */
+THREADNODE *imap_thread (MAILSTREAM *stream,char *type,char *charset,
+   SEARCHPGM *spg,long flags);
+
+void build_thread_tree_helper(THREADNODE *cur, zval *tree, long *numNodes, char *buf) 
+{
+       unsigned long thisNode = *numNodes;
+
+       /* define "#.num" */
+       snprintf(buf,25,"%ld.num", thisNode);
+
+       add_assoc_long(tree,buf,cur->num);
+
+       snprintf(buf,25,"%ld.next", thisNode);
+       if(cur->next) {
+           (*numNodes)++;
+           add_assoc_long(tree,buf,*numNodes);
+           build_thread_tree_helper(cur->next, tree, numNodes, buf);
+       } else { /* "null pointer" */
+           add_assoc_long(tree,buf,0);
+       }
+
+       snprintf(buf,25,"%ld.branch", thisNode);
+       if(cur->branch) {
+           (*numNodes)++;
+           add_assoc_long(tree,buf,*numNodes);
+           build_thread_tree_helper(cur->branch, tree, numNodes, buf);     
+       } else { /* "null pointer" */
+           add_assoc_long(tree,buf,0);
+       }
+}
+
+int build_thread_tree(THREADNODE *top, zval **tree) {
+       long numNodes = 0;
+       char buf[25];
+
+       if(array_init(*tree) != SUCCESS) return FAILURE;
+       
+       build_thread_tree_helper(top, *tree, &numNodes, buf);
+
+       return SUCCESS;
+}
+
+/* {{{ proto int imap_thread(int stream_id)
+   Return threaded by REFERENCES tree */
+PHP_FUNCTION (imap_thread)
+{
+       pval *streamind, *search_flags;
+       int ind, ind_type, args;
+       pils *imap_le_struct;
+       long flags;
+       char criteria[] = "ALL";
+        THREADNODE *top;
+
+       if(!return_value_used) {
+               php_error(E_WARNING, "imap_thread does not make use of return value");
+               RETURN_FALSE;
+       }
+
+       args = ARG_COUNT(ht);
+       if (  args < 1 || args > 2
+          || getParameters(ht, args, &streamind, &search_flags) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       
+       convert_to_long(streamind);
+       
+       if (args == 1) {
+               flags = SE_FREE;
+       } else {
+               convert_to_long(search_flags);
+               flags = search_flags->value.lval;
+       }
+       
+       ind = streamind->value.lval;
+       imap_le_struct = (pils *)zend_list_find(ind, &ind_type);
+       if (!imap_le_struct || !IS_STREAM(ind_type)) {
+               php_error(E_WARNING, "Unable to find stream pointer");
+               RETURN_FALSE;
+       }
+       
+       top = mail_thread(imap_le_struct->imap_stream,
+               "REFERENCES", NIL, mail_criteria(criteria), flags);
+
+       if(top == NIL) {
+               php_error(E_WARNING, "imap_thread returned an empty tree");
+               RETURN_FALSE;
+       }
+
+       /* Populate our return value data structure here. */
+       if(build_thread_tree(top, &return_value) == FAILURE){
+           mail_free_threadnode(&top);
+           RETURN_FALSE;
+       }
+       
+       mail_free_threadnode(&top);
+}
+/* }}} */
+/* end IMAP_THREAD functionality */
-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
To contact the list administrators, e-mail: [EMAIL PROTECTED]

Reply via email to