Here's the patch inline:

diff -u --recursive ../orig/php-5.2.12/ext/imap/php_imap.c ./ext/imap/php_imap.c
--- ../orig/php-5.2.12/ext/imap/php_imap.c      2009-09-22 14:18:57.000000000 
-0400
+++ ./ext/imap/php_imap.c       2010-02-03 14:16:41.000000000 -0500
@@ -152,6 +152,9 @@
        PHP_FE(imap_timeout,                                                    
        NULL)
 
 #if defined(HAVE_IMAP2000) || defined(HAVE_IMAP2001)
+       PHP_FE(imap_searchprogram_new,                                          
                NULL)
+       PHP_FE(imap_searchprogram_or,                                           
                NULL)
+       PHP_FE(imap_searchprogram_setcriterion,                                 
                        NULL)
        PHP_FE(imap_get_quota,                                                  
NULL)
        PHP_FE(imap_get_quotaroot,                                              
NULL)
        PHP_FE(imap_set_quota,                                                  
NULL)
@@ -209,6 +212,7 @@
 
 /* True globals, no need for thread safety */
 static int le_imap;
+static int le_imap_searchpgm;
 
 #define PHP_IMAP_CHECK_MSGNO(msgindex) \
        if ((msgindex < 1) || ((unsigned) msgindex > 
imap_le_struct->imap_stream->nmsgs)) {     \
@@ -673,6 +677,7 @@
        */
 
        le_imap = zend_register_list_destructors_ex(mail_close_it, NULL, 
"imap", module_number);
+       le_imap_searchpgm = zend_register_list_destructors_ex(NULL, NULL, 
"imapsearchpgm", module_number);
        return SUCCESS;
 }
 /* }}} */
@@ -3693,7 +3698,9 @@
        char *search_criteria;
        MESSAGELIST *cur;
        int argc = ZEND_NUM_ARGS();
+       int criteria_is_string;
        SEARCHPGM *pgm = NIL;
+       pisearchpgms *php_searchpgm;
 
        if (argc < 2 || argc > 4 || zend_get_parameters_ex(argc, &streamind, 
&criteria, &search_flags, &charset) == FAILURE) {
                ZEND_WRONG_PARAM_COUNT();
@@ -3701,8 +3708,25 @@
 
        ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", 
le_imap);
 
-       convert_to_string_ex(criteria);
-       search_criteria = estrndup(Z_STRVAL_PP(criteria), 
Z_STRLEN_PP(criteria));
+       switch (Z_TYPE_PP(criteria)) {
+               case IS_STRING:
+                       convert_to_string_ex(criteria);
+                       search_criteria = estrndup(Z_STRVAL_PP(criteria), 
Z_STRLEN_PP(criteria));
+                       pgm = mail_criteria(search_criteria);
+                       criteria_is_string=1;
+                       break;
+
+               case IS_RESOURCE:
+                       ZEND_FETCH_RESOURCE(php_searchpgm, pisearchpgms *, 
criteria, -1, "imapsearchpgm", le_imap_searchpgm);
+                       pgm = php_searchpgm->searchpgm;
+                       criteria_is_string=0;
+                       break;
+
+               default:
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Second 
argumented is expected to be either a string or a searchprogram resource, %s 
given", zend_zval_type_name(*criteria));
+                        RETURN_FALSE;
+       }
+                       
 
        if (argc == 2) {
                flags = SE_FREE;
@@ -3714,17 +3738,18 @@
                }
        }
 
-       pgm = mail_criteria(search_criteria);
        IMAPG(imap_messages) = IMAPG(imap_messages_tail) = NIL;
 
        mail_search_full(imap_le_struct->imap_stream, (argc == 4 ? 
Z_STRVAL_PP(charset) : NIL), pgm, flags);
 
-       if (pgm && !(flags & SE_FREE)) {
+       if (pgm && criteria_is_string && !(flags & SE_FREE)) {
                mail_free_searchpgm(&pgm);
        }
 
        if (IMAPG(imap_messages) == NIL) {
-               efree(search_criteria);
+               if (criteria_is_string) {
+                       efree(search_criteria);
+               }
                RETURN_FALSE;
        }
 
@@ -3736,7 +3761,9 @@
                cur = cur->next;
        }
        mail_free_messagelist(&IMAPG(imap_messages), 
&IMAPG(imap_messages_tail));
-       efree(search_criteria);
+       if (criteria_is_string) {
+               efree(search_criteria);
+       }
 }
 /* }}} */
 
