Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
page_rest_resource_js.inc
1 <?php
18 require_once SQ_PACKAGES_PATH.'/web_services/rest/page_templates/page_rest_resource/page_rest_resource.inc';
19 
20 
34 {
35 
42  function __construct($assetid=0)
43  {
44  parent::__construct($assetid);
45 
46  }//end constructor
47 
48 
55  public function printBody()
56  {
57  // Run the request(s).
58  $this->_process();
59  // let the user decide if they want Matrix to do keyword replacements on the response. See bug
60  // #5701 Minor Enhancement : Allow REST resources assets to stop replacing keywords in response
61  $GLOBALS['SQ_SYSTEM']->setGlobalDefine('SQ_REPLACE_MYSOURCE_LEVEL_KEYWORDS', $this->attr('allow_global_replace'));
62 
63  $this->_processJavascript();
64 
65  }//end printBody()
66 
67 
74  protected function _processJavascript()
75  {
76  $js = 'var _REST = Array();';
77 
78  // Encode the data to JSON.
79  if (!empty($this->_res)) {
80  // Mostly the body doesn't want an XML declaration, as this chokes E4X in JS.
81  // response.bodyx is available with any XML declaration removed.
82  foreach ($this->_res['responses'] as &$resp) {
83  $resp['bodyx'] = preg_replace("/^<\?xml\s.*\?>/", "", $resp['body']);
84  }
85  if (!function_exists('json_encode')) {
86  require_once 'Services/JSON.php';
87  $json = new Services_JSON();
88  $js .= '_REST = ' . $json->encodeUnsafe($this->_res) . ";\n";
89  } else {
90  $js .= '_REST = ' .json_encode($this->_res) . ";\n";
91  }
92  }
93 
94  // Run any include files.
95  $file_ids = $this->attr('javascript_files');
96  foreach ($file_ids as $fid) {
97  $file =& $GLOBALS['SQ_SYSTEM']->am->getAsset($fid);
98 
99  $existing = $file->getExistingFile();
100  if (!empty($existing)) {
101  $js .= file_get_contents($existing['path']);
102  }
103 
104  $GLOBALS['SQ_SYSTEM']->am->forgetAsset($file);
105  }
106 
107  // Run any inline JS.
108  $js .= $this->attr('javascript');
109 
110  // Go!
111  //$rm =& $GLOBALS['SQ_SYSTEM']->am->getSystemAsset('rest_manager');
112  $engine = $this->attr('js_engine');
113  if($engine == 'spidermonkey')
114  echo $this->_runJavascript($js);
115  else if($engine == 'v8')
116  echo $this->_runJavascriptv8($js);
117 
118  }//end _processJavascript()
119 
120 
127  public function _runJavascript($js)
128  {
129  $js_output = '';
130 
131  // Open the process
132  $descriptorspec = Array(
133  0 => Array('pipe', 'r'),
134  1 => Array('pipe', 'w'),
135  2 => Array('pipe', 'w')
136  );
137  require_once SQ_DATA_PATH.'/private/conf/tools.inc';
138 
139  $process = proc_open(SQ_TOOL_JS_PATH . ' - ', $descriptorspec, $pipes);
140 
141  if (is_resource($process)) {
142  $STDIN = $pipes[0];
143  $STDOUT = $pipes[1];
144  $STDERR = $pipes[2];
145 
146  // Send data through js.
147  fwrite($STDIN, $js);
148  fclose($STDIN);
149  $js_output = stream_get_contents($STDOUT);
150  fclose($STDOUT);
151 
152  // Read STDERR
153  // We must check for changes on the stream before reading, to avoid hanging for
154  // data that will never arrive.
155  $read = Array($STDERR);
156  $write = NULL;
157  $except = NULL;
158  $num_changed_streams = stream_select($read, $write, $except, 0);
159 
160  // For each readable pipe
161  foreach ($read as $r) {
162  switch ($r) {
163  case $STDERR:
164  $js_errors = stream_get_contents($STDERR);
165  break;
166  }
167  }
168 
169  // Cleanup remaining resources
170  fclose($STDERR);
171  proc_close($process);
172 
173  // Handle errors
174  if ((isset($js_errors)) && (strlen($js_errors) > 0 )) {
175  trigger_error(__CLASS__ . " (#$this->id) " . $js_errors);
176  $errors = TRUE;
177  }
178  }
179 
180  return $js_output;
181 
182  }//end _runJavascript()
183 
191  public function _runJavascriptv8($js)
192  {
193  if(!extension_loaded('v8js')){
194  trigger_error('PECL v8js extension is required');
195  return;
196  }
197  $js_output = '';
198 
199  $v8 = new V8Js();
200  try {
201  ob_start();
202  $v8->executeString($js);
203  $js_output = ob_get_clean();
204  } catch (V8JsException $e) {
205  $js_errors = $e->getMessage() .' - \''.$e->getJsSourceLine().'\' Line: '.$e->getJsLineNumber();
206  trigger_error(__CLASS__ . " (#$this->id) " . $js_errors);
207  $errors = TRUE;
208  }
209 
210  return $js_output;
211 
212  }//end _runJavascript()
213 
214 }//end class
215 
216 ?>