@@ -4475,38 +4475,56 @@ redis_geosearch_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
44754475char * * cmd ,int * cmd_len ,short * slot ,void * * ctx )
44764476{
44774477char * key ,* unit ;
4478- int argc = 2 ;
4478+ int argc = 0 ;
44794479size_t keylen ,unitlen ;
44804480geoOptions gopts = {0 };
44814481smart_string cmdstr = {0 };
44824482zval * position ,* shape ,* opts = NULL ,* z_ele ;
44834483zend_string * zkey ,* zstr ;
4484+ zend_bool bypolygon = 0 ;
4485+ HashTable * ht ;
44844486
4485- if (zend_parse_parameters (ZEND_NUM_ARGS (),"szzs|a" ,
4486- & key ,& keylen ,& position ,& shape ,
4487- & unit , & unitlen , & opts )== FAILURE )
4487+ if (zend_parse_parameters (ZEND_NUM_ARGS (),"szzs|a" ,& key , & keylen ,
4488+ & position ,& shape ,& unit ,& unitlen ,
4489+ & opts )== FAILURE )
44884490 {
44894491return FAILURE ;
44904492 }
44914493
4492- if (Z_TYPE_P (position )== IS_STRING && Z_STRLEN_P (position )> 0 ) {
4493- argc += 2 ;
4494- }else if (Z_TYPE_P (position )== IS_ARRAY && zend_hash_num_elements (Z_ARRVAL_P (position ))== 2 ) {
4495- argc += 3 ;
4496- }else {
4497- php_error_docref (NULL ,E_WARNING ,"Invalid position" );
4498- return FAILURE ;
4499- }
4500-
45014494if (Z_TYPE_P (shape )== IS_LONG || Z_TYPE_P (shape )== IS_DOUBLE ) {
45024495argc += 2 ;
4503- }else if (Z_TYPE_P (shape )== IS_ARRAY ) {
4496+ }else if (Z_TYPE_P (shape )== IS_ARRAY &&
4497+ zend_hash_num_elements (Z_ARRVAL_P (shape ))== 2 )
4498+ {
4499+ // BYBOX
45044500argc += 3 ;
4501+ }else if (Z_TYPE_P (shape )== IS_ARRAY &&
4502+ zend_hash_num_elements (Z_ARRVAL_P (shape )) >=6 &&
4503+ zend_hash_num_elements (Z_ARRVAL_P (shape )) %2 == 0 )
4504+ {
4505+ // BYPOLYGON N verticies
4506+ argc += 2 + zend_hash_num_elements (Z_ARRVAL_P (shape ));
4507+ bypolygon = 1 ;
45054508 }else {
45064509php_error_docref (NULL ,E_WARNING ,"Invalid shape dimensions" );
45074510return FAILURE ;
45084511 }
45094512
4513+ if (!bypolygon ) {
4514+ if (Z_TYPE_P (position )== IS_STRING && Z_STRLEN_P (position )> 0 ) {
4515+ argc += 2 ;
4516+ }else if (Z_TYPE_P (position )== IS_ARRAY &&
4517+ zend_hash_num_elements (Z_ARRVAL_P (position ))== 2 )
4518+ {
4519+ argc += 3 ;
4520+ }else {
4521+ php_error_docref (NULL ,E_WARNING ,"Invalid position" );
4522+ return FAILURE ;
4523+ }
4524+ }
4525+
4526+ argc += bypolygon ?1 :2 ;
4527+
45104528/* Attempt to parse our options array */
45114529if (opts != NULL ) {
45124530ZEND_HASH_FOREACH_STR_KEY_VAL (Z_ARRVAL_P (opts ),zkey ,z_ele ) {
@@ -4539,28 +4557,40 @@ redis_geosearch_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
45394557REDIS_CMD_INIT_SSTR_STATIC (& cmdstr ,argc ,"GEOSEARCH" );
45404558redis_cmd_append_sstr_key (& cmdstr ,key ,keylen ,redis_sock ,slot );
45414559
4542- if (Z_TYPE_P (position )== IS_ARRAY ) {
4543- REDIS_CMD_APPEND_SSTR_STATIC (& cmdstr ,"FROMLONLAT" );
4544- ZEND_HASH_FOREACH_VAL (Z_ARRVAL_P (position ),z_ele ) {
4545- ZVAL_DEREF (z_ele );
4546- redis_cmd_append_sstr_dbl (& cmdstr ,zval_get_double (z_ele ));
4547- }ZEND_HASH_FOREACH_END ();
4548- }else {
4549- REDIS_CMD_APPEND_SSTR_STATIC (& cmdstr ,"FROMMEMBER" );
4550- redis_cmd_append_sstr (& cmdstr ,Z_STRVAL_P (position ),Z_STRLEN_P (position ));
4560+ if (!bypolygon ) {
4561+ if (Z_TYPE_P (position )== IS_ARRAY ) {
4562+ REDIS_CMD_APPEND_SSTR_STATIC (& cmdstr ,"FROMLONLAT" );
4563+ ZEND_HASH_FOREACH_VAL (Z_ARRVAL_P (position ),z_ele ) {
4564+ ZVAL_DEREF (z_ele );
4565+ redis_cmd_append_sstr_dbl (& cmdstr ,zval_get_double (z_ele ));
4566+ }ZEND_HASH_FOREACH_END ();
4567+ }else {
4568+ REDIS_CMD_APPEND_SSTR_STATIC (& cmdstr ,"FROMMEMBER" );
4569+ redis_cmd_append_sstr (& cmdstr ,Z_STRVAL_P (position ),Z_STRLEN_P (position ));
4570+ }
45514571 }
45524572
45534573if (Z_TYPE_P (shape )== IS_ARRAY ) {
4554- REDIS_CMD_APPEND_SSTR_STATIC (& cmdstr ,"BYBOX" );
4555- ZEND_HASH_FOREACH_VAL (Z_ARRVAL_P (shape ),z_ele ) {
4574+ ht = Z_ARRVAL_P (shape );
4575+ if (bypolygon ) {
4576+ REDIS_CMD_APPEND_SSTR_STATIC (& cmdstr ,"BYPOLYGON" );
4577+ redis_cmd_append_sstr_long (& cmdstr ,zend_hash_num_elements (ht ) /2 );
4578+ }else {
4579+ REDIS_CMD_APPEND_SSTR_STATIC (& cmdstr ,"BYBOX" );
4580+ }
4581+
4582+ ZEND_HASH_FOREACH_VAL (ht ,z_ele ) {
45564583ZVAL_DEREF (z_ele );
45574584redis_cmd_append_sstr_dbl (& cmdstr ,zval_get_double (z_ele ));
45584585 }ZEND_HASH_FOREACH_END ();
45594586 }else {
45604587REDIS_CMD_APPEND_SSTR_STATIC (& cmdstr ,"BYRADIUS" );
45614588redis_cmd_append_sstr_dbl (& cmdstr ,zval_get_double (shape ));
45624589 }
4563- redis_cmd_append_sstr (& cmdstr ,unit ,unitlen );
4590+
4591+ if (!bypolygon ) {
4592+ redis_cmd_append_sstr (& cmdstr ,unit ,unitlen );
4593+ }
45644594
45654595/* Append optional arguments */
45664596if (gopts .withcoord )REDIS_CMD_APPEND_SSTR_STATIC (& cmdstr ,"WITHCOORD" );
@@ -4597,14 +4627,16 @@ int
45974627redis_geosearchstore_cmd (INTERNAL_FUNCTION_PARAMETERS ,RedisSock * redis_sock ,
45984628char * * cmd ,int * cmd_len ,short * slot ,void * * ctx )
45994629{
4600- int argc = 3 ;
46014630char * dest ,* src ,* unit ;
46024631size_t destlen ,srclen ,unitlen ;
46034632geoOptions gopts = {0 };
46044633smart_string cmdstr = {0 };
46054634zval * position ,* shape ,* opts = NULL ,* z_ele ;
4635+ zend_bool bypolygon = 0 ;
46064636zend_string * zkey ;
4637+ HashTable * ht ;
46074638short s2 = 0 ;
4639+ int argc = 0 ;
46084640
46094641if (zend_parse_parameters (ZEND_NUM_ARGS (),"sszzs|a" ,
46104642& dest ,& destlen ,& src ,& srclen ,& position ,& shape ,
@@ -4613,24 +4645,38 @@ redis_geosearchstore_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
46134645return FAILURE ;
46144646 }
46154647
4616- if (Z_TYPE_P (position )== IS_STRING && Z_STRLEN_P (position )> 0 ) {
4617- argc += 2 ;
4618- }else if (Z_TYPE_P (position )== IS_ARRAY && zend_hash_num_elements (Z_ARRVAL_P (position ))== 2 ) {
4619- argc += 3 ;
4620- }else {
4621- php_error_docref (NULL ,E_WARNING ,"Invalid position" );
4622- return FAILURE ;
4623- }
4624-
46254648if (Z_TYPE_P (shape )== IS_LONG || Z_TYPE_P (shape )== IS_DOUBLE ) {
46264649argc += 2 ;
4627- }else if (Z_TYPE_P (shape )== IS_ARRAY ) {
4650+ }else if (Z_TYPE_P (shape )== IS_ARRAY &&
4651+ zend_hash_num_elements (Z_ARRVAL_P (shape ))== 2 )
4652+ {
46284653argc += 3 ;
4654+ }else if (Z_TYPE_P (shape )== IS_ARRAY &&
4655+ zend_hash_num_elements (Z_ARRVAL_P (shape )) >=6 &&
4656+ zend_hash_num_elements (Z_ARRVAL_P (shape )) %2 == 0 )
4657+ {
4658+ argc += 2 + zend_hash_num_elements (Z_ARRVAL_P (shape ));
4659+ bypolygon = 1 ;
46294660 }else {
46304661php_error_docref (NULL ,E_WARNING ,"Invalid shape dimensions" );
46314662return FAILURE ;
46324663 }
46334664
4665+ argc += bypolygon ?2 :3 ;
4666+
4667+ if (!bypolygon ) {
4668+ if (Z_TYPE_P (position )== IS_STRING && Z_STRLEN_P (position )> 0 ) {
4669+ argc += 2 ;
4670+ }else if (Z_TYPE_P (position )== IS_ARRAY &&
4671+ zend_hash_num_elements (Z_ARRVAL_P (position ))== 2 )
4672+ {
4673+ argc += 3 ;
4674+ }else {
4675+ php_error_docref (NULL ,E_WARNING ,"Invalid position" );
4676+ return FAILURE ;
4677+ }
4678+ }
4679+
46344680/* Attempt to parse our options array */
46354681if (opts != NULL ) {
46364682ZEND_HASH_FOREACH_STR_KEY_VAL (Z_ARRVAL_P (opts ),zkey ,z_ele ) {
@@ -4671,28 +4717,39 @@ redis_geosearchstore_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
46714717return FAILURE ;
46724718 }
46734719
4674- if (Z_TYPE_P (position )== IS_ARRAY ) {
4675- REDIS_CMD_APPEND_SSTR_STATIC (& cmdstr ,"FROMLONLAT" );
4676- ZEND_HASH_FOREACH_VAL (Z_ARRVAL_P (position ),z_ele ) {
4677- ZVAL_DEREF (z_ele );
4678- redis_cmd_append_sstr_dbl (& cmdstr ,zval_get_double (z_ele ));
4679- }ZEND_HASH_FOREACH_END ();
4680- }else {
4681- REDIS_CMD_APPEND_SSTR_STATIC (& cmdstr ,"FROMMEMBER" );
4682- redis_cmd_append_sstr (& cmdstr ,Z_STRVAL_P (position ),Z_STRLEN_P (position ));
4720+ if (!bypolygon ) {
4721+ if (Z_TYPE_P (position )== IS_ARRAY ) {
4722+ REDIS_CMD_APPEND_SSTR_STATIC (& cmdstr ,"FROMLONLAT" );
4723+ ZEND_HASH_FOREACH_VAL (Z_ARRVAL_P (position ),z_ele ) {
4724+ ZVAL_DEREF (z_ele );
4725+ redis_cmd_append_sstr_dbl (& cmdstr ,zval_get_double (z_ele ));
4726+ }ZEND_HASH_FOREACH_END ();
4727+ }else {
4728+ REDIS_CMD_APPEND_SSTR_STATIC (& cmdstr ,"FROMMEMBER" );
4729+ redis_cmd_append_sstr (& cmdstr ,Z_STRVAL_P (position ),Z_STRLEN_P (position ));
4730+ }
46834731 }
46844732
46854733if (Z_TYPE_P (shape )== IS_ARRAY ) {
4686- REDIS_CMD_APPEND_SSTR_STATIC (& cmdstr ,"BYBOX" );
4687- ZEND_HASH_FOREACH_VAL (Z_ARRVAL_P (shape ),z_ele ) {
4734+ ht = Z_ARRVAL_P (shape );
4735+ if (bypolygon ) {
4736+ REDIS_CMD_APPEND_SSTR_STATIC (& cmdstr ,"BYPOLYGON" );
4737+ redis_cmd_append_sstr_long (& cmdstr ,zend_hash_num_elements (ht ) /2 );
4738+ }else {
4739+ REDIS_CMD_APPEND_SSTR_STATIC (& cmdstr ,"BYBOX" );
4740+ }
4741+ ZEND_HASH_FOREACH_VAL (ht ,z_ele ) {
46884742ZVAL_DEREF (z_ele );
46894743redis_cmd_append_sstr_dbl (& cmdstr ,zval_get_double (z_ele ));
46904744 }ZEND_HASH_FOREACH_END ();
46914745 }else {
46924746REDIS_CMD_APPEND_SSTR_STATIC (& cmdstr ,"BYRADIUS" );
46934747redis_cmd_append_sstr_dbl (& cmdstr ,zval_get_double (shape ));
46944748 }
4695- redis_cmd_append_sstr (& cmdstr ,unit ,unitlen );
4749+
4750+ if (!bypolygon ) {
4751+ redis_cmd_append_sstr (& cmdstr ,unit ,unitlen );
4752+ }
46964753
46974754/* Append sort if it's not GEO_NONE */
46984755if (gopts .sort == SORT_ASC ) {