]> git.agnieray.net Git - galette.git/blob - galette/lib/Galette/IO/ExternalScript.php
Fix typo
[galette.git] / galette / lib / Galette / IO / ExternalScript.php
1 <?php
2
3 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
4
5 /**
6 * External script call
7 *
8 * PHP version 5
9 *
10 * Copyright © 2013-2014 The Galette Team
11 *
12 * This file is part of Galette (http://galette.tuxfamily.org).
13 *
14 * Galette is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation, either version 3 of the License, or
17 * (at your option) any later version.
18 *
19 * Galette is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with Galette. If not, see <http://www.gnu.org/licenses/>.
26 *
27 * @category IO
28 * @package Galette
29 *
30 * @author Johan Cwiklinski <johan@x-tnd.be>
31 * @copyright 2013-2014 The Galette Team
32 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
33 * @link http://galette.tuxfamily.org
34 * @since Available since 0.7.5dev - 2013-06-11
35 */
36
37 namespace Galette\IO;
38
39 use Analog\Analog;
40 use Galette\Core\Preferences;
41
42 /**
43 * External script call
44 *
45 * @category IO
46 * @name ExternalScript
47 * @package Galette
48 * @author Johan Cwiklinski <johan@x-tnd.be>
49 * @copyright 2013-2014 The Galette Team
50 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
51 * @link http://galette.tuxfamily.org
52 * @since Available since 0.7.5dev - 2010-06-11
53 */
54 class ExternalScript
55 {
56 private $protocol;
57 private $method;
58 private $uri;
59 private $as_json = true; //TODO: parametize?
60 private $output;
61
62 /**
63 * Main constructor
64 *
65 * @param Preferences $pref Galette preferences
66 */
67 public function __construct(Preferences $pref)
68 {
69 $uri = $pref->pref_new_contrib_script;
70 list($protocol,) = explode('://', $uri);
71
72 if ($protocol == $uri) {
73 Analog::log(
74 'An URI must be specified',
75 Analog::ERROR
76 );
77 }
78
79 switch ($protocol) {
80 case 'galette':
81 //FIXME: should probably be changed to use pref_galette_url and Slim routing
82 $this->protocol = 'http';
83 if (isset($_SERVER['HTTPS'])) {
84 $this->protocol = 'https';
85 }
86 $this->method = 'galette';
87 $selfs = explode('/', $_SERVER['PHP_SELF']);
88 array_pop($selfs);
89 $self = implode('/', $selfs);
90 $uri = $protocol . '://' . $_SERVER['SERVER_NAME'] . $self .
91 '/' . GALETTE_BASE_PATH . str_replace($protocol . '://', '', $uri);
92 break;
93 case 'file':
94 $this->protocol = $protocol;
95 $this->method = $protocol;
96 break;
97 case 'get':
98 case 'post':
99 $this->method = $protocol;
100 $this->protocol = 'http';
101
102 break;
103 case 'gets':
104 case 'posts':
105 $this->method = trim($protocol, 's');
106 $this->protocol = 'https';
107 break;
108 default:
109 throw new \RuntimeException('Unknown protocol.');
110 break;
111 }
112
113 Analog::log(
114 __CLASS__ . ' instancied with method ' . $this->method .
115 ' and protocol ' . $this->protocol,
116 Analog::INFO
117 );
118
119 if ($protocol !== 'file') {
120 $this->uri = str_replace(
121 $protocol . '://',
122 $this->protocol . '://',
123 $uri
124 );
125 } else {
126 if (file_exists($uri)) {
127 $this->uri = str_replace(
128 $protocol . '://',
129 '',
130 $uri
131 );
132 } else {
133 throw new \RuntimeException(
134 __METHOD__ . 'File ' . $uri . ' does not exists!'
135 );
136 }
137 }
138
139 Analog::log(
140 __CLASS__ . ' URI set to ' . $this->uri,
141 Analog::INFO
142 );
143 }
144
145 /**
146 * Send data
147 *
148 * @param array $params Array of params to send
149 *
150 * @return boolean
151 */
152 public function send($params)
153 {
154 if (!is_array($params) || count($params) == 0) {
155 throw new \RuntimeException(__METHOD__ . ': parameters are mandatory.');
156 }
157
158 $uri = $this->uri;
159 $result = null;
160
161 switch ($this->method) {
162 case 'get':
163 $ch = curl_init();
164 if ($this->as_json === true) {
165 $uri .= '?params=' . json_encode($params);
166 } else {
167 $url_params = http_build_query($params, 'galette_');
168 $uri .= '?' . $url_params;
169 }
170 curl_setopt($ch, CURLOPT_URL, $uri);
171 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
172 $this->output = curl_exec($ch);
173 if ($this->output !== false) {
174 $result = true;
175 } else {
176 $result = false;
177 }
178 curl_close($ch);
179 break;
180 case 'galette':
181 case 'post':
182 $ch = curl_init();
183 curl_setopt($ch, CURLOPT_URL, $this->uri);
184 curl_setopt($ch, CURLOPT_POST, count($params));
185 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
186 if ($this->as_json === true) {
187 curl_setopt(
188 $ch,
189 CURLOPT_POSTFIELDS,
190 array(
191 'params' => json_encode($params)
192 )
193 );
194 } else {
195 curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
196 }
197 $this->output = curl_exec($ch);
198 if ($this->output !== false) {
199 $result = true;
200 } else {
201 $result = false;
202 }
203 curl_close($ch);
204 break;
205 case 'file':
206 $this->output = '';
207 if ($this->as_json === true) {
208 $params = json_encode($params);
209 } else {
210 $imploded = '';
211 foreach ($params as $k => $v) {
212 $imploded .= ' ' . $k . '=' . $v;
213 }
214 $params = $imploded;
215 }
216
217 $descriptors = array(
218 0 => array('pipe', 'r'),
219 1 => array('pipe', 'w'),
220 2 => array('pipe', 'w')
221 );
222
223 $process = proc_open(
224 $uri,
225 $descriptors,
226 $pipes
227 );
228 fwrite($pipes[0], $params);
229 fclose($pipes[0]);
230
231 //get stdout, if any
232 $output = stream_get_contents($pipes[1]);
233 if (trim($output) !== '') {
234 $this->output .= "\n\nStdOut:\n" . $output;
235 }
236
237 //get stderr, if any
238 $errors = stream_get_contents($pipes[2]);
239 if (trim($errors) !== '') {
240 $this->output .= "\n\nStdErr:\n" . $errors;
241 }
242
243 //closes pipes and process
244 fclose($pipes[1]);
245 fclose($pipes[2]);
246 $exit = proc_close($process);
247
248 if (trim($this->output) === '') {
249 $result = true;
250 } else {
251 $result = false;
252 }
253 break;
254 default:
255 throw new \RuntimeException(
256 __METHOD__ . ': unknown method ' . $this->method
257 );
258 }
259
260 Analog::log(
261 __METHOD__ . ' result: ' . $result . "output:\n" . $this->output,
262 Analog::DEBUG
263 );
264
265 return $result;
266 }
267
268 /**
269 * Get full output (only relevant is method is file)
270 *
271 * @return array
272 */
273 public function getOutput()
274 {
275 return $this->output;
276 }
277 }