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