Re: imap4 search criteria
| From: | Dominik Gehl | Date: | Thu, 04 Feb 2010 21:23:55 +0000 |
| Subject: | Re: imap4 search criteria | ||
| References: | 1 2 3 4 5 6 7 8 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-46945@lists.php.net to get a copy of this message | ||
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);