[TASK] Re-work/simplify copyright header in PHP files - Part 4
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / Service / AbstractService.php
1 <?php
2 namespace TYPO3\CMS\Core\Service;
3
4 /**
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 /**
18 * Parent class for "Services" classes
19 *
20 * @author René Fritz <r.fritz@colorcube.de>
21 */
22 abstract class AbstractService {
23
24 /**
25 * @var array service description array
26 * @todo Define visibility
27 */
28 public $info = array();
29
30 /**
31 * @var array error stack
32 * @todo Define visibility
33 */
34 public $error = array();
35
36 /**
37 * @var bool Defines if debug messages should be written with \TYPO3\CMS\Core\Utility\GeneralUtility::devLog
38 * @todo Define visibility
39 */
40 public $writeDevLog = FALSE;
41
42 /**
43 * @var string The output content. That's what the services produced as result.
44 * @todo Define visibility
45 */
46 public $out = '';
47
48 /**
49 * @var string The file that should be processed.
50 * @todo Define visibility
51 */
52 public $inputFile = '';
53
54 /**
55 * @var string The content that should be processed.
56 * @todo Define visibility
57 */
58 public $inputContent = '';
59
60 /**
61 * @var string The type of the input content (or file). Might be the same as the service subtypes.
62 * @todo Define visibility
63 */
64 public $inputType = '';
65
66 /**
67 * @var string The file where the output should be written to.
68 * @todo Define visibility
69 */
70 public $outputFile = '';
71
72 /**
73 * Temporary files which have to be deleted
74 *
75 * @private
76 * @todo Define visibility
77 */
78 public $tempFiles = array();
79
80 /**
81 * @var array list of registered shutdown functions; should be used to prevent registering the same function multiple times
82 */
83 protected $shutdownRegistry = array();
84
85 /**
86 * @var string Prefix for temporary files
87 */
88 protected $prefixId = '';
89
90 /***************************************
91 *
92 * Get service meta information
93 *
94 ***************************************/
95 /**
96 * Returns internal information array for service
97 *
98 * @return array Service description array
99 * @todo Define visibility
100 */
101 public function getServiceInfo() {
102 return $this->info;
103 }
104
105 /**
106 * Returns the service key of the service
107 *
108 * @return string Service key
109 * @todo Define visibility
110 */
111 public function getServiceKey() {
112 return $this->info['serviceKey'];
113 }
114
115 /**
116 * Returns the title of the service
117 *
118 * @return string Service title
119 * @todo Define visibility
120 */
121 public function getServiceTitle() {
122 return $this->info['title'];
123 }
124
125 /**
126 * Returns service configuration values from the $TYPO3_CONF_VARS['SVCONF'] array
127 *
128 * @param string $optionName Name of the config option
129 * @param mixed $defaultValue Default configuration if no special config is available
130 * @param boolean $includeDefaultConfig If set the 'default' config will be returned if no special config for this service is available (default: TRUE)
131 * @return mixed Configuration value for the service
132 * @todo Define visibility
133 */
134 public function getServiceOption($optionName, $defaultValue = '', $includeDefaultConfig = TRUE) {
135 $config = NULL;
136 $svOptions = $GLOBALS['TYPO3_CONF_VARS']['SVCONF'][$this->info['serviceType']];
137 if (isset($svOptions[$this->info['serviceKey']][$optionName])) {
138 $config = $svOptions[$this->info['serviceKey']][$optionName];
139 } elseif ($includeDefaultConfig && isset($svOptions['default'][$optionName])) {
140 $config = $svOptions['default'][$optionName];
141 }
142 if (!isset($config)) {
143 $config = $defaultValue;
144 }
145 return $config;
146 }
147
148 /***************************************
149 *
150 * Error handling
151 *
152 ***************************************/
153 /**
154 * Logs debug messages to \TYPO3\CMS\Core\Utility\GeneralUtility::devLog()
155 *
156 * @param string $msg Debug message
157 * @param integer $severity Severity: 0 is info, 1 is notice, 2 is warning, 3 is fatal error, -1 is "OK" message
158 * @param array|boolean $dataVar dditional data you want to pass to the logger.
159 * @return void
160 * @todo Define visibility
161 */
162 public function devLog($msg, $severity = 0, $dataVar = FALSE) {
163 if ($this->writeDevLog) {
164 \TYPO3\CMS\Core\Utility\GeneralUtility::devLog($msg, $this->info['serviceKey'], $severity, $dataVar);
165 }
166 }
167
168 /**
169 * Puts an error on the error stack. Calling without parameter adds a general error.
170 *
171 * @param integer $errNum Error number (see T3_ERR_SV_* constants)
172 * @param string $errMsg Error message
173 * @return void
174 * @todo Define visibility
175 */
176 public function errorPush($errNum = T3_ERR_SV_GENERAL, $errMsg = 'Unspecified error occurred') {
177 array_push($this->error, array('nr' => $errNum, 'msg' => $errMsg));
178 if (is_object($GLOBALS['TT'])) {
179 $GLOBALS['TT']->setTSlogMessage($errMsg, 2);
180 }
181 }
182
183 /**
184 * Removes the last error from the error stack.
185 *
186 * @return void
187 * @todo Define visibility
188 */
189 public function errorPull() {
190 array_pop($this->error);
191 }
192
193 /**
194 * Returns the last error number from the error stack.
195 *
196 * @return integer|boolean Error number (or TRUE if no error)
197 * @todo Define visibility
198 */
199 public function getLastError() {
200 // Means all is ok - no error
201 $lastError = TRUE;
202 if (count($this->error)) {
203 $error = end($this->error);
204 $lastError = $error['nr'];
205 }
206 return $lastError;
207 }
208
209 /**
210 * Returns the last message from the error stack.
211 *
212 * @return string Error message
213 * @todo Define visibility
214 */
215 public function getLastErrorMsg() {
216 $lastErrorMessage = '';
217 if (count($this->error)) {
218 $error = end($this->error);
219 $lastErrorMessage = $error['msg'];
220 }
221 return $lastErrorMessage;
222 }
223
224 /**
225 * Returns all error messages as array.
226 *
227 * @return array Error messages
228 * @todo Define visibility
229 */
230 public function getErrorMsgArray() {
231 $errArr = array();
232 if (count($this->error)) {
233 foreach ($this->error as $error) {
234 $errArr[] = $error['msg'];
235 }
236 }
237 return $errArr;
238 }
239
240 /**
241 * Returns the last array from the error stack.
242 *
243 * @return array Error number and message
244 * @todo Define visibility
245 */
246 public function getLastErrorArray() {
247 return end($this->error);
248 }
249
250 /**
251 * Reset the error stack.
252 *
253 * @return void
254 * @todo Define visibility
255 */
256 public function resetErrors() {
257 $this->error = array();
258 }
259
260 /***************************************
261 *
262 * General service functions
263 *
264 ***************************************/
265 /**
266 * check the availability of external programs
267 *
268 * @param string $progList Comma list of programs 'perl,python,pdftotext'
269 * @return boolean Return FALSE if one program was not found
270 * @todo Define visibility
271 */
272 public function checkExec($progList) {
273 $ret = TRUE;
274 $progList = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $progList, TRUE);
275 foreach ($progList as $prog) {
276 if (!\TYPO3\CMS\Core\Utility\CommandUtility::checkCommand($prog)) {
277 // Program not found
278 $this->errorPush(T3_ERR_SV_PROG_NOT_FOUND, 'External program not found: ' . $prog);
279 $ret = FALSE;
280 }
281 }
282 return $ret;
283 }
284
285 /**
286 * Deactivate the service. Use this if the service fails at runtime and will not be available.
287 *
288 * @return void
289 * @todo Define visibility
290 */
291 public function deactivateService() {
292 \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::deactivateService($this->info['serviceType'], $this->info['serviceKey']);
293 }
294
295 /***************************************
296 *
297 * IO tools
298 *
299 ***************************************/
300 /**
301 * Check if a file exists and is readable.
302 *
303 * @param string $absFile File name with absolute path.
304 * @return string|boolean File name or FALSE.
305 * @todo Define visibility
306 */
307 public function checkInputFile($absFile) {
308 $checkResult = FALSE;
309 if (\TYPO3\CMS\Core\Utility\GeneralUtility::isAllowedAbsPath($absFile) && @is_file($absFile)) {
310 if (@is_readable($absFile)) {
311 $checkResult = $absFile;
312 } else {
313 $this->errorPush(T3_ERR_SV_FILE_READ, 'File is not readable: ' . $absFile);
314 }
315 } else {
316 $this->errorPush(T3_ERR_SV_FILE_NOT_FOUND, 'File not found: ' . $absFile);
317 }
318 return $checkResult;
319 }
320
321 /**
322 * Read content from a file a file.
323 *
324 * @param string $absFile File name to read from.
325 * @param integer $length Maximum length to read. If empty the whole file will be read.
326 * @return string|boolean $content or FALSE
327 * @todo Define visibility
328 */
329 public function readFile($absFile, $length = 0) {
330 $out = FALSE;
331 if ($this->checkInputFile($absFile)) {
332 $out = file_get_contents($absFile);
333 if ($out === FALSE) {
334 $this->errorPush(T3_ERR_SV_FILE_READ, 'Can not read from file: ' . $absFile);
335 }
336 }
337 return $out;
338 }
339
340 /**
341 * Write content to a file.
342 *
343 * @param string $content Content to write to the file
344 * @param string $absFile File name to write into. If empty a temp file will be created.
345 * @return string|boolean File name or FALSE
346 * @todo Define visibility
347 */
348 public function writeFile($content, $absFile = '') {
349 if (!$absFile) {
350 $absFile = $this->tempFile($this->prefixId);
351 }
352 if ($absFile && \TYPO3\CMS\Core\Utility\GeneralUtility::isAllowedAbsPath($absFile)) {
353 if ($fd = @fopen($absFile, 'wb')) {
354 @fwrite($fd, $content);
355 @fclose($fd);
356 } else {
357 $this->errorPush(T3_ERR_SV_FILE_WRITE, 'Can not write to file: ' . $absFile);
358 $absFile = FALSE;
359 }
360 }
361 return $absFile;
362 }
363
364 /**
365 * Create a temporary file.
366 *
367 * @param string $filePrefix File prefix.
368 * @return string|boolean File name or FALSE
369 * @todo Define visibility
370 */
371 public function tempFile($filePrefix) {
372 $absFile = \TYPO3\CMS\Core\Utility\GeneralUtility::tempnam($filePrefix);
373 if ($absFile) {
374 $ret = $absFile;
375 $this->registerTempFile($absFile);
376 } else {
377 $ret = FALSE;
378 $this->errorPush(T3_ERR_SV_FILE_WRITE, 'Can not create temp file.');
379 }
380 return $ret;
381 }
382
383 /**
384 * Register file which should be deleted afterwards.
385 *
386 * @param string File name with absolute path.
387 * @return void
388 * @todo Define visibility
389 */
390 public function registerTempFile($absFile) {
391 if (!isset($this->shutdownRegistry[__METHOD__])) {
392 register_shutdown_function(array($this, 'unlinkTempFiles'));
393 $this->shutdownRegistry[__METHOD__] = TRUE;
394 }
395 $this->tempFiles[] = $absFile;
396 }
397
398 /**
399 * Delete registered temporary files.
400 *
401 * @return void
402 * @todo Define visibility
403 */
404 public function unlinkTempFiles() {
405 foreach ($this->tempFiles as $absFile) {
406 \TYPO3\CMS\Core\Utility\GeneralUtility::unlink_tempfile($absFile);
407 }
408 $this->tempFiles = array();
409 }
410
411 /***************************************
412 *
413 * IO input
414 *
415 ***************************************/
416 /**
417 * Set the input content for service processing.
418 *
419 * @param mixed $content Input content (going into ->inputContent)
420 * @param string $type The type of the input content (or file). Might be the same as the service subtypes.
421 * @return void
422 * @todo Define visibility
423 */
424 public function setInput($content, $type = '') {
425 $this->inputContent = $content;
426 $this->inputFile = '';
427 $this->inputType = $type;
428 }
429
430 /**
431 * Set the input file name for service processing.
432 *
433 * @param string $absFile File name
434 * @param string $type The type of the input content (or file). Might be the same as the service subtypes.
435 * @return void
436 * @todo Define visibility
437 */
438 public function setInputFile($absFile, $type = '') {
439 $this->inputContent = '';
440 $this->inputFile = $absFile;
441 $this->inputType = $type;
442 }
443
444 /**
445 * Get the input content.
446 * Will be read from input file if needed. (That is if ->inputContent is empty and ->inputFile is not)
447 *
448 * @return mixed
449 * @todo Define visibility
450 */
451 public function getInput() {
452 if ($this->inputContent == '') {
453 $this->inputContent = $this->readFile($this->inputFile);
454 }
455 return $this->inputContent;
456 }
457
458 /**
459 * Get the input file name.
460 * If the content was set by setContent a file will be created.
461 *
462 * @param string $createFile File name. If empty a temp file will be created.
463 * @return string File name or FALSE if no input or file error.
464 * @todo Define visibility
465 */
466 public function getInputFile($createFile = '') {
467 if ($this->inputFile) {
468 $this->inputFile = $this->checkInputFile($this->inputFile);
469 } elseif ($this->inputContent) {
470 $this->inputFile = $this->writeFile($this->inputContent, $createFile);
471 }
472 return $this->inputFile;
473 }
474
475 /***************************************
476 *
477 * IO output
478 *
479 ***************************************/
480 /**
481 * Set the output file name.
482 *
483 * @param string $absFile File name
484 * @return void
485 * @todo Define visibility
486 */
487 public function setOutputFile($absFile) {
488 $this->outputFile = $absFile;
489 }
490
491 /**
492 * Get the output content.
493 *
494 * @return mixed
495 * @todo Define visibility
496 */
497 public function getOutput() {
498 if ($this->outputFile) {
499 $this->out = $this->readFile($this->outputFile);
500 }
501 return $this->out;
502 }
503
504 /**
505 * Get the output file name. If no output file is set, the ->out buffer is written to the file given by input parameter filename
506 *
507 * @param string $absFile Absolute filename to write to
508 * @return mixed
509 * @todo Define visibility
510 */
511 public function getOutputFile($absFile = '') {
512 if (!$this->outputFile) {
513 $this->outputFile = $this->writeFile($this->out, $absFile);
514 }
515 return $this->outputFile;
516 }
517
518 /***************************************
519 *
520 * Service implementation
521 *
522 ***************************************/
523 /**
524 * Initialization of the service.
525 *
526 * The class have to do a strict check if the service is available.
527 * example: check if the perl interpreter is available which is needed to run an extern perl script.
528 *
529 * @return boolean TRUE if the service is available
530 * @todo Define visibility
531 */
532 public function init() {
533 // look in makeInstanceService()
534 $this->reset();
535 // Check for external programs which are defined by $info['exec']
536 if (trim($this->info['exec'])) {
537 if (!$this->checkExec($this->info['exec'])) {
538
539 }
540 }
541 return $this->getLastError() === TRUE;
542 }
543
544 /**
545 * Resets the service.
546 * Will be called by init(). Should be used before every use if a service instance is used multiple times.
547 *
548 * @return void
549 * @todo Define visibility
550 */
551 public function reset() {
552 $this->unlinkTempFiles();
553 $this->resetErrors();
554 $this->out = '';
555 $this->inputFile = '';
556 $this->inputContent = '';
557 $this->inputType = '';
558 $this->outputFile = '';
559 }
560
561 /**
562 * Clean up the service.
563 * Child classes should explicitly call parent::__destruct() in their destructors for this to work
564 *
565 * @return void
566 * @todo Define visibility
567 */
568 public function __destruct() {
569 $this->unlinkTempFiles();
570 }
571
572 }