· 7 years ago · Feb 18, 2019, 02:08 PM
1<?php
2
3/*
4 * Chain plugins management class
5 */
6
7abstract class plugin {
8
9 public $CI = NULL;
10 public $inputParams = NULL;
11 public $configParams = NULL;
12 public $repositoryId = NULL;
13 public $tmpFilesDirectory = NULL;
14 public $dbTablePrefix = 'plugin_';
15 public $dbTable = NULL;
16 public $response = NULL;
17 public $extraInfo = NULL;
18 public $additionalResponse = NULL;
19 public $includesPath = NULL;
20 public $additionalConfigParams = array();
21 public $errorMsg = NULL;
22
23 /**
24 * Class constructor
25 * @param array $inputParams
26 * @param array $configParams
27 *
28 * $inputParams example: array(0 => array('name' => 'myDocument', 'content' => FILE_CONTENT, 'type' => 'application/msword'))
29 * $configParams example: array('compressionLevel' => 5)
30 */
31 public function __construct($inputParams, $configParams) {
32
33 $this->inputParams = $inputParams;
34 $this->configParams = $configParams;
35 $this->response = array();
36
37 $this->CI = & get_instance();
38
39 // set temporary files directory
40 $currentDateTime = new DateTime();
41 $this->tmpFilesDirectory = sys_get_temp_dir() . DIRECTORY_SEPARATOR . $currentDateTime->format('YmdHis') . '_' . uniqid() . DIRECTORY_SEPARATOR;
42
43 $this->includesPath = getcwd() . "/application/plugins/includes";
44 }
45
46 /**
47 * Create a tempfile in the already defined $tmpFilesDirectory path
48 *
49 * @param string $content: Content which should be written to the newly created tempfile
50 * @return string: filepath of the created tempfile
51 */
52 public function createTempFile($content = "") {
53
54 // create temporary directory (if not exists)
55 if (!is_dir($this->tmpFilesDirectory) && !mkdir($this->tmpFilesDirectory)) {
56 throw new \Exception("Could not create plugin temporary files directory: " . $this->tmpFilesDirectory);
57 }
58
59 // create temporary file with passed content
60 $tempfilename = $this->tmpFilesDirectory . uniqid();
61
62 if (strlen($content) == 0 && !touch($tempfilename)) {
63 throw new \Exception("Could not write plugin empty temporary file: " . $tempfilename);
64 } elseif (strlen($content) > 0 && !file_put_contents($tempfilename, $content)) {
65 throw new \Exception("Could not write plugin temporary file: " . $tempfilename);
66 }
67
68 return $tempfilename;
69 }
70
71 /**
72 * Force removal of unlinked tmp files
73 */
74 public function deleteTmpFilesDirectory() {
75
76 // folder exists ?
77 if (is_dir($this->tmpFilesDirectory)) {
78
79 // empty folder content
80 $contents = scandir($this->tmpFilesDirectory);
81
82 foreach ($contents as $content) {
83
84 $targetPath = $this->tmpFilesDirectory . $content;
85
86 if (!in_array($content, array('.', '..')) && is_file($targetPath)) {
87 @unlink($targetPath);
88 }
89 }
90
91 // remove folder
92 @rmdir($this->tmpFilesDirectory);
93 }
94 }
95
96 /**
97 * Plugin execution
98 * @return array $response on success (can return multiple files at once), FALSE otherwise
99 *
100 * $response example: array(0 => array('name' => 'myGzippedDocument', 'content' => FILE_CONTENT_2, 'type' => 'application/x-gzip'));
101 */
102 abstract public function execute();
103
104 public function postExecute($baseResources = array(), $resources = array(), $pluginExecutionExtraInfo = array()) {
105
106 return TRUE;
107 }
108
109 /**
110 * Log wrapper
111 * @param string $shortMessage
112 * @param array $additionalData
113 * @param int $logLevel
114 * @param string $fullMsg
115 */
116 public function logger($shortMessage = '', $additionalData = array(), $logLevel = 6, $fullMsg = NULL) {
117
118 $pluginClassName = get_class($this);
119
120 // log action
121 logger::writeLog('storage_plugin', $pluginClassName . ': ' . $shortMessage, $logLevel, $additionalData, NULL, $fullMsg);
122 }
123
124 public function sendMail($target, $subject, $content, $bcc = array()) {
125
126 return $this->CI->email->sendMail($target, $subject, $content, $bcc);
127 }
128
129 public function getSiteUrl() {
130
131 return site_url();
132 }
133
134 public function addAdditionalResponseContent($key = '', $value = '') {
135
136 $this->additionalResponse[$key] = $value;
137 }
138
139 public function saveResource($repositoryId = NULL, $filePath = NULL, $fileName = NULL, $fileType = NULL) {
140
141 $this->CI->load->model('resource_model');
142
143 // save file
144 $properties = array(
145 'tmp_name' => $filePath,
146 'name' => $fileName,
147 'type' => $fileType,
148 'size' => filesize($filePath)
149 );
150
151 $status = $this->CI->resource_model->saveResource($repositoryId, $properties);
152
153 return $status->validation ? $status : FALSE;
154 }
155
156 public function getResource($fileKey = '', $fileVersion = '') {
157
158 $this->CI->db->from('Resources');
159 $this->CI->db->where('fileKey', $fileKey);
160 if (strlen($fileVersion) > 0) {
161 $this->CI->db->where('fileVersion', $fileVersion);
162 }
163 $this->CI->db->where('isDeleted', 0);
164 $this->CI->db->order_by('fileVersion', 'desc');
165 $this->CI->db->limit(1, 0);
166
167 $query = $this->CI->db->get();
168
169 return ($query->num_rows() != 1 ? FALSE : $query->row());
170 }
171
172 public function dbStartTransaction() {
173
174 $this->CI->db->trans_start();
175
176 return TRUE;
177 }
178
179 public function dbCommitTransaction() {
180
181 $this->CI->db->trans_complete();
182
183 return TRUE;
184 }
185
186 public function dbRollbackTransaction() {
187
188 $this->CI->db->trans_rollback();
189
190 return TRUE;
191 }
192
193 public function dbRecordsRead() {
194
195 $pluginTable = $this->dbTablePrefix . $this->dbTable;
196
197 $query = $this->CI->db->get($pluginTable);
198
199 return $query->result();
200 }
201
202// metodo che consente l'esecuzione di select in join tra più tabelle
203 public function dbRecordsJoinRead($selectConditions = NULL, $joinConditions = array(), $whereConditions = array(), $likeConditions = array(), $groupBy = '', $havingConditions = array(), $orderByConditions = array(), $limit = NULL, $offset = NULL) {
204
205 $pluginTable = $this->dbTablePrefix . $this->dbTable;
206
207 $this->CI->db->select($selectConditions->fields, $selectConditions->useBackticks);
208
209 // la query deve necessariamente partire dalla tabella specifica per il plugin
210 $this->CI->db->from($pluginTable);
211
212 foreach ($joinConditions as $joinCondition) {
213
214 $table = (property_exists($joinCondition, 'table') ? $joinCondition->table : '');
215 $relation = (property_exists($joinCondition, 'relation') ? $joinCondition->relation : '');
216 $type = (property_exists($joinCondition, 'type') ? $joinCondition->type : '');
217
218 $this->CI->db->join($table, $relation, $type);
219 }
220
221 foreach ($whereConditions as $whereCondition) {
222
223 $field = (property_exists($whereCondition, 'field') ? $whereCondition->field : '');
224 $value = (property_exists($whereCondition, 'value') ? $whereCondition->value : '');
225 $useBackticks = (property_exists($whereCondition, 'useBackticks') && $whereCondition->useBackticks == FALSE ? FALSE : TRUE);
226
227 $this->CI->db->where($field, $value, $useBackticks);
228 }
229
230 foreach ($likeConditions as $likeCondition) {
231
232 $field = (property_exists($likeCondition, 'field') ? $likeCondition->field : '');
233 $value = (property_exists($likeCondition, 'value') ? $likeCondition->value : '');
234
235 $this->CI->db->like($field, $value);
236 }
237
238 if (strlen($groupBy) > 0) {
239 $this->CI->db->group_by($groupBy);
240 }
241
242 foreach ($havingConditions as $havingCondition) {
243
244 $field = (property_exists($havingCondition, 'field') ? $havingCondition->field : '');
245 $value = (property_exists($havingCondition, 'value') ? $havingCondition->value : '');
246
247 $this->CI->db->having($field, $value);
248 }
249
250 foreach ($orderByConditions as $orderByCondition) {
251
252 $field = (property_exists($orderByCondition, 'field') ? $orderByCondition->field : '');
253 $mode = (property_exists($orderByCondition, 'mode') ? $orderByCondition->mode : '');
254
255 $this->CI->db->order_by($field, $mode);
256 }
257
258 if (!is_null($limit) && !is_null($offset)) {
259 $this->CI->db->limit($limit, $offset);
260 } elseif (!is_null($limit)) {
261 $this->CI->db->limit($limit);
262 }
263
264 $query = $this->CI->db->get();
265
266 return $query->result();
267 }
268
269 public function dbRecordRead($id = NULL) {
270
271 $query = $this->CI->db->get_where($this->dbTablePrefix . $this->dbTable, array('id' => $id));
272
273 return $query->result();
274 }
275
276 public function dbRecordSearch($searchParams = array()) {
277
278 $this->CI->db->from($this->dbTablePrefix . $this->dbTable);
279 foreach ($searchParams as $key => $value) {
280 $this->CI->db->where($key, $value);
281 }
282 $query = $this->CI->db->get();
283
284 return $query->result();
285 }
286
287 public function dbRecordInsert($record = array()) {
288
289 $this->CI->db->insert($this->dbTablePrefix . $this->dbTable, $record);
290
291 return $this->CI->db->insert_id();
292 }
293
294 public function dbRecordInsertCustomTable($dbTable, $record = array()) {
295
296 $this->CI->db->insert($dbTable, $record);
297
298 return $this->CI->db->insert_id();
299 }
300
301 public function dbRecordUpdate($id = NULL, $record = array()) {
302
303 $this->CI->db->where('id', $id);
304 $this->CI->db->update($this->dbTablePrefix . $this->dbTable, $record);
305
306 return $id;
307 }
308
309 public function dbRecordDelete($id = NULL) {
310
311 $this->CI->db->where('id', $id);
312 $this->CI->db->delete($this->dbTablePrefix . $this->dbTable);
313
314 return $id;
315 }
316
317 public function dbRecordIncrementField($id = NULL, $fieldName = NULL) {
318
319 // REPLICATION AWARE!!!!
320
321 $this->CI->db->where("id", $id);
322 $this->CI->db->set($fieldName, "{$fieldName} + 1", FALSE);
323 $this->CI->db->update($this->dbTablePrefix . $this->dbTable);
324
325 return $id;
326 }
327
328 public function generateUUID() {
329
330 $query = $this->CI->db->query('SELECT UUID() as `UUID`');
331
332 return $query->row()->UUID;
333 }
334
335 public function generateQRCode($content) {
336
337 $this->CI->load->library('ciqrcode');
338
339 $tmpFile = tempnam(sys_get_temp_dir(), 'qr');
340
341 $ciqrcodeParams['data'] = $content;
342 $ciqrcodeParams['savename'] = $tmpFile;
343
344 $this->CI->ciqrcode->generate($ciqrcodeParams);
345
346 $imageString = file_get_contents($tmpFile);
347
348 @unlink($tmpFile);
349
350 return $imageString;
351 }
352
353 public function procOpenHandler($command = '', $stdin = '', $maxExecutionTime = 30) {
354
355 $timeLimit = (time() + $maxExecutionTime);
356
357 $descriptorSpec = array(
358 0 => array("pipe", "r"),
359 1 => array('pipe', 'w'),
360 2 => array('pipe', 'w')
361 );
362
363 $pipes = array();
364
365 $response = new stdClass();
366 $response->status = TRUE;
367 $response->stdOut = '';
368 $response->stdErr = '';
369 $response->exitCode = '';
370
371 $process = proc_open($command, $descriptorSpec, $pipes);
372 if (!$process) {
373 // could not exec command
374 $response->status = FALSE;
375 return $response;
376 }
377
378 $txOff = 0;
379 $txLen = strlen($stdin);
380 $stdoutDone = FALSE;
381 $stderrDone = FALSE;
382
383 // Make stdin/stdout/stderr non-blocking
384 stream_set_blocking($pipes[0], 0);
385 stream_set_blocking($pipes[1], 0);
386 stream_set_blocking($pipes[2], 0);
387
388 if ($txLen == 0) {
389 fclose($pipes[0]);
390 }
391
392 while (TRUE) {
393
394 if (time() > $timeLimit) {
395 // max execution time reached
396 // echo 'MAX EXECUTION TIME REACHED'; die;
397 @proc_close($process);
398 $response->status = FALSE;
399 break;
400 }
401
402 $rx = array(); // The program's stdout/stderr
403
404 if (!$stdoutDone) {
405 $rx[] = $pipes[1];
406 }
407
408 if (!$stderrDone) {
409 $rx[] = $pipes[2];
410 }
411
412 $tx = array(); // The program's stdin
413
414 if ($txOff < $txLen) {
415 $tx[] = $pipes[0];
416 }
417
418 $ex = NULL;
419
420 stream_select($rx, $tx, $ex, NULL, NULL); // Block til r/w possible
421
422 if (!empty($tx)) {
423
424 $txRet = fwrite($pipes[0], substr($stdin, $txOff, 8192));
425
426 if ($txRet !== FALSE) {
427 $txOff += $txRet;
428 }
429 if ($txOff >= $txLen) {
430 fclose($pipes[0]);
431 }
432 }
433
434 foreach ($rx as $r) {
435
436 if ($r == $pipes[1]) {
437
438 $response->stdOut .= fread($pipes[1], 8192);
439
440 if (feof($pipes[1])) {
441
442 fclose($pipes[1]);
443 $stdoutDone = TRUE;
444 }
445 } else if ($r == $pipes[2]) {
446
447 $response->stdErr .= fread($pipes[2], 8192);
448
449 if (feof($pipes[2])) {
450
451 fclose($pipes[2]);
452 $stderrDone = TRUE;
453 }
454 }
455 }
456 if (!is_resource($process)) {
457 $txOff = $txLen;
458 // echo 'PROCESS LOST'; die;
459 // break;
460 }
461
462 $processStatus = proc_get_status($process);
463 if (array_key_exists('running', $processStatus) && !$processStatus['running']) {
464 $txOff = $txLen;
465 // break;
466 }
467
468 if ($txOff >= $txLen && $stdoutDone && $stderrDone) {
469 break;
470 }
471 }
472
473 // Ok - close process (if already running)
474 $response->exitCode = @proc_close($process);
475
476 return $response;
477 }
478
479 public function UTF8Encoder($input) {
480
481 /*
482 * Se il valore in input è una stringa, la ritorniamo subito
483 */
484 if (is_string($input)) {
485 return utf8_encode($input);
486 }
487
488 /*
489 * Nel caso di oggetti, effettiuamo la conversione in array
490 */
491 if (is_object($input)) {
492 $input = (array) $input;
493 }
494
495 $result = array();
496
497 foreach ($input as $key => $value) {
498
499 if (is_array($value)) {
500 $result[$key] = $this->UTF8Encoder($value);
501 } else if (is_string($value)) {
502 $result[$key] = utf8_encode($value);
503 } else {
504 $result[$key] = $value;
505 }
506 }
507
508 return $result;
509 }
510
511 public function XMLEntitiesEscape($input) {
512
513 $mapping = array(
514 '<' => '<',
515 '&' => '&',
516 '>' => '>',
517 "'" => ''',
518 '"' => '"'
519 );
520
521 foreach ($mapping as $unescaped => $escaped) {
522
523 $input = str_replace($unescaped, $escaped, $input);
524 }
525
526 return $input;
527 }
528
529 /**
530 * Headers: GET
531 *
532 * Return extended HTTP Header for incoming request
533 *
534 * @param string $name The header to fetch
535 * @return string The header value
536 */
537 protected function _header($name) {
538
539 $name = strtolower($name);
540
541 $headers = getallheaders();
542
543 foreach ($headers as $header => $value) {
544 $header = strtolower($header);
545 $headersRFC2616[$header] = $value;
546 }
547
548 return (isset($headersRFC2616[$name]) ? $headersRFC2616[$name] : '');
549 }
550}