source: trunk/zoo-project/zoo-kernel/service_internal_php.c @ 586

Last change on this file since 586 was 586, checked in by djay, 9 years ago

Add the PHP ZOO-API, fix issue if ZTS is not defined, correct loading of the PHP script depending of the ZOO-Kernel location, use a ZEND_HANDLE_FD rather than the ZEND_HANDLE_FP used before, correct location of the hello.php service.

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 10.8 KB
Line 
1/*
2 * Author : Gérald FENOY
3 *
4 * Copyright (c) 2009-2010 GeoLabs SARL
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25#ifdef WIN32
26  #define NO_FCGI_DEFINES
27#endif
28 
29#include "service_internal_php.h"
30
31#include <sapi/embed/php_embed.h>
32#include <zend_stream.h>
33
34zval *php_Array_from_maps(maps* t);
35zval*  php_Array_from_map(map*);
36maps* php_maps_from_Array(HashTable* t);
37map* php_map_from_HasTable(HashTable* t);
38
39#ifdef ZTS
40void ***tsrm_ls;
41#endif
42
43ZEND_BEGIN_MODULE_GLOBALS(zoo)
44long _SERVICE_SUCCEEDED;
45long _SERVICE_FAILED;
46ZEND_END_MODULE_GLOBALS(zoo)
47
48#ifdef ZTS
49#define ZOO_G(v) TSRMG(zoo_globals_id, zend_zoo_globals *, v)
50#else
51#define ZOO_G(v) (zoo_globals.v)
52#endif
53
54#define PHP_ZOO_VERSION "1.0"
55#define PHP_ZOO_EXTNAME "ZOO"
56
57PHP_MINIT_FUNCTION(zoo);
58PHP_MSHUTDOWN_FUNCTION(zoo);
59PHP_RINIT_FUNCTION(zoo);
60
61PHP_FUNCTION(zoo_Translate);
62PHP_FUNCTION(zoo_UpdateStatus);
63PHP_FUNCTION(zoo_SERVICE_SUCCEEDED);
64PHP_FUNCTION(zoo_SERVICE_FAILED);
65
66extern zend_module_entry zoo_module_entry;
67#define phpext_zoo_ptr &zoo_entry
68
69ZEND_DECLARE_MODULE_GLOBALS(zoo)
70
71static zend_function_entry zoo_functions[] = {
72  PHP_FE(zoo_Translate, NULL)
73  PHP_FE(zoo_UpdateStatus, NULL)
74  PHP_FE(zoo_SERVICE_SUCCEEDED, NULL)
75  PHP_FE(zoo_SERVICE_FAILED, NULL)
76  {NULL, NULL, NULL}
77};
78
79zend_module_entry zoo_module_entry = {
80#if ZEND_MODULE_API_NO >= 20010901
81    STANDARD_MODULE_HEADER,
82#endif
83    PHP_ZOO_EXTNAME,
84    zoo_functions,
85    PHP_MINIT(zoo),
86    PHP_MSHUTDOWN(zoo),
87    PHP_RINIT(zoo),
88    NULL,
89    NULL,
90#if ZEND_MODULE_API_NO >= 20010901
91    PHP_ZOO_VERSION,
92#endif
93    STANDARD_MODULE_PROPERTIES
94};
95
96ZEND_GET_MODULE(zoo)
97
98PHP_INI_BEGIN()
99PHP_INI_END()
100
101static void
102php_zoo_init_globals(zend_zoo_globals *zoo_globals)
103{
104  zoo_globals->_SERVICE_SUCCEEDED=3;
105  zoo_globals->_SERVICE_FAILED=4;
106}
107
108PHP_RINIT_FUNCTION(zoo)
109{
110  return SUCCESS;
111}
112
113PHP_MINIT_FUNCTION(zoo)
114{
115  ZEND_INIT_MODULE_GLOBALS(zoo, php_zoo_init_globals,NULL);
116  REGISTER_INI_ENTRIES();
117  return SUCCESS;
118}
119
120PHP_MSHUTDOWN_FUNCTION(zoo)
121{
122  UNREGISTER_INI_ENTRIES();
123  return SUCCESS;
124}
125
126PHP_FUNCTION(zoo_Translate)
127{
128  char *value;
129  int value_len;
130  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &value, &value_len) == FAILURE) {
131    RETURN_NULL();
132  }
133  RETURN_STRING(_ss(value), 1);
134}
135
136PHP_FUNCTION(zoo_UpdateStatus)
137{
138  zval *arr;
139  char *message;
140  int message_len;
141  long pourcent;
142  char *status=(char*)malloc(4*sizeof(char));
143  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "asl", &arr, &message, &message_len,&pourcent) == FAILURE) {
144    RETURN_NULL();
145  }
146  HashTable* t=HASH_OF(arr);
147  maps* conf=php_maps_from_Array(t);
148  setMapInMaps(conf,"lenv","message",message);
149  sprintf(status,"%d",pourcent);
150  setMapInMaps(conf,"lenv","status",status);
151  _updateStatus(conf);
152  freeMaps(&conf);
153  free(conf);
154  free(status);
155  RETURN_NULL();
156}
157
158PHP_FUNCTION(zoo_SERVICE_SUCCEEDED)
159{
160  RETURN_LONG(ZOO_G(_SERVICE_SUCCEEDED));
161}
162
163PHP_FUNCTION(zoo_SERVICE_FAILED)
164{
165  RETURN_LONG(ZOO_G(_SERVICE_FAILED));
166}
167
168/**
169 * Load a PHP script then run the function corresponding to the service by
170 * passing the conf, inputs and outputs parameters by reference.
171 *
172 * @param main_conf the conf maps containing the main.cfg settings
173 * @param request the map containing the HTTP request
174 * @param s the service structure
175 * @param real_inputs the maps containing the inputs
176 * @param real_outputs the maps containing the outputs
177 */
178int zoo_php_support(maps** main_conf,map* request,service* s,maps **real_inputs,maps **real_outputs){   
179  maps* m=*main_conf;
180  maps* inputs=*real_inputs;
181  maps* outputs=*real_outputs;
182  char ntmp[1024];
183  getcwd(ntmp,1024);
184  map* tmp=getMap(request,"metapath");
185
186  int res=SERVICE_FAILED;
187
188  tmp=getMap(s->content,"serviceProvider");
189  map* cwd=getMapFromMaps(m,"lenv","cwd");
190  map* mp=getMap(request,"metapath");
191  char *scriptName;
192  if(mp!=NULL && strlen(mp->value)>0){
193    scriptName=(char*)malloc((strlen(cwd->value)+strlen(mp->value)+strlen(tmp->value)+3)*sizeof(char));
194    sprintf(scriptName,"%s/%s/%s",cwd->value,mp->value,tmp->value);
195  }else{
196    scriptName=(char*)malloc((strlen(cwd->value)+strlen(tmp->value)+2)*sizeof(char));
197    sprintf(scriptName,"%s/%s",cwd->value,tmp->value);
198  }
199  zend_file_handle iscript;
200  iscript.type=ZEND_HANDLE_FD;
201  iscript.opened_path=NULL;
202  iscript.filename=tmp->value;
203  iscript.free_filename=0;
204  FILE* temp=fopen(scriptName,"rb");
205  if(temp==NULL){
206    char tmp1[1024];
207    sprintf(tmp1,_("Unable to load the PHP file %s"),tmp->value);
208    free(scriptName);
209    return errorException(m,tmp1,"NoApplicableCode",NULL);
210  }
211  iscript.handle.fd=fileno(temp);
212
213  php_embed_init(0,NULL PTSRMLS_CC);
214   
215  zend_try {
216    zend_startup_module(&zoo_module_entry);
217    php_execute_script(&iscript TSRMLS_CC);
218    zval *iargs[3];
219    zval iret, ifunc,ifile;
220     
221    ZVAL_STRING(&ifunc, s->name, 0);
222    iargs[0] = php_Array_from_maps(*main_conf);
223    iargs[1] = php_Array_from_maps(*real_inputs);
224    iargs[2] = php_Array_from_maps(*real_outputs);
225     
226    if((res=call_user_function(EG(function_table), NULL, &ifunc, &iret, 3, iargs TSRMLS_CC))==SUCCESS){
227     
228      HashTable* t=HASH_OF(iargs[2]);
229      HashTable* t1=HASH_OF(iargs[0]);
230      *real_outputs=php_maps_from_Array(t);
231      *main_conf=php_maps_from_Array(t1);
232
233      res=Z_LVAL(iret);
234    }else{
235      free(scriptName);
236      fclose(temp);
237      return errorException(m,"Unable to process.","NoApplicableCode",NULL);;
238    }
239  } zend_catch { 
240    free(scriptName);
241    fclose(temp);
242    return errorException(m,"Unable to process.","NoApplicableCode",NULL);;
243  } zend_end_try();
244  free(scriptName);
245  fclose(temp);
246  php_embed_shutdown(TSRMLS_C);
247
248  return res;
249}
250
251/**
252 * Convert a maps to a php Array
253 *
254 * @param t the maps to convert
255 * @return the php Array
256 */
257zval *php_Array_from_maps(maps* t){
258  zval *mapArray;
259  zval *mapArrayTmp;
260  maps* tmp=t;
261  int tres=0;
262  MAKE_STD_ZVAL(mapArray);
263  tres=array_init(mapArray);
264  while(tmp!=NULL){
265    add_assoc_zval(mapArray,tmp->name,php_Array_from_map(tmp->content));
266    tmp=tmp->next;
267  }
268  return mapArray;
269}
270
271/**
272 * Convert a map to a php Array
273 *
274 * @param t the map to convert
275 * @return the php Array
276 */
277zval *php_Array_from_map(map* t){
278  zval *mapArray;
279  zval *mapArrayTmp;
280  map* tmp=t;
281  int tres=0;
282  MAKE_STD_ZVAL(mapArray);
283  tres=array_init(mapArray);
284  while(tmp!=NULL){
285    map* sMap=getMapArray(tmp,"size",0);   
286        if(strncmp(tmp->name,"value",5)==0 && sMap!=NULL && tmp->value != NULL){
287      tres=add_assoc_stringl(mapArray,tmp->name,tmp->value,atoi(sMap->value),1);
288        } 
289        else if (tmp->value != NULL) {
290      tres=add_assoc_string(mapArray,tmp->name,tmp->value,1);
291        }
292    tmp=tmp->next;
293  }
294  return mapArray;
295}
296
297/**
298 * Convert a php Array to a maps
299 *
300 * @param t the php Array to convert
301 * @return the created maps
302 */
303maps* php_maps_from_Array(HashTable *t){
304  maps* final_res=NULL;
305  maps* cursor=final_res;
306  char key[1024];
307  for(zend_hash_internal_pointer_reset(t); 
308      zend_hash_has_more_elements(t) == SUCCESS; 
309      zend_hash_move_forward(t)) { 
310    char *key; 
311    uint keylen; 
312    ulong idx; 
313    int type; 
314    zval **ppzval, tmpcopy; 
315    type = zend_hash_get_current_key_ex(t, &key, &keylen, &idx, 0, NULL); 
316    if (zend_hash_get_current_data(t, (void**)&ppzval) == FAILURE) { 
317      /**
318       * Should never actually fail since the key is known to exist.
319       */
320      continue; 
321    }
322    /**
323     * Duplicate the zval so that * the orignal’s contents are not destroyed
324     */
325    tmpcopy = **ppzval;
326#ifdef DEBUG
327    fprintf(stderr,"key : %s\n",key);
328#endif
329    zval_copy_ctor(&tmpcopy); 
330#ifdef DEBUG
331    fprintf(stderr,"key : %s\n",key);
332#endif
333    /**
334     * Reset refcount & Convert
335     */
336    INIT_PZVAL(&tmpcopy); 
337    //convert_to_string(&tmpcopy);
338    if (type == HASH_KEY_IS_STRING) { 
339      /**
340       * String Key / Associative
341       */
342      cursor=(maps*)malloc(MAPS_SIZE);
343      cursor->name=strdup(key);
344    }
345#ifdef DEBUG   
346    fprintf(stderr,"key : %s\n",key);
347#endif 
348    HashTable* t=HASH_OF(*ppzval);
349#ifdef DEBUG
350    fprintf(stderr,"key : %s\n",key);
351#endif
352    cursor->content=php_map_from_HasTable(t);
353    cursor->next=NULL;
354    if(final_res==NULL)
355      final_res=cursor;
356    else{
357      addMapsToMaps(&final_res,cursor);
358      freeMaps(&cursor);
359      free(cursor);
360    }
361#ifdef DEBUG
362    fprintf(stderr,"key : %s\n",key);
363#endif
364    /**
365     * Toss out old copy
366     */
367    zval_dtor(&tmpcopy);
368  }
369  return final_res;
370}
371
372/**
373 * Convert a php Array to a map
374 *
375 * @param t the php Array to convert
376 * @return the created map
377 */
378map* php_map_from_HasTable(HashTable* t){
379#ifdef DEBUG
380  fprintf(stderr,"mapsFromPHPArray start\n");
381#endif
382  map* final_res=(map*)malloc(MAP_SIZE);
383  final_res=NULL;
384  char key[1024];
385  for(zend_hash_internal_pointer_reset(t);
386      zend_hash_has_more_elements(t) == SUCCESS;
387      zend_hash_move_forward(t)) {
388    char *key;
389    uint keylen;
390    ulong idx;
391    int type;
392    int len;
393    zval **ppzval, tmpcopy;
394    type = zend_hash_get_current_key_ex(t, &key, &keylen, &idx, 0, NULL); 
395    if (zend_hash_get_current_data(t, (void**)&ppzval) == FAILURE) { 
396      /* Should never actually fail * since the key is known to exist. */ 
397      continue; 
398    }
399    /**
400     * Duplicate the zval so that * the orignal’s contents are not destroyed
401     */ 
402    tmpcopy = **ppzval; 
403    zval_copy_ctor(&tmpcopy); 
404    /**
405     * Reset refcount & Convert
406     */ 
407    INIT_PZVAL(&tmpcopy); 
408    convert_to_string(&tmpcopy);
409    if(strncmp(key,"value",5)==0){
410      len=Z_STRLEN_P(&tmpcopy);
411      addToMapWithSize(final_res,key,Z_STRVAL_P(&tmpcopy),len);
412    }
413    else{
414      if(final_res==NULL){
415#ifdef DEBUG
416        fprintf(stderr,"%s => %s\n",key,Z_STRVAL(tmpcopy));
417#endif
418        final_res=createMap(key,Z_STRVAL(tmpcopy));
419      }
420      else{
421#ifdef DEBUG
422        fprintf(stderr,"%s => %s\n",key,Z_STRVAL(tmpcopy));
423#endif
424        addToMap(final_res,key,Z_STRVAL(tmpcopy));
425      }
426    }
427    /* Toss out old copy */ 
428    zval_dtor(&tmpcopy); 
429  }
430  return final_res;
431}
Note: See TracBrowser for help on using the repository browser.

Search

ZOO Sponsors

http://www.zoo-project.org/trac/chrome/site/img/geolabs-logo.pnghttp://www.zoo-project.org/trac/chrome/site/img/neogeo-logo.png http://www.zoo-project.org/trac/chrome/site/img/apptech-logo.png http://www.zoo-project.org/trac/chrome/site/img/3liz-logo.png http://www.zoo-project.org/trac/chrome/site/img/gateway-logo.png

Become a sponsor !

Knowledge partners

http://www.zoo-project.org/trac/chrome/site/img/ocu-logo.png http://www.zoo-project.org/trac/chrome/site/img/gucas-logo.png http://www.zoo-project.org/trac/chrome/site/img/polimi-logo.png http://www.zoo-project.org/trac/chrome/site/img/fem-logo.png http://www.zoo-project.org/trac/chrome/site/img/supsi-logo.png http://www.zoo-project.org/trac/chrome/site/img/cumtb-logo.png

Become a knowledge partner

Related links

http://zoo-project.org/img/ogclogo.png http://zoo-project.org/img/osgeologo.png