source: trunk/zoo-project/zoo-kernel/service_internal_php7.c @ 790

Last change on this file since 790 was 790, checked in by djay, 8 years ago

Add support for nested inputs and outputs.

File size: 10.3 KB
Line 
1/*
2 * Author : Gérald FENOY, Knut LANDMARK
3 *
4 * Copyright (c) 2009-2016 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#ifndef ZEND_DEBUG
30  #define ZEND_DEBUG 0
31#endif 
32
33#include <sapi/embed/php_embed.h>
34#include <zend_stream.h>
35
36#include "service_internal_php.h"
37#include "response_print.h"
38
39map* php_hashtable_to_map(HashTable* tab);
40maps* php_array_to_maps(HashTable* arr);
41void php_map_to_array(map* src, zval* arr);
42void php_maps_to_array(maps* src, zval* arr);
43
44#define zval_make_ref_array(zv,len) for (int elem = 0; elem < len; elem++) ZVAL_MAKE_REF(&zv[elem]);
45#define zval_unref_array(zv,len)    for (int elem = 0; elem < len; elem++) ZVAL_UNREF(&zv[elem]);       
46
47#ifdef ZTS
48void ***tsrm_ls;
49#endif
50
51ZEND_BEGIN_MODULE_GLOBALS(zoo)
52long _SERVICE_SUCCEEDED;
53long _SERVICE_FAILED;
54ZEND_END_MODULE_GLOBALS(zoo)
55
56#ifdef ZTS
57#define ZOO_G(v) TSRMG(zoo_globals_id, zend_zoo_globals *, v)
58#else
59#define ZOO_G(v) (zoo_globals.v)
60#endif
61
62#define PHP_ZOO_VERSION "1.0"
63#define PHP_ZOO_EXTNAME "ZOO"
64
65PHP_MINIT_FUNCTION(zoo);
66PHP_MSHUTDOWN_FUNCTION(zoo);
67PHP_RINIT_FUNCTION(zoo);
68
69PHP_FUNCTION(zoo_Translate);
70PHP_FUNCTION(zoo_UpdateStatus);
71PHP_FUNCTION(zoo_SERVICE_SUCCEEDED);
72PHP_FUNCTION(zoo_SERVICE_FAILED);
73
74extern zend_module_entry zoo_module_entry;
75#define phpext_zoo_ptr &zoo_entry
76
77ZEND_DECLARE_MODULE_GLOBALS(zoo)
78
79static zend_function_entry zoo_functions[] = {
80  PHP_FE(zoo_Translate, NULL)
81  PHP_FE(zoo_UpdateStatus, NULL)
82  PHP_FE(zoo_SERVICE_SUCCEEDED, NULL)
83  PHP_FE(zoo_SERVICE_FAILED, NULL)
84  {NULL, NULL, NULL}
85};
86
87zend_module_entry zoo_module_entry = {
88#if ZEND_MODULE_API_NO >= 20010901
89    STANDARD_MODULE_HEADER,
90#endif
91    PHP_ZOO_EXTNAME,
92    zoo_functions,
93    PHP_MINIT(zoo),
94    PHP_MSHUTDOWN(zoo),
95    PHP_RINIT(zoo),
96    NULL,
97    NULL,
98#if ZEND_MODULE_API_NO >= 20010901
99    PHP_ZOO_VERSION,
100#endif
101    STANDARD_MODULE_PROPERTIES
102};
103
104ZEND_GET_MODULE(zoo)
105
106PHP_INI_BEGIN()
107PHP_INI_END()
108
109static void
110php_zoo_init_globals(zend_zoo_globals *zoo_globals)
111{
112  zoo_globals->_SERVICE_SUCCEEDED=3;
113  zoo_globals->_SERVICE_FAILED=4;
114}
115
116PHP_RINIT_FUNCTION(zoo)
117{
118  return SUCCESS;
119}
120
121PHP_MINIT_FUNCTION(zoo)
122{
123  ZEND_INIT_MODULE_GLOBALS(zoo, php_zoo_init_globals,NULL);
124  REGISTER_INI_ENTRIES();
125  return SUCCESS;
126}
127
128PHP_MSHUTDOWN_FUNCTION(zoo)
129{
130  UNREGISTER_INI_ENTRIES();
131  return SUCCESS;
132}
133
134PHP_FUNCTION(zoo_Translate)
135{
136  char *value;
137  size_t value_len;
138  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &value, &value_len) == FAILURE) {
139    RETURN_NULL();
140  }
141  RETURN_STRING(_ss(value), 1);
142}
143
144PHP_FUNCTION(zoo_UpdateStatus)
145{
146  zval *arr;
147  char *message;
148  size_t message_len;
149  zend_long pourcent;
150  char *status=(char*)malloc(4*sizeof(char));
151  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "asl", &arr, &message, &message_len,&pourcent) == FAILURE) {
152    RETURN_NULL();
153  }
154  HashTable* t=HASH_OF(arr);
155  maps* conf = php_array_to_maps(t);
156   
157  setMapInMaps(conf,"lenv","message",message);
158  sprintf(status,"%d",pourcent);
159  setMapInMaps(conf,"lenv","status",status); 
160  _updateStatus(conf); 
161  freeMaps(&conf); 
162  free(conf);
163  free(status);
164 
165  RETURN_NULL();
166}
167
168PHP_FUNCTION(zoo_SERVICE_SUCCEEDED)
169{
170  RETURN_LONG(ZOO_G(_SERVICE_SUCCEEDED));
171}
172
173PHP_FUNCTION(zoo_SERVICE_FAILED)
174{
175  RETURN_LONG(ZOO_G(_SERVICE_FAILED));
176}
177
178/**
179 * Load a PHP script then run the function corresponding to the service by
180 * passing the conf, inputs and outputs parameters by reference.
181 *
182 * @param main_conf the conf maps containing the main.cfg settings
183 * @param request the map containing the HTTP request
184 * @param s the service structure
185 * @param real_inputs the maps containing the inputs
186 * @param real_outputs the maps containing the outputs
187 */
188int zoo_php_support(maps** main_conf, map* request, service* s, maps **real_inputs, maps **real_outputs) {     
189  maps* m = *main_conf;
190  maps* inputs = *real_inputs;
191  maps* outputs = *real_outputs;
192   
193  map* libp = getMapFromMaps(m, "main", "libPath"); 
194  int res=SERVICE_FAILED;
195
196  map* tmp = getMap(s->content, "serviceProvider");
197  if (tmp == NULL || tmp->value == NULL) {
198    return errorException(m, "Missing serviceProvider (library file)", "NoApplicableCode", NULL);
199  } 
200 
201  #ifdef IGNORE_METAPATH
202  map* mp = createMap("metapath", "");
203  #else 
204  map* mp = getMap(request, "metapath");
205  #endif
206 
207  map* cwd = getMapFromMaps(m,"lenv","cwd");
208  char *scriptName;
209 
210  if (libp != NULL && libp->value != NULL) {
211    scriptName = (char*) malloc((strlen(libp->value) + strlen(tmp->value) + 2)*sizeof(char));
212    sprintf (scriptName, "%s/%s", libp->value, tmp->value);     
213  }
214  else {       
215    if(mp != NULL && strlen(mp->value) > 0) {
216      scriptName = (char*) malloc((strlen(cwd->value)+strlen(mp->value)+strlen(tmp->value)+3)*sizeof(char));
217      sprintf(scriptName, "%s/%s/%s", cwd->value, mp->value, tmp->value);
218    } 
219          else {
220      scriptName = (char*) malloc((strlen(cwd->value)+strlen(tmp->value)+2)*sizeof(char));
221      sprintf(scriptName, "%s/%s", cwd->value, tmp->value);
222    }
223  }
224 
225  zend_file_handle iscript;
226  iscript.type = ZEND_HANDLE_FD;
227  iscript.opened_path = NULL;
228  iscript.filename = tmp->value;
229  iscript.free_filename = 0;
230 
231  FILE* temp = fopen(scriptName, "rb");
232  if(temp == NULL) {
233    char tmp1[1024];
234    sprintf(tmp1, _("Unable to load the PHP file %s"), tmp->value);
235    free(scriptName);
236    return errorException(m, tmp1, "NoApplicableCode", NULL);
237  }
238  iscript.handle.fd = fileno(temp);
239
240  php_embed_init(0, NULL);
241
242  zend_try {
243    zend_startup_module(&zoo_module_entry);
244    php_execute_script(&iscript TSRMLS_CC);
245
246          zval iargs[3];
247    zval iret, ifunc;   
248                     
249          ZVAL_STRING(&ifunc, s->name);
250       
251          php_maps_to_array(*main_conf, iargs);   
252    php_maps_to_array(*real_inputs, iargs+1);   
253    php_maps_to_array(*real_outputs, iargs+2);
254    zval_make_ref_array(iargs,3);
255   
256    if((res = call_user_function(EG(function_table), NULL, &ifunc, &iret, 3, iargs)) == SUCCESS) {     
257               
258            zval_unref_array(iargs,3);           
259            zend_string_release(Z_STR_P(&ifunc));
260     
261      HashTable* t = HASH_OF(iargs+2);
262      HashTable* t1 = HASH_OF(iargs);
263      freeMaps(real_outputs);
264      free(*real_outputs);
265      freeMaps(main_conf);
266      free(*main_conf);
267     
268      *real_outputs = php_array_to_maps(t);       
269      *main_conf = php_array_to_maps(t1);
270
271      res = Z_LVAL(iret);
272    }
273    else {
274      free(scriptName);
275      fclose(temp);
276      return errorException(m, "Unable to process.", "NoApplicableCode", NULL);;
277    }
278  } 
279  zend_catch { 
280    free(scriptName);
281    fclose(temp);
282    return errorException(m, "Unable to process.", "NoApplicableCode", NULL);;
283  } 
284  zend_end_try();
285 
286  free(scriptName);
287  fclose(temp);
288  php_embed_shutdown(TSRMLS_C);
289
290  return res;
291}
292
293/**
294 * Convert a Zoo struct maps to a php array
295 *
296 * @param src the struct maps* to convert (source data structure)
297 * @param arr pointer to zval that is to hold the php array
298 */
299void php_maps_to_array(maps* src, zval* arr) {
300       
301  int tres = array_init(arr);
302  maps* pm = src;
303               
304  while (pm != NULL) {
305    zval zv; // allocate on heap??
306    php_map_to_array(pm->content, &zv);
307    add_assoc_zval(arr, pm->name, &zv); 
308    pm = pm->next;
309        }
310}
311
312/**
313 * Convert a Zoo map to a php array
314 *
315 * @param src the struct map* to convert (source data structure)
316 * @param arr pointer to zval that is to hold the php array
317 */
318void php_map_to_array(map* src, zval* arr) {
319       
320  int tres = array_init(arr);
321  map* pm = src;
322       
323  while(pm != NULL) {
324    map* sMap = getMapArray(pm, "size", 0);
325               
326    if (pm->value != NULL && strncmp(pm->name, "value", 5) == 0 && sMap != NULL) {                       
327      tres = add_assoc_stringl(arr, pm->name, pm->value, atoi(sMap->value));
328                }
329    else {
330      tres = add_assoc_string(arr, pm->name, pm->value);                       
331                }                                               
332    pm = pm->next;                     
333  }     
334}
335
336/**
337 * Convert a php hashtable (array) to a Zoo maps
338 *
339 * @param arr the php hashtable to convert
340 * @return the created struct maps*
341 */
342maps* php_array_to_maps(HashTable* arr) {
343
344  maps* res = NULL;
345  zval* data;
346  zend_string* key = NULL;
347  ulong num_key;       
348       
349  ZEND_HASH_FOREACH_KEY_VAL(arr, num_key, key, data)
350    if (!key) { // HASH_KEY_IS_LONG                     
351      key = strpprintf(64, "%lu", num_key);
352          }     
353    zval copy;
354    ZVAL_DUP(&copy, data);
355    HashTable* tab = HASH_OF(&copy);
356               
357    maps* node = createMaps(ZSTR_VAL(key));                                     
358    node->content = php_hashtable_to_map(tab);
359               
360    if(res == NULL) {
361      res = node;
362    }
363    else {
364      addMapsToMaps(&res, node);
365      freeMaps(&node);
366      free(node);
367    }
368    zval_dtor(&copy);           
369  ZEND_HASH_FOREACH_END();
370       
371  return res;
372}
373
374/**
375 * Convert a php hashtable (array) to a Zoo map
376 *
377 * @param tab the php hashtable to convert
378 * @return the created struct map*
379 */
380map* php_hashtable_to_map(HashTable* tab) {
381
382  map* res = NULL;
383  zval* data;
384  zend_string* key = NULL;
385  ulong num_key;
386       
387  ZEND_HASH_FOREACH_KEY_VAL(tab, num_key, key, data)
388    if (!key) { // HASH_KEY_IS_LONG                     
389      key = strpprintf(64, "%lu", num_key);
390    }
391    zval copy;
392    ZVAL_DUP(&copy, data);
393    convert_to_string(&copy);
394               
395    if(strncmp(ZSTR_VAL(key), "value", 5) == 0) {                       
396      size_t len = Z_STRLEN(copy);                             
397      res = addToMapWithSize(res, ZSTR_VAL(key), Z_STRVAL(copy), len);
398    }
399    else {
400      if (res == NULL) {                               
401        res = createMap(ZSTR_VAL(key), Z_STRVAL(copy));
402                        }
403      else {                           
404        addToMap(res, ZSTR_VAL(key), Z_STRVAL(copy));
405      }
406    }                           
407    zval_dtor(&copy);                   
408  ZEND_HASH_FOREACH_END();
409       
410  return res;   
411}       
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