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