// -------------------------------------------------
// libhtdigphp.c
//
// Code for libhtdig PHP 4.0 wrapper.
//
// Requires libhtdig 3.2.0 or better
//
// Part of the ht://Dig package
//
//
// Copyright (c) 1995-2002 The ht://Dig Group
// Copyright (c) 2002 Rightnow Technologies, Inc.
//
// Dual Licensed LGPL
// See LGPL file for License.
//
// Copies available at
// http://www.fsf.org/licenses/gpl.html
// http://www.fsf.org/licenses/lgpl.html
//
// --------------------------------------------------
/* $Id: htdigphp.c,v 1.1 2004/03/20 01:31:21 nealr Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php.h"
#include "htdigphp.h"
/* PHP Includes */
#include "ext/standard/file.h"
#include "ext/standard/info.h"
/* for fileno() */
#include
#include
/* HtDig includes */
#include
PHP_FUNCTION(htsearch_open);
PHP_FUNCTION(htsearch_query);
PHP_FUNCTION(htsearch_get_nth_match);
PHP_FUNCTION(htsearch_close);
PHP_FUNCTION(htsearch_get_error);
PHP_FUNCTION(htdig_index_test_url);
function_entry htdig_functions[] =
{
PHP_FE(htsearch_open, NULL)
PHP_FE(htsearch_query, NULL)
PHP_FE(htsearch_get_nth_match, NULL)
PHP_FE(htsearch_close, NULL)
PHP_FE(htsearch_get_error, NULL)
PHP_FE(htdig_index_test_url, NULL)
{NULL, NULL, NULL}
};
zend_module_entry htdig_module_entry =
{
STANDARD_MODULE_HEADER,
"htdig",
htdig_functions,
PHP_MINIT(htdig),
NULL,
NULL,
NULL,
PHP_MINFO(htdig),
NO_VERSION_YET,
STANDARD_MODULE_PROPERTIES
};
#ifdef COMPILE_DL_HTDIG
ZEND_GET_MODULE(htdig)
#endif
//static int le_htdig;
static int num_search_results;
static char time_format[TIME_FORMAT_SIZE];
//static void php_htdig_close(zend_rsrc_list_entry * rsrc TSRMLS_DC);
PHP_MINIT_FUNCTION(htdig)
{
/* Register the resource, with destructor (arg 1) and text description (arg 3), the
other arguments are just standard placeholders */
//le_htdig = zend_register_list_destructors_ex(php_htdig_close, NULL, "HtDig 3.2.0", module_number);
return SUCCESS;
}
PHP_MINFO_FUNCTION(htdig)
{
php_info_print_table_start();
php_info_print_table_row(2, "HtDig Support", "Enabled");
php_info_print_table_row(2, "HtDig Version", "3.2.0b5");
php_info_print_table_end();
}
/*
* htsearch_open
*
* Wrapper for
* int htsearch_open(htsearch_parameters_struct *);
*
* TODO recieve configFile, debug, logFile as parameters. 2 & 3 are Optional!
*
*/
PHP_FUNCTION(htsearch_open)
{
zval **config_array_arg, **pvalue;
HashTable *config_array_ht;
htsearch_parameters_struct htsearch_params;
int array_size = 0;
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &config_array_arg) == FAILURE)
WRONG_PARAM_COUNT;
if (Z_TYPE_PP(config_array_arg) != IS_ARRAY)
{
php_error(E_WARNING, "First argument to htsearch_open() should be an array");
return;
}
convert_to_array_ex(config_array_arg);
config_array_ht = Z_ARRVAL_PP(config_array_arg);
array_size = zend_hash_num_elements(config_array_ht);
if (array_size < 3)
{
php_error(E_WARNING, "First argument to htsearch_open() should be an array with at least 3 elements");
return;
}
memset(&htsearch_params ,0, sizeof(htsearch_params));
//----------- Required Paramters --------------
if (zend_hash_find(config_array_ht, "configFile", sizeof("configFile"),
(void **) &pvalue) == SUCCESS)
{
convert_to_string_ex(pvalue);
sprintf(htsearch_params.configFile, Z_STRVAL_PP(pvalue));
}
else
{
php_error(E_WARNING, "'configFile' key not in array parameter");
return;
}
if (zend_hash_find(config_array_ht, "debug", sizeof("debug"),
(void **) &pvalue) == SUCCESS)
{
convert_to_long_ex(pvalue);
htsearch_params.debug = Z_LVAL_PP(pvalue);
}
else
{
php_error(E_WARNING, "'debug' key not in array parameter");
return;
}
if (zend_hash_find(config_array_ht, "logFile", sizeof("logFile"),
(void **) &pvalue) == SUCCESS)
{
convert_to_string_ex(pvalue);
sprintf(htsearch_params.logFile, Z_STRVAL_PP(pvalue));
}
else
{
php_error(E_WARNING, "'logFile' key not in array parameter");
return;
}
//----------- Optional Paramters --------------
if (zend_hash_find(config_array_ht, "DBpath", sizeof("DBpath"),
(void **) &pvalue) == SUCCESS)
{
convert_to_string_ex(pvalue);
sprintf(htsearch_params.DBpath, Z_STRVAL_PP(pvalue));
}
else
{
htsearch_params.DBpath[0] = 0; //NULL terminator
htsearch_params.DBpath[1] = 0;
}
if (zend_hash_find(config_array_ht, "locale", sizeof("locale"),
(void **) &pvalue) == SUCCESS)
{
convert_to_string_ex(pvalue);
sprintf(htsearch_params.locale, Z_STRVAL_PP(pvalue));
}
else
{
htsearch_params.locale[0] = 0; //NULL terminator
htsearch_params.locale[1] = 0;
}
if (zend_hash_find(config_array_ht, "restrict", sizeof("restrict"),
(void **) &pvalue) == SUCCESS)
{
convert_to_string_ex(pvalue);
sprintf(htsearch_params.search_restrict, Z_STRVAL_PP(pvalue));
}
else
{
htsearch_params.search_restrict[0] = 0; //NULL terminator
htsearch_params.search_restrict[1] = 0;
}
if (zend_hash_find(config_array_ht, "exclude", sizeof("exclude"),
(void **) &pvalue) == SUCCESS)
{
convert_to_string_ex(pvalue);
sprintf(htsearch_params.search_exclude, Z_STRVAL_PP(pvalue));
}
else
{
htsearch_params.search_exclude[0] = 0; //NULL terminator
htsearch_params.search_exclude[1] = 0;
}
if (zend_hash_find(config_array_ht, "alwaysret", sizeof("alwaysret"),
(void **) &pvalue) == SUCCESS)
{
convert_to_string_ex(pvalue);
sprintf(htsearch_params.search_alwaysreturn, Z_STRVAL_PP(pvalue));
}
else
{
htsearch_params.search_alwaysreturn[0] = 0; //NULL terminator
htsearch_params.search_alwaysreturn[1] = 0;
}
if (zend_hash_find(config_array_ht, "title_factor", sizeof("title_factor"),
(void **) &pvalue) == SUCCESS)
{
convert_to_string_ex(pvalue);
sprintf(htsearch_params.title_factor, Z_STRVAL_PP(pvalue));
}
else
{
htsearch_params.title_factor[0] = 0; //NULL terminator
htsearch_params.title_factor[1] = 0;
}
if (zend_hash_find(config_array_ht, "text_factor", sizeof("text_factor"),
(void **) &pvalue) == SUCCESS)
{
convert_to_string_ex(pvalue);
sprintf(htsearch_params.text_factor, Z_STRVAL_PP(pvalue));
}
else
{
htsearch_params.text_factor[0] = 0; //NULL terminator
htsearch_params.text_factor[1] = 0;
}
if (zend_hash_find(config_array_ht, "meta_description_factor", sizeof("meta_description_factor"),
(void **) &pvalue) == SUCCESS)
{
convert_to_string_ex(pvalue);
sprintf(htsearch_params.meta_description_factor, Z_STRVAL_PP(pvalue));
}
else
{
htsearch_params.meta_description_factor[0] = 0; //NULL terminator
htsearch_params.meta_description_factor[1] = 0;
}
snprintf(time_format, TIME_FORMAT_SIZE, "%s", DEFAULT_TIME_FORMAT);
htsearch_open(&htsearch_params);
num_search_results = 0;
RETURN_LONG(SUCCESS);
}
/*
* wrapper for htsearch_query(htsearch_query_struct *)
*
* TODO recieve query, algorithms_flag, sortby_flag, format as parameters
* Some Optional??
*
* "raw_query" => "$p_query"
* "algorithm" => HTSEARCH_ALG_AND_STR
* "sortby" => HTSEARCH_SORT_SCORE_STR
* "format" => HTSEARCH_FORMAT_LONG_STR
* "time_format" **** optional ***
*
*
*/
PHP_FUNCTION(htsearch_query)
{
zval **query_array_arg, **pvalue;
HashTable *query_array_ht;
htsearch_query_struct the_query;
int array_size = 0;
num_search_results = 0;
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &query_array_arg) == FAILURE)
WRONG_PARAM_COUNT;
if (Z_TYPE_PP(query_array_arg) != IS_ARRAY)
{
php_error(E_WARNING, "First argument to htsearch_query() should be an array");
return;
}
//SEPARATE_ZVAL(query_array_arg);
convert_to_array_ex(query_array_arg);
query_array_ht = Z_ARRVAL_PP(query_array_arg);
array_size = zend_hash_num_elements(query_array_ht);
if (array_size < 4)
{
php_error(E_WARNING, "First argument to htsearch_open() should be an array with at least 4 elements");
return;
}
if (zend_hash_find(query_array_ht, "raw_query", sizeof("raw_query"),
(void **) &pvalue) == SUCCESS)
{
//SEPARATE_ZVAL(pvalue);
convert_to_string_ex(pvalue);
sprintf(the_query.raw_query, Z_STRVAL_PP(pvalue));
}
else
{
php_error(E_WARNING, "'raw_query' key not in array parameter");
return;
}
if (zend_hash_find(query_array_ht, "algorithm", sizeof("algorithm"),
(void **) &pvalue) == SUCCESS)
{
//SEPARATE_ZVAL(pvalue);
convert_to_string_ex(pvalue);
if (strcmp(HTSEARCH_ALG_AND_STR, Z_STRVAL_PP(pvalue)) == 0)
the_query.algorithms_flag = HTSEARCH_ALG_AND;
else if (strcmp(HTSEARCH_ALG_OR_STR, Z_STRVAL_PP(pvalue)) == 0)
the_query.algorithms_flag = HTSEARCH_ALG_OR;
else if (strcmp(HTSEARCH_ALG_BOOLEAN_STR, Z_STRVAL_PP(pvalue)) == 0)
the_query.algorithms_flag = HTSEARCH_ALG_BOOLEAN;
else
{
php_error(E_WARNING, "'algorithm' value not valid [%s]", Z_STRVAL_PP(pvalue));
return;
}
}
else
{
php_error(E_WARNING, "'algorithm' key not in array parameter");
return;
}
if (zend_hash_find(query_array_ht, "format", sizeof("format"),
(void **) &pvalue) == SUCCESS)
{
//SEPARATE_ZVAL(pvalue);
convert_to_string_ex(pvalue);
if (strcmp(HTSEARCH_FORMAT_LONG_STR, Z_STRVAL_PP(pvalue)) == 0)
the_query.format = HTSEARCH_FORMAT_LONG;
else if (strcmp(HTSEARCH_FORMAT_SHORT_STR, Z_STRVAL_PP(pvalue)) == 0)
the_query.format = HTSEARCH_FORMAT_SHORT;
else
{
php_error(E_WARNING, "'format' value not valid [%s]", Z_STRVAL_PP(pvalue));
return;
}
}
else
{
php_error(E_WARNING, "'format' key not in array parameter");
return;
}
if (zend_hash_find(query_array_ht, "sortby", sizeof("sortby"),
(void **) &pvalue) == SUCCESS)
{
//SEPARATE_ZVAL(pvalue);
convert_to_string_ex(pvalue);
if (strcmp(HTSEARCH_SORT_SCORE_STR, Z_STRVAL_PP(pvalue)) == 0)
the_query.sortby_flag = HTSEARCH_SORT_SCORE;
else if (strcmp(HTSEARCH_SORT_REV_SCORE_STR, Z_STRVAL_PP(pvalue)) == 0)
the_query.sortby_flag = HTSEARCH_SORT_REV_SCORE;
else if (strcmp(HTSEARCH_SORT_TIME_STR, Z_STRVAL_PP(pvalue)) == 0)
the_query.sortby_flag = HTSEARCH_SORT_TIME;
else if (strcmp(HTSEARCH_SORT_REV_TIME_STR, Z_STRVAL_PP(pvalue)) == 0)
the_query.sortby_flag = HTSEARCH_SORT_REV_TIME;
else if (strcmp(HTSEARCH_SORT_TITLE_STR, Z_STRVAL_PP(pvalue)) == 0)
the_query.sortby_flag = HTSEARCH_SORT_TITLE;
else if (strcmp(HTSEARCH_SORT_REV_TITLE_STR, Z_STRVAL_PP(pvalue)) == 0)
the_query.sortby_flag = HTSEARCH_SORT_REV_TITLE;
else
{
php_error(E_WARNING, "'sortby' value not valid [%s]", Z_STRVAL_PP(pvalue));
return;
}
}
else
{
php_error(E_WARNING, "'sortby' key not in array parameter");
return;
}
if (zend_hash_find(query_array_ht, "time_format", sizeof("time_format"),
(void **) &pvalue) == SUCCESS)
{
//SEPARATE_ZVAL(pvalue);
convert_to_string_ex(pvalue);
snprintf(time_format, TIME_FORMAT_SIZE, "%s", Z_STRVAL_PP(pvalue));
}
num_search_results = htsearch_query(&the_query);
//printf("[%s][%d]\n", the_query.raw_query, num_results);
RETURN_LONG(num_search_results);
}
/*
*
*
*/
PHP_FUNCTION(htsearch_get_nth_match)
{
zval **result_num_arg, **pvalue;
htsearch_query_match_struct result;
int result_num;
int ret = 0;
char local_time_str[TIME_FORMAT_SIZE];
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &result_num_arg) == FAILURE)
WRONG_PARAM_COUNT;
if (Z_TYPE_PP(result_num_arg) != IS_LONG)
{
php_error(E_WARNING, "First argument to htsearch_get_nth_match() should be an integer");
return;
}
convert_to_long_ex(result_num_arg);
result_num = Z_LVAL_PP(result_num_arg);
if (array_init(return_value) == FAILURE) {
RETURN_FALSE;
}
ret = htsearch_get_nth_match(result_num, &result);
if(ret > 0)
{
strftime(local_time_str, TIME_FORMAT_SIZE, time_format, &result.time_tm);
//fprintf(stderr, "time:[%s]\n", asctime(&result.time_tm));
add_assoc_string(return_value, "title", result.title, 1);
add_assoc_string(return_value, "URL", result.URL, 1);
add_assoc_string(return_value, "excerpt", result.excerpt, 1);
add_assoc_string(return_value, "time", local_time_str, 1);
add_assoc_long( return_value, "score", result.score );
add_assoc_long( return_value, "scorepercent", result.score_percent );
add_assoc_long( return_value, "size", result.size );
add_assoc_long( return_value, "size", result.size );
//fprintf(stderr, "%s\n", result.title);
}
else
{
add_assoc_long( return_value, "error", ret );
}
}
/*
*
*
*/
PHP_FUNCTION(htsearch_close)
{
int ret = 0;
ret = htsearch_close();
RETURN_LONG(ret);
}
/*
*
*
*/
PHP_FUNCTION(htsearch_get_error)
{
RETURN_LONG(SUCCESS);
}
PHP_FUNCTION(htdig_index_test_url)
{
zval **config_array_arg, **pvalue;
zval *tmp;
HashTable *config_array_ht;
htdig_parameters_struct htdigparms;
int array_size = 0;
int ret = 0;
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &config_array_arg) == FAILURE)
WRONG_PARAM_COUNT;
if (Z_TYPE_PP(config_array_arg) != IS_ARRAY)
{
php_error(E_WARNING, "First argument to htdig_index_test_url() should be an array");
}
convert_to_array_ex(config_array_arg);
config_array_ht = Z_ARRVAL_PP(config_array_arg);
array_size = zend_hash_num_elements(config_array_ht);
if (array_size < 1)
{
php_error(E_WARNING, "First argument to htdig_index_test_url() should be an array with at least 1 elements");
return;
}
MAKE_STD_ZVAL(tmp);
memset(&htdigparms ,0, sizeof(htdigparms));
//configFile
if (zend_hash_find(config_array_ht, "configFile", sizeof("configFile"),
(void **) &pvalue) == SUCCESS)
{
convert_to_string_ex(pvalue);
sprintf(htdigparms.configFile, Z_STRVAL_PP(pvalue));
}
else
{
php_error(E_WARNING, "'configFile' key not in array parameter");
return;
}
//URL
if (zend_hash_find(config_array_ht, "URL", sizeof("URL"),
(void **) &pvalue) == SUCCESS)
{
convert_to_string_ex(pvalue);
sprintf(htdigparms.URL, Z_STRVAL_PP(pvalue));
}
else
{
php_error(E_WARNING, "'URL' key not in array parameter");
return;
}
//limit_urls_to
if (zend_hash_find(config_array_ht, "limit_urls_to", sizeof("limit_urls_to"),
(void **) &pvalue) == SUCCESS)
{
convert_to_string_ex(pvalue);
sprintf(htdigparms.limit_urls_to, Z_STRVAL_PP(pvalue));
}
else
{
php_error(E_WARNING, "'limit_urls_to' key not in array parameter");
return;
}
//limit_normalized
if (zend_hash_find(config_array_ht, "limit_normalized", sizeof("limit_normalized"),
(void **) &pvalue) == SUCCESS)
{
convert_to_string_ex(pvalue);
sprintf(htdigparms.limit_normalized, Z_STRVAL_PP(pvalue));
}
else
{
php_error(E_WARNING, "'limit_normalized' key not in array parameter");
return;
}
//exclude_urls
if (zend_hash_find(config_array_ht, "exclude_urls", sizeof("exclude_urls"),
(void **) &pvalue) == SUCCESS)
{
convert_to_string_ex(pvalue);
sprintf(htdigparms.exclude_urls, Z_STRVAL_PP(pvalue));
}
else
{
php_error(E_WARNING, "'exclude_urls' key not in array parameter");
return;
}
//search_restrict
if (zend_hash_find(config_array_ht, "search_restrict", sizeof("search_restrict"),
(void **) &pvalue) == SUCCESS)
{
convert_to_string_ex(pvalue);
sprintf(htdigparms.search_restrict, Z_STRVAL_PP(pvalue));
}
else
{
php_error(E_WARNING, "'search_restrict' key not in array parameter");
return;
}
//search_exclude
if (zend_hash_find(config_array_ht, "search_exclude", sizeof("search_exclude"),
(void **) &pvalue) == SUCCESS)
{
convert_to_string_ex(pvalue);
sprintf(htdigparms.search_exclude, Z_STRVAL_PP(pvalue));
}
else
{
php_error(E_WARNING, "'search_exclude' key not in array parameter");
return;
}
//url_rewrite_rules
if (zend_hash_find(config_array_ht, "url_rewrite_rules", sizeof("url_rewrite_rules"),
(void **) &pvalue) == SUCCESS)
{
convert_to_string_ex(pvalue);
sprintf(htdigparms.url_rewrite_rules, Z_STRVAL_PP(pvalue));
}
else
{
php_error(E_WARNING, "'url_rewrite_rules' key not in array parameter");
return;
}
//bad_querystr
if (zend_hash_find(config_array_ht, "bad_querystr", sizeof("bad_querystr"),
(void **) &pvalue) == SUCCESS)
{
convert_to_string_ex(pvalue);
sprintf(htdigparms.bad_querystr, Z_STRVAL_PP(pvalue));
}
else
{
php_error(E_WARNING, "'bad_querystr' key not in array parameter");
return;
}
//max_hop_count
if (zend_hash_find(config_array_ht, "max_hop_count", sizeof("max_hop_count"),
(void **) &pvalue) == SUCCESS)
{
convert_to_string_ex(pvalue);
sprintf(htdigparms.max_hop_count, Z_STRVAL_PP(pvalue));
}
else
{
php_error(E_WARNING, "'max_hop_count' key not in array parameter");
return;
}
//now test the URL with these filters
ret = htdig_index_test_url(&htdigparms);
//add_assoc_string(*config_array_arg, "rewritten_URL", htdigparms.rewritten_URL, 1);
if (zend_hash_find(config_array_ht, "rewritten_URL", sizeof("rewritten_URL"),
(void **) &pvalue) == SUCCESS)
{
//update rewritten_URL in hashtable-array
ZVAL_STRING(tmp, htdigparms.rewritten_URL, TRUE);
zend_hash_update(config_array_ht, "rewritten_URL", sizeof("rewritten_URL"),
(void *) &tmp, sizeof(zval *), NULL);
}
else
{
//add rewritten_URL to hashtable-array
ZVAL_STRING(tmp, htdigparms.rewritten_URL, TRUE);
zend_hash_add(config_array_ht, "rewritten_URL", sizeof("rewritten_URL"),
(void *) &tmp, sizeof(zval *), NULL);
}
//test add/update
if (zend_hash_find(config_array_ht, "rewritten_URL", sizeof("rewritten_URL"),
(void **) &pvalue) != SUCCESS)
{
RETURN_LONG(-9999999);
}
RETURN_LONG(ret);
}
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: sw=4 ts=4 tw=78 fdm=marker
* vim<600: sw=4 ts=4 tw=78
*/