@@ -4425,6 +4452,148 @@
 }
 /* }}} */
 
+/* {{{ proto mixed imap_search_program_new()
+   Get new search program */
+PHP_FUNCTION(imap_searchprogram_new)
+{
+       pisearchpgms *php_searchpgm;
+
+       if (ZEND_NUM_ARGS() != 0) {
+               ZEND_WRONG_PARAM_COUNT();
+       }
+
+       php_searchpgm = emalloc(sizeof(pisearchpgms));
+       php_searchpgm->searchpgm = mail_newsearchpgm();
+       ZEND_REGISTER_RESOURCE(return_value, php_searchpgm, le_imap_searchpgm);
+}
+/* }}} */
+
+PHP_FUNCTION(imap_searchprogram_or)
+{
+       zval **zpgm1, **zpgm2;
+       pisearchpgms *php_searchpgm_or;
+       pisearchpgms *php_searchpgm_1;
+       pisearchpgms *php_searchpgm_2;
+
+       if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &zpgm1, &zpgm2) 
== FAILURE) {
+               ZEND_WRONG_PARAM_COUNT();
+       }
+
+       ZEND_FETCH_RESOURCE(php_searchpgm_1, pisearchpgms *, zpgm1, -1, 
"imapsearchpgm", le_imap_searchpgm);
+       ZEND_FETCH_RESOURCE(php_searchpgm_2, pisearchpgms *, zpgm2, -1, 
"imapsearchpgm", le_imap_searchpgm);
+
+       php_searchpgm_or = emalloc(sizeof(pisearchpgms));
+       php_searchpgm_or->searchpgm = mail_newsearchpgm();
+       php_searchpgm_or->searchpgm->or = mail_newsearchor();
+       php_searchpgm_or->searchpgm->or->first = php_searchpgm_1->searchpgm;
+       php_searchpgm_or->searchpgm->or->second = php_searchpgm_2->searchpgm;
+       ZEND_REGISTER_RESOURCE(return_value, php_searchpgm_or, 
le_imap_searchpgm);
+}
+
+PHP_FUNCTION(imap_searchprogram_setcriterion)
+{
+       zval **zpgm, **criterion_name, **criterion_value;
+       pisearchpgms *php_searchpgm;
+       char *search_criterion_name;
+       char *search_criterion_value;
+       int argc = ZEND_NUM_ARGS();
+       int f=0;
+
+       if (argc < 2 || argc > 3 || zend_get_parameters_ex(argc, &zpgm, 
&criterion_name, &criterion_value) == FAILURE) {
+               ZEND_WRONG_PARAM_COUNT();
+       }
+
+       ZEND_FETCH_RESOURCE(php_searchpgm, pisearchpgms *, zpgm, -1, 
"imapsearchpgm", le_imap_searchpgm);
+
+       convert_to_string_ex(criterion_name);
+       search_criterion_name = estrndup(Z_STRVAL_PP(criterion_name), 
Z_STRLEN_PP(criterion_name));
+       if (argc == 3) {
+               convert_to_string_ex(criterion_value);
+               search_criterion_value = estrndup(Z_STRVAL_PP(criterion_value), 
Z_STRLEN_PP(criterion_value));
+       }
+
+       // this comes from mail.c and imapd.c
+       switch (*ucase (search_criterion_name)) {
+               case 'A':                       /* possible ALL, ANSWERED */
+                       if (!strcmp (search_criterion_name+1,"LL")) f = 1;
+                       else if (!strcmp (search_criterion_name+1,"NSWERED")) f 
= php_searchpgm->searchpgm->answered = 1;
+                       break;
+               case 'B':                       /* possible BCC, BEFORE, BODY */
+                       if (!strcmp (search_criterion_name+1,"CC"))
+                               f = mail_criteria_string 
(&php_searchpgm->searchpgm->bcc,&search_criterion_value);
+                       else if (!strcmp (search_criterion_name+1,"EFORE"))
+                               f = mail_criteria_date 
(&php_searchpgm->searchpgm->before,&search_criterion_value);
+                       else if (!strcmp (search_criterion_name+1,"ODY"))
+                               f = mail_criteria_string 
(&php_searchpgm->searchpgm->body,&search_criterion_value);
+                       break;
+               case 'C':                       /* possible CC */
+                       if (!strcmp (search_criterion_name+1,"C")) f = 
mail_criteria_string (&php_searchpgm->searchpgm->cc,&search_criterion_value);
+                       break;
+               case 'D':                       /* possible DELETED, DRAFT */
+                       if (!strcmp (search_criterion_name+1,"ELETED")) f = 
php_searchpgm->searchpgm->deleted = 1;
+                       else if (!strcmp (search_criterion_name+1,"RAFT")) f = 
php_searchpgm->searchpgm->draft = 1;
+                       break;
+               case 'F':                       /* possible FLAGGED, FROM */
+                       if (!strcmp (search_criterion_name+1,"LAGGED")) f = 
php_searchpgm->searchpgm->flagged = 1;
+                       else if (!strcmp (search_criterion_name+1,"ROM"))
+                               f = mail_criteria_string 
(&php_searchpgm->searchpgm->from,&search_criterion_value);
+                       break;
+               case 'K':                       /* possible KEYWORD */
+                       if (!strcmp (search_criterion_name+1,"EYWORD"))
+                               f = mail_criteria_string 
(&php_searchpgm->searchpgm->keyword,&search_criterion_value);
+                       break;
+               case 'N':                       /* possible NEW */
+                       if (!strcmp (search_criterion_name+1,"EW")) f = 
php_searchpgm->searchpgm->recent = php_searchpgm->searchpgm->unseen = 1;
+                       break;
+               case 'O':                       /* possible OLD, ON */
+                       if (!strcmp (search_criterion_name+1,"LD")) f = 
php_searchpgm->searchpgm->old = 1;
+                       else if (!strcmp (search_criterion_name+1,"N"))
+                               f = mail_criteria_date 
(&php_searchpgm->searchpgm->on,&search_criterion_value);
+                       break;
+               case 'R':                       /* possible RECENT */
+                       if (!strcmp (search_criterion_name+1,"ECENT")) f = 
php_searchpgm->searchpgm->recent = 1;
+                       break;
+               case 'S':                       /* possible SEEN, SENTBEFORE, 
SENTON, SENTSINCE, SINCE, SUBJECT */
+                       if (!strcmp (search_criterion_name+1,"EEN")) f = 
php_searchpgm->searchpgm->seen = 1;
+                       else if (!strcmp (search_criterion_name+1,"ENTBEFORE"))
+                               f = mail_criteria_date 
(&php_searchpgm->searchpgm->sentbefore,&search_criterion_value);
+                       else if (!strcmp (search_criterion_name+1,"ENTON"))
+                               f = mail_criteria_date 
(&php_searchpgm->searchpgm->senton,&search_criterion_value);
+                       else if (!strcmp (search_criterion_name+1,"ENTSINCE"))
+                               f = mail_criteria_date 
(&php_searchpgm->searchpgm->sentsince,&search_criterion_value);
+                       else if (!strcmp (search_criterion_name+1,"INCE"))
+                               f = mail_criteria_date 
(&php_searchpgm->searchpgm->since,&search_criterion_value);
+                       else if (!strcmp (search_criterion_name+1,"UBJECT"))
+                               f = mail_criteria_string 
(&php_searchpgm->searchpgm->subject,&search_criterion_value);
+                       break;
+               case 'T':                       /* possible TEXT, TO */
+                       if (!strcmp (search_criterion_name+1,"EXT"))
+                               f = mail_criteria_string 
(&php_searchpgm->searchpgm->text,&search_criterion_value);
+                       else if (!strcmp (search_criterion_name+1,"O"))
+                               f = mail_criteria_string 
(&php_searchpgm->searchpgm->to,&search_criterion_value);
+                       break;
+               case 'U':                       /* possible UN* */
+                       if (search_criterion_name[1] == 'N') {
+                               if (!strcmp 
(search_criterion_name+2,"ANSWERED")) f = php_searchpgm->searchpgm->unanswered 
= 1;
+                                       else if (!strcmp 
(search_criterion_name+2,"DELETED")) f = php_searchpgm->searchpgm->undeleted = 
1;
+                                       else if (!strcmp 
(search_criterion_name+2,"DRAFT")) f = php_searchpgm->searchpgm->undraft = 1;
+                                       else if (!strcmp 
(search_criterion_name+2,"FLAGGED")) f = php_searchpgm->searchpgm->unflagged = 
1;
+                                       else if (!strcmp 
(search_criterion_name+2,"KEYWORD"))
+                                               f = mail_criteria_string 
(&php_searchpgm->searchpgm->unkeyword,&search_criterion_value);
+                                       else if (!strcmp 
(search_criterion_name+2,"SEEN")) f = php_searchpgm->searchpgm->unseen = 1;
+                               }
+                               break;
+               default:                        /* we will barf below */
+                               break;
+       }
+
+       if (! f) {
+               RETURN_FALSE;
+       }
+       RETURN_TRUE;
+}
+
+
 #define GETS_FETCH_SIZE 8196LU
 /* {{{ php_mail_gets */
 static char *php_mail_gets(readfn_t f, void *stream, unsigned long size, 
GETS_DATA *md)
diff -u --recursive ../orig/php-5.2.12/ext/imap/php_imap.h ./ext/imap/php_imap.h
--- ../orig/php-5.2.12/ext/imap/php_imap.h      2008-12-31 06:17:49.000000000 
-0500
+++ ./ext/imap/php_imap.h       2010-02-03 13:56:51.000000000 -0500
@@ -94,6 +94,10 @@
        unsigned long msgid;
        struct _php_imap_message_struct *next;
 } MESSAGELIST;
