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

Last change on this file since 838 was 796, checked in by knut, 7 years ago

Added documentation for the [include] section and libPath parameter of main.cfg. Replaced macro RETURN_STRING by RETURN_STRINGL in service_internal_php7.c.

File size: 10.4 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  RETURN_STRINGL(_ss(value), 1);
143}
144
145PHP_FUNCTION(zoo_UpdateStatus)
146{
147  zval *arr;
148  char *message;
149  size_t message_len;
150  zend_long pourcent;
151  char *status=(char*)malloc(4*sizeof(char));
152  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "asl", &arr, &message, &message_len,&pourcent) == FAILURE) {
153    RETURN_NULL();
154  }
155  HashTable* t=HASH_OF(arr);
156  maps* conf = php_array_to_maps(t);
157   
158  setMapInMaps(conf,"lenv","message",message);
159  sprintf(status,"%d",pourcent);
160  setMapInMaps(conf,"lenv","status",status); 
161  _updateStatus(conf); 
162  freeMaps(&conf); 
163  free(conf);
164  free(status);
165 
166  RETURN_NULL();
167}
168
169PHP_FUNCTION(zoo_SERVICE_SUCCEEDED)
170{
171  RETURN_LONG(ZOO_G(_SERVICE_SUCCEEDED));
172}
173
174PHP_FUNCTION(zoo_SERVICE_FAILED)
175{
176  RETURN_LONG(ZOO_G(_SERVICE_FAILED));
177}
178
179/**
180 * Load a PHP script then run the function corresponding to the service by
181 * passing the conf, inputs and outputs parameters by reference.
182 *
183 * @param main_conf the conf maps containing the main.cfg settings
184 * @param request the map containing the HTTP request
185 * @param s the service structure
186 * @param real_inputs the maps containing the inputs
187 * @param real_outputs the maps containing the outputs
188 */
189int zoo_php_support(maps** main_conf, map* request, service* s, maps **real_inputs, maps **real_outputs) {     
190  maps* m = *main_conf;
191  maps* inputs = *real_inputs;
192  maps* outputs = *real_outputs;
193   
194  map* libp = getMapFromMaps(m, "main", "libPath"); 
195  int res=SERVICE_FAILED;
196
197  map* tmp = getMap(s->content, "serviceProvider");
198  if (tmp == NULL || tmp->value == NULL) {
199    return errorException(m, "Missing serviceProvider (library file)", "NoApplicableCode", NULL);
200  } 
201 
202  #ifdef IGNORE_METAPATH
203  map* mp = createMap("metapath", "");
204  #else 
205  map* mp = getMap(request, "metapath");
206  #endif
207 
208  map* cwd = getMapFromMaps(m,"lenv","cwd");
209  char *scriptName;
210 
211  if (libp != NULL && libp->value != NULL) {
212    scriptName = (char*) malloc((strlen(libp->value) + strlen(tmp->value) + 2)*sizeof(char));
213    sprintf (scriptName, "%s/%s", libp->value, tmp->value);     
214  }
215  else {       
216    if(mp != NULL && strlen(mp->value) > 0) {
217      scriptName = (char*) malloc((strlen(cwd->value)+strlen(mp->value)+strlen(tmp->value)+3)*sizeof(char));
218      sprintf(scriptName, "%s/%s/%s", cwd->value, mp->value, tmp->value);
219    } 
220          else {
221      scriptName = (char*) malloc((strlen(cwd->value)+strlen(tmp->value)+2)*sizeof(char));
222      sprintf(scriptName, "%s/%s", cwd->value, tmp->value);
223    }
224  }
225 
226  zend_file_handle iscript;
227  iscript.type = ZEND_HANDLE_FD;
228  iscript.opened_path = NULL;
229  iscript.filename = tmp->value;
230  iscript.free_filename = 0;
231 
232  FILE* temp = fopen(scriptName, "rb");
233  if(temp == NULL) {
234    char tmp1[1024];
235    sprintf(tmp1, _("Unable to load the PHP file %s"), tmp->value);
236    free(scriptName);
237    return errorException(m, tmp1, "NoApplicableCode", NULL);
238  }
239  iscript.handle.fd = fileno(temp);
240
241  php_embed_init(0, NULL);
242
243  zend_try {
244    zend_startup_module(&zoo_module_entry);
245    php_execute_script(&iscript TSRMLS_CC);
246
247          zval iargs[3];
248    zval iret, ifunc;   
249                     
250          ZVAL_STRING(&ifunc, s->name);
251       
252          php_maps_to_array(*main_conf, iargs);   
253    php_maps_to_array(*real_inputs, iargs+1);   
254    php_maps_to_array(*real_outputs, iargs+2);
255    zval_make_ref_array(iargs,3);
256   
257    if((res = call_user_function(EG(function_table), NULL, &ifunc, &iret, 3, iargs)) == SUCCESS) {     
258               
259            zval_unref_array(iargs,3);           
260            zend_string_release(Z_STR_P(&ifunc));
261     
262      HashTable* t = HASH_OF(iargs+2);
263      HashTable* t1 = HASH_OF(iargs);
264      freeMaps(real_outputs);
265      free(*real_outputs);
266      freeMaps(main_conf);
267      free(*main_conf);
268     
269      *real_outputs = php_array_to_maps(t);       
270      *main_conf = php_array_to_maps(t1);
271
272      res = Z_LVAL(iret);
273    }
274    else {
275      free(scriptName);
276      fclose(temp);
277      return errorException(m, "Unable to process.", "NoApplicableCode", NULL);;
278    }
279  } 
280  zend_catch { 
281    free(scriptName);
282    fclose(temp);
283    return errorException(m, "Unable to process.", "NoApplicableCode", NULL);;
284  } 
285  zend_end_try();
286 
287  free(scriptName);
288  fclose(temp);
289  php_embed_shutdown(TSRMLS_C);
290
291  return res;
292}
293
294/**
295 * Convert a Zoo struct maps to a php array
296 *
297 * @param src the struct maps* to convert (source data structure)
298 * @param arr pointer to zval that is to hold the php array
299 */
300void php_maps_to_array(maps* src, zval* arr) {
301       
302  int tres = array_init(arr);
303  maps* pm = src;
304               
305  while (pm != NULL) {
306    zval zv; // allocate on heap??
307    php_map_to_array(pm->content, &zv);
308    add_assoc_zval(arr, pm->name, &zv); 
309    pm = pm->next;
310        }
311}
312
313/**
314 * Convert a Zoo map to a php array
315 *
316 * @param src the struct map* to convert (source data structure)
317 * @param arr pointer to zval that is to hold the php array
318 */
319void php_map_to_array(map* src, zval* arr) {
320       
321  int tres = array_init(arr);
322  map* pm = src;
323       
324  while(pm != NULL) {
325    map* sMap = getMapArray(pm, "size", 0);
326               
327    if (pm->value != NULL && strncmp(pm->name, "value", 5) == 0 && sMap != NULL) {                       
328      tres = add_assoc_stringl(arr, pm->name, pm->value, atoi(sMap->value));
329                }
330    else {
331      tres = add_assoc_string(arr, pm->name, pm->value);                       
332                }                                               
333    pm = pm->next;                     
334  }     
335}
336
337/**
338 * Convert a php hashtable (array) to a Zoo maps
339 *
340 * @param arr the php hashtable to convert
341 * @return the created struct maps*
342 */
343maps* php_array_to_maps(HashTable* arr) {
344
345  maps* res = NULL;
346  zval* data;
347  zend_string* key = NULL;
348  ulong num_key;       
349       
350  ZEND_HASH_FOREACH_KEY_VAL(arr, num_key, key, data)
351    if (!key) { // HASH_KEY_IS_LONG                     
352      key = strpprintf(64, "%lu", num_key);
353          }     
354    zval copy;
355    ZVAL_DUP(&copy, data);
356    HashTable* tab = HASH_OF(&copy);
357               
358    maps* node = createMaps(ZSTR_VAL(key));                                     
359    node->content = php_hashtable_to_map(tab);
360               
361    if(res == NULL) {
362      res = node;
363    }
364    else {
365      addMapsToMaps(&res, node);
366      freeMaps(&node);
367      free(node);
368    }
369    zval_dtor(&copy);           
370  ZEND_HASH_FOREACH_END();
371       
372  return res;
373}
374
375/**
376 * Convert a php hashtable (array) to a Zoo map
377 *
378 * @param tab the php hashtable to convert
379 * @return the created struct map*
380 */
381map* php_hashtable_to_map(HashTable* tab) {
382
383  map* res = NULL;
384  zval* data;
385  zend_string* key = NULL;
386  ulong num_key;
387       
388  ZEND_HASH_FOREACH_KEY_VAL(tab, num_key, key, data)
389    if (!key) { // HASH_KEY_IS_LONG                     
390      key = strpprintf(64, "%lu", num_key);
391    }
392    zval copy;
393    ZVAL_DUP(&copy, data);
394    convert_to_string(&copy);
395               
396    if(strncmp(ZSTR_VAL(key), "value", 5) == 0) {                       
397      size_t len = Z_STRLEN(copy);                             
398      res = addToMapWithSize(res, ZSTR_VAL(key), Z_STRVAL(copy), len);
399    }
400    else {
401      if (res == NULL) {                               
402        res = createMap(ZSTR_VAL(key), Z_STRVAL(copy));
403                        }
404      else {                           
405        addToMap(res, ZSTR_VAL(key), Z_STRVAL(copy));
406      }
407    }                           
408    zval_dtor(&copy);                   
409  ZEND_HASH_FOREACH_END();
410       
411  return res;   
412}       
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