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
There's an open bug on this, #15238 (http://bugs.php.net/bug.php?id=15238&). I'm
sure patches would be welcomed.
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 stringThis 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
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
There's an open bug on this, #15238 (http://bugs.php.net/bug.php?id=15238&). I'm
sure patches would be welcomed.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 stringThis 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
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
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
There's an open bug on this, #15238 (http://bugs.php.net/bug.php?id=15238&). I'm
sure patches would be welcomed.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 stringThis 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
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
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,
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
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,
DominikThanks 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
There's an open bug on this, #15238 (http://bugs.php.net/bug.php?id=15238&). I'm
sure patches would be welcomed.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 stringThis 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--
--
--
Pierre
@pierrejoye | http://blog.thepimp.net | http://www.libgd.org
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
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,
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
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,
DominikThanks 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
There's an open bug on this, #15238 (http://bugs.php.net/bug.php?id=15238&). I'm
sure patches would be welcomed.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 stringThis 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--
--
--
Pierre@pierrejoye | http://blog.thepimp.net | http://www.libgd.org
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);
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
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,
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
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,
DominikThanks 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
There's an open bug on this, #15238 (http://bugs.php.net/bug.php?id=15238&). I'm
sure patches would be welcomed.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 stringThis 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--
--
--
Pierre@pierrejoye | http://blog.thepimp.net | http://www.libgd.org
Here's a new version of the patch. It allows the usage of the following style of code:
$pgm = imap_searchprogram_new();
imap_searchprogram_criteria($pgm1,"DRAFT SMALLER 34567 HEADER Message-Id D76C58CD-C94D-4DE4-B621-83D66437EFE3@dokdok.com FROM dominik@dokdok.com");
imap_search($mbox,$pgm));
Dominik
diff --git a/external/php-5.2.12/ext/imap/php_imap.c b/external/php-5.2.12/ext/imap/php_imap.c
index 16714ae..771c788 100644
--- a/external/php-5.2.12/ext/imap/php_imap.c
+++ b/external/php-5.2.12/ext/imap/php_imap.c
@@ -152,6 +152,9 @@ zend_function_entry imap_functions[] = {
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_criteria, NULL)
PHP_FE(imap_get_quota, NULL)
PHP_FE(imap_get_quotaroot, NULL)
PHP_FE(imap_set_quota, NULL)
@@ -209,6 +212,7 @@ ZEND_GET_MODULE(imap)
/* 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)) {
@@ -240,6 +244,14 @@ static void mail_close_it(zend_rsrc_list_entry rsrc TSRMLS_DC)
}
/ }}} */
+static void mailsearchpgm_close_it(zend_rsrc_list_entry *rsrc TSRMLS_DC)
+{
- pisearchpgms *php_searchpgm = (pisearchpgms *)rsrc->ptr;
- //mail_free_searchpgm(&php_searchpgm->searchpgm);
- efree(php_searchpgm);
+}
/* {{{ add_assoc_object
*/
static int add_assoc_object(zval *arg, char *key, zval *tmp TSRMLS_DC)
@@ -673,6 +685,7 @@ PHP_MINIT_FUNCTION(imap)
*/
le_imap = zend_register_list_destructors_ex(mail_close_it, NULL, "imap", module_number);
-
le_imap_searchpgm = zend_register_list_destructors_ex(mailsearchpgm_close_it, NULL, "imapsearchpgm", module_number);
return SUCCESS;
}
/* }}} */
@@ -3693,7 +3706,9 @@ PHP_FUNCTION(imap_search)
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 +3716,25 @@ PHP_FUNCTION(imap_search)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 +3746,18 @@ PHP_FUNCTION(imap_search)
}
}
-
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 +3769,9 @@ PHP_FUNCTION(imap_search)
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 +4460,178 @@ PHP_FUNCTION(imap_timeout)
}
/* }}} */
+/* {{{ 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_criteria)
+{
- zval **zpgm, **zcriteria;
- pisearchpgms *php_searchpgm;
- char *criteria;
- SEARCHHEADER **hdr;
- char *header_name, *header_value;
- char *search_criterion_name,*r;
- int f;
- if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &zpgm, &zcriteria) == FAILURE) {
-
ZEND_WRONG_PARAM_COUNT();
- }
- ZEND_FETCH_RESOURCE(php_searchpgm, pisearchpgms *, zpgm, -1, "imapsearchpgm", le_imap_searchpgm);
- convert_to_string_ex(zcriteria);
- criteria = estrndup(Z_STRVAL_PP(zcriteria), Z_STRLEN_PP(zcriteria));
- // this comes from mail.c and imapd.c
- /* for each criterion */
- for (search_criterion_name = strtok_r (criteria," ",&r); search_criterion_name; (search_criterion_name = strtok_r (NIL," ",&r))) {
-
f = NIL; /* init then scan the criterion */
-
switch (*ucase (search_criterion_name)) {
-
case 'A': /* possible ALL, ANSWERED */
-
if (!strcmp (search_criterion_name+1,"LL")) f = T;
-
else if (!strcmp (search_criterion_name+1,"NSWERED")) f = php_searchpgm->searchpgm->answered = T;
-
break;
-
case 'B': /* possible BCC, BEFORE, BODY */
-
if (!strcmp (search_criterion_name+1,"CC"))
-
f = mail_criteria_string (&php_searchpgm->searchpgm->bcc,&r);
-
else if (!strcmp (search_criterion_name+1,"EFORE"))
-
f = mail_criteria_date (&php_searchpgm->searchpgm->before,&r);
-
else if (!strcmp (search_criterion_name+1,"ODY"))
-
f = mail_criteria_string (&php_searchpgm->searchpgm->body,&r);
-
break;
-
case 'C': /* possible CC */
-
if (!strcmp (search_criterion_name+1,"C")) f = mail_criteria_string (&php_searchpgm->searchpgm->cc,&r);
-
break;
-
case 'D': /* possible DELETED, DRAFT */
-
if (!strcmp (search_criterion_name+1,"ELETED")) f = php_searchpgm->searchpgm->deleted = T;
-
else if (!strcmp (search_criterion_name+1,"RAFT")) f = php_searchpgm->searchpgm->draft = T;
-
break;
-
case 'F': /* possible FLAGGED, FROM */
-
if (!strcmp (search_criterion_name+1,"LAGGED")) f = php_searchpgm->searchpgm->flagged = T;
-
else if (!strcmp (search_criterion_name+1,"ROM"))
-
f = mail_criteria_string (&php_searchpgm->searchpgm->from,&r);
-
break;
-
case 'H': /* possible HEADER */
-
if (!strcmp
(search_criterion_name+1,"EADER")) {
-
header_name = strtok_r (NIL," ",&r);
-
header_value = strtok_r (NIL," ",&r);
-
for (hdr = &php_searchpgm->searchpgm->header; *hdr; hdr = &(*hdr)->next);
-
*hdr = mail_newsearchheader (header_name,header_value);
-
f = T; /* success */
-
}
-
break;
-
case 'K': /* possible KEYWORD */
-
if (!strcmp (search_criterion_name+1,"EYWORD"))
-
f = mail_criteria_string (&php_searchpgm->searchpgm->keyword,&r);
-
break;
-
case 'L': /* possible LARGER */
-
if (!strcmp (search_criterion_name+1,"ARGER"))
-
f = mail_criteria_number (&php_searchpgm->searchpgm->larger,&r);
-
break;
-
case 'N': /* possible NEW */
-
if (!strcmp (search_criterion_name+1,"EW")) f = php_searchpgm->searchpgm->recent = php_searchpgm->searchpgm->unseen = T;
-
break;
-
case 'O': /* possible OLD, ON */
-
if (!strcmp (search_criterion_name+1,"LD")) f = php_searchpgm->searchpgm->old = T;
-
else if (!strcmp (search_criterion_name+1,"N"))
-
f = mail_criteria_date (&php_searchpgm->searchpgm->on,&r);
-
break;
-
case 'R': /* possible RECENT */
-
if (!strcmp (search_criterion_name+1,"ECENT")) f = php_searchpgm->searchpgm->recent = T;
-
break;
-
case 'S': /* possible SEEN, SENTBEFORE, SENTON, SENTSINCE, SINCE, SUBJECT */
-
if (!strcmp (search_criterion_name+1,"EEN")) f = php_searchpgm->searchpgm->seen = T;
-
else if (!strcmp (search_criterion_name+1,"ENTBEFORE"))
-
f = mail_criteria_date (&php_searchpgm->searchpgm->sentbefore,&r);
-
else if (!strcmp (search_criterion_name+1,"ENTON"))
-
f = mail_criteria_date (&php_searchpgm->searchpgm->senton,&r);
-
else if (!strcmp (search_criterion_name+1,"ENTSINCE"))
-
f = mail_criteria_date (&php_searchpgm->searchpgm->sentsince,&r);
-
else if (!strcmp (search_criterion_name+1,"INCE"))
-
f = mail_criteria_date (&php_searchpgm->searchpgm->since,&r);
-
else if (!strcmp (search_criterion_name+1,"MALLER"))
-
f = mail_criteria_number (&php_searchpgm->searchpgm->smaller,&r);
-
else if (!strcmp (search_criterion_name+1,"UBJECT"))
-
f = mail_criteria_string (&php_searchpgm->searchpgm->subject,&r);
-
break;
-
case 'T': /* possible TEXT, TO */
-
if (!strcmp (search_criterion_name+1,"EXT"))
-
f = mail_criteria_string (&php_searchpgm->searchpgm->text,&r);
-
else if (!strcmp (search_criterion_name+1,"O"))
-
f = mail_criteria_string (&php_searchpgm->searchpgm->to,&r);
-
break;
-
case 'U': /* possible UN* */
-
if (search_criterion_name[1] == 'N') {
-
if (!strcmp (search_criterion_name+2,"ANSWERED")) f = php_searchpgm->searchpgm->unanswered = T;
-
else if (!strcmp (search_criterion_name+2,"DELETED")) f = php_searchpgm->searchpgm->undeleted = T;
-
else if (!strcmp (search_criterion_name+2,"DRAFT")) f = php_searchpgm->searchpgm->undraft = T;
-
else if (!strcmp (search_criterion_name+2,"FLAGGED")) f = php_searchpgm->searchpgm->unflagged = T;
-
else if (!strcmp (search_criterion_name+2,"KEYWORD"))
-
f = mail_criteria_string (&php_searchpgm->searchpgm->unkeyword,&r);
-
else if (!strcmp (search_criterion_name+2,"SEEN")) f = php_searchpgm->searchpgm->unseen = T;
-
}
-
break;
-
default: /* we will barf below */
-
break;
-
}
-
if (! f) {
-
RETURN_FALSE;
-
}
- }
- efree(criteria);
- RETURN_TRUE;
+}
+int mail_criteria_number (unsigned long *number,unsigned char **arg)
+{
-
/* can't double this value */
- if (*number || !isdigit (**arg)) return NIL;
- *number = 0;
- while (isdigit (*arg)) { / found a digit? */
- *number = 10; / add a decade */
- *number += *(arg)++ - '0'; / add number */
- }
- return T;
+}
#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 --git a/external/php-5.2.12/ext/imap/php_imap.h b/external/php-5.2.12/ext/imap/php_imap.h
index 8dd60f5..390999f 100644
--- a/external/php-5.2.12/ext/imap/php_imap.h
+++ b/external/php-5.2.12/ext/imap/php_imap.h
@@ -94,6 +94,10 @@ typedef struct _php_imap_message_struct {
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_thread);
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_criteria);
PHP_FUNCTION(imap_get_quota);
PHP_FUNCTION(imap_get_quotaroot);
PHP_FUNCTION(imap_set_quota);