+
+typedef struct _php_imap_searchpgm_struct {
+       SEARCHPGM *searchpgm;
+} pisearchpgms;
  
 
 /* Functions */
@@ -169,6 +173,9 @@
 PHP_FUNCTION(imap_timeout);
 
 #if defined(HAVE_IMAP2000) || defined(HAVE_IMAP2001)
+PHP_FUNCTION(imap_searchprogram_new);
+PHP_FUNCTION(imap_searchprogram_or);
+PHP_FUNCTION(imap_searchprogram_setcriterion);
 PHP_FUNCTION(imap_get_quota);
 PHP_FUNCTION(imap_get_quotaroot);
 PHP_FUNCTION(imap_set_quota);



On 2010-02-03, at 3:19 PM, Dominik Gehl wrote:

> Hi,
> 
> I just checked the mailinglist archive 
> (http://news.php.net/php.internals/46939) and you're right, the attachment 
> was missing, even though it's in my sent items ... is there some list policy 
> which rejects attachments ?
> 
> Dominik
> 
> On 2010-02-03, at 3:08 PM, Pierre Joye wrote:
> 
>> hi,
>> 
>> Can you send patches as attachment please?
>> 
>> Also I like to think again about a nicer approach. As your proposal
>> works, it sounds like multiple calls could be avoided.
>> 
>> Cheers,
>> 
>> On Wed, Feb 3, 2010 at 8:37 PM, Dominik Gehl <domi...@dokdok.com> wrote:
>>> Attached is a patch which would allow the usage of most of the IMAP4 search 
>>> criteria.
>>> 
>>> Please let me know if I should contact someone else (IMAP extension 
>>> maintainer(s) ?) regarding this ...
>>> 
>>> Dominik
>>> 
>>> 
>>> On 2010-02-02, at 4:14 PM, Dominik Gehl wrote:
>>> 
>>>> I continued thinking about this and came up with the idea of adding a new 
>>>> resource 'imap_searchpgm' to the imap extension, which would then have 
>>>> quite a good number of new functions: imap_searchprogram_new, 
>>>> imap_searchprogram_sentsince, imap_searchprogram_since, 
>>>> imap_searchprogram_before, imap_searchprogram_on etc. etc.
>>>> 
>>>> The functions could then be defined along the following lines (untested 
>>>> code ...):
>>>> 
>>>> PHP_FUNCTION(imap_searchprogram_new)
>>>> {
>>>>      int myargc = ZEND_NUM_ARGS();
>>>> 
>>>>      if (myargc != 0) {
>>>>              ZEND_WRONG_PARAM_COUNT();
>>>>      }
>>>> 
>>>>      pgm = mail_newsearchpgm();
>>>>      searchpgm = emalloc(sizeof(php_imap_searchpgm));
>>>>      searchpgm->searchpgm = pgm;
>>>>      ZEND_REGISTER_RESOURCE(return_value, searchpgm, le_imap_searchpgm);
>>>> }
>>>> 
>>>> PHP_FUNCTION(imap_searchprogram_sentsince)
>>>> {
>>>>      zval *zpgm;
>>>>      php_imap_searchpgm *pgm;
>>>>      char *criterion = "";
>>>> 
>>>>      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &zpgm, 
>>>> &criterion) == FAILURE) {
>>>>              RETURN_FALSE;
>>>>      }
>>>> 
>>>>      ZEND_FETCH_RESOURCE(pgm, php_imap_search_pgm*, &zpgm, -1, 
>>>> "imapsearch", le_imap_searchpgm);
>>>> 
>>>>      mail_criteria_date(&pgm->searchpgm->sentsince, &criterion);
>>>> 
>>>>      RETURN_TRUE;
>>>> }
>>>> 
>>>> etc. etc.
>>>> 
>>>> 
>>>> And finally, the imap_search function could then accept either the 
>>>> criteria string OR an imap_searchpgm resource.
>>>> 
>>>> Ideas, comments ?
>>>> 
>>>> Thanks,
>>>> Dominik
>>>> 
>>>> 
>>>> On 2010-02-01, at 10:06 AM, Dominik Gehl wrote:
>>>> 
>>>>> Thanks a lot for your reply. I also found a second bug report related to 
>>>>> this: http://bugs.php.net/bug.php?id=21168
>>>>> 
>>>>> Now, how about adding an imap_newsearchpgm function to the PHP imap 
>>>>> extension which would do a call to mail_nsewsearchpgm inside c-client and 
>>>>> return a structure allowing to contruct IMAP4 search programs (SEARCHPGM 
>>>>> inside c-client) ?
>>>>> 
>>>>> Anyone interested in this ?
>>>>> 
>>>>> Dominik
>>>>> 
>>>>> On 2010-01-30, at 6:22 PM, Joey Smith wrote:
>>>>> 
>>>>>> There's an open bug on this, #15238 
>>>>>> (http://bugs.php.net/bug.php?id=15238&;). I'm
>>>>>> sure patches would be welcomed.
>>>>>> 
>>>>>> On Fri, Jan 29, 2010 at 03:49:18PM -0500, Dominik Gehl wrote:
>>>>>>> Hi,
>>>>>>> 
>>>>>>> I noticed that the imap extension seems to support only IMAP2 search 
>>>>>>> criteria.
>>>>>>> 
>>>>>>> This is caused by the fact that in ext/imap/php_imap.c, the imap_search 
>>>>>>> function uses a call to mail_criteria. And
>>>>>>> the University of Washington IMAP toolkit mentions in docs/internal.txt:
>>>>>>> 
>>>>>>> SEARCHPGM *mail_criteria (char *criteria);
>>>>>>>    criteria IMAP2-format search criteria string
>>>>>>> 
>>>>>>> This function accepts an IMAP2-format search criteria string and
>>>>>>> parses it.  If the parse is successful, it returns a search program
>>>>>>> suitable for use in mail_search_full().
>>>>>>>    WARNING: This function does not accept IMAP4 search criteria.
>>>>>>> 
>>>>>>> 
>>>>>>> Is there any specific reason why PHP uses this mail_criteria call ? It 
>>>>>>> really would be nice to be able to use IMAP4 search criteria !
>>>>>>> 
>>>>>>> Thanks,
>>>>>>> Dominik
>>>>>>> 
>>>>>>> --
>>>>>>> PHP Internals - PHP Runtime Development Mailing List
>>>>>>> To unsubscribe, visit: http://www.php.net/unsub.php
>>>>>>> 
>>>>> 
>>>> 
>>> 
>>> 
>>> 
>>> --
>>> PHP Internals - PHP Runtime Development Mailing List
>>> To unsubscribe, visit: http://www.php.net/unsub.php
>>> 
>> 
>> 
>> 
>> -- 
>> Pierre
>> 
>> @pierrejoye | http://blog.thepimp.net | http://www.libgd.org
> 


--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to