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