small cleanups
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_svbase.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 1999-2004 Kasper Skaarhoj (kasper@typo3.com)
6 * All rights reserved
7 *
8 * This script is part of the Typo3 project. The Typo3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 * A copy is found in the textfile GPL.txt and important notices to the license
17 * from the author is found in LICENSE.txt distributed with these scripts.
18 *
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27 /**
28 * Parent class for "Services" classes
29 *
30 * $Id$
31 * TODO: temp files are not removed
32 *
33 * @author René Fritz <r.fritz@colorcube.de>
34 */
35 /**
36 * [CLASS/FUNCTION INDEX of SCRIPT]
37 *
38 *
39 *
40 * 121: class t3lib_svbase
41 *
42 * SECTION: Get service meta information
43 * 175: function getServiceInfo()
44 * 183: function getServiceKey()
45 * 191: function getServiceTitle()
46 *
47 * SECTION: Error handling
48 * 212: function errorPush($errNum=T3_ERR_SV_GENERAL, $errMsg='Unspecified error occured')
49 * 227: function errorPull()
50 * 239: function getLastError()
51 * 254: function getLastErrorMsg()
52 * 269: function getErrorMsgArray()
53 * 287: function getLastErrorArray()
54 * 296: function resetErrors()
55 *
56 * SECTION: General service functions
57 * 316: function checkExec($progList)
58 * 338: function deactivateService()
59 * 344: function available()
60 *
61 * SECTION: IO tools
62 * 382: function checkInputFile ($absFile)
63 * 403: function readFile ($absFile, $length=0)
64 * 426: function writeFile ($content, $absFile='')
65 *
66 * SECTION: IO input
67 * 467: function setInput ($content, $type='')
68 * 481: function setInputFile ($absFile, $type='')
69 * 494: function getInput ()
70 * 509: function getInputFile ($absFile='')
71 *
72 * SECTION: IO output
73 * 534: function setOutputFile ($absFile)
74 * 544: function getOutput ()
75 * 558: function getOutputFile ($absFile='')
76 *
77 * SECTION: Service implementation
78 * 582: function init()
79 * 601: function reset()
80 * 612: function process($content='', $type='', $conf=array())
81 *
82 * TOTAL FUNCTIONS: 26
83 * (This index is automatically created/updated by the extension "extdeveval")
84 *
85 */
86
87
88
89
90
91 define ('T3_ERR_SV_GENERAL', -1); // General error - something went wrong
92 define ('T3_ERR_SV_NOT_AVAIL', -2); // During execution it showed that the service is not available and should be ignored. The service itself should call $this->setNonAvailable()
93 define ('T3_ERR_SV_WRONG_SUBTYPE', -3); // passed subtype is not possible with this service
94 define ('T3_ERR_SV_NO_INPUT', -4); // passed subtype is not possible with this service
95
96
97 define ('T3_ERR_SV_FILE_NOT_FOUND', -20); // File not found which the service should process
98 define ('T3_ERR_SV_FILE_READ', -21); // File not readable
99 define ('T3_ERR_SV_FILE_WRITE', -22); // File not writeable
100
101 define ('T3_ERR_SV_PROG_NOT_FOUND', -40); // passed subtype is not possible with this service
102 define ('T3_ERR_SV_PROG_FAILED', -41); // passed subtype is not possible with this service
103
104 // define ('T3_ERR_SV_serviceType_myerr, -100); // All errors with prefix T3_ERR_SV_[serviceType]_ and lower than -99 are service type dependent error
105
106
107 require_once(PATH_t3lib.'class.t3lib_exec.php');
108
109
110
111
112
113
114 /**
115 * Parent class for "Services" classes
116 *
117 * @author René Fritz <r.fritz@colorcube.de>
118 * @package TYPO3
119 * @subpackage t3lib
120 */
121 class t3lib_svbase {
122
123 /**
124 * service description array
125 */
126 var $info=array();
127
128 /**
129 * error stack
130 */
131 var $error=array();
132
133 /**
134 * Defines if debug messages should be written with t3lib_div::devLog
135 */
136 var $writeDevLog = false;
137
138
139 /**
140 * The output content.
141 * That's what the services produced as result.
142 */
143 var $out = '';
144
145 /**
146 * The file that should be processed.
147 */
148 var $inputFile = '';
149
150 /**
151 * The content that should be processed.
152 */
153 var $inputContent = '';
154
155 /**
156 * The type of the input content (or file). Might be the same as the service subtypes.
157 */
158 var $inputType = '';
159
160 /**
161 * The file where the output should be written to.
162 */
163 var $outputFile = '';
164
165
166 /**
167 * Temporary files which have to be deleted
168 *
169 * @private
170 */
171 var $tempFiles = array();
172
173
174
175 /***************************************
176 *
177 * Get service meta information
178 *
179 ***************************************/
180
181
182 /**
183 * @return array service description array
184 */
185 function getServiceInfo() {
186 return $this->info;
187 }
188
189
190 /**
191 * @return string service key
192 */
193 function getServiceKey() {
194 return $this->info['serviceKey'];
195 }
196
197
198 /**
199 * @return string service title
200 */
201 function getServiceTitle() {
202 return $this->info['title'];
203 }
204
205
206 /**
207 * Returns service configuration values from the $TYPO3_CONF_VARS['SVCONF'] array
208 *
209 * @param string Name of the config option
210 * @return mixed Default configuration value for the service. Will be returned if no value found.
211 * @param boolean If set the 'default' config will be return if no special config for this service is available (default: true)
212 * @return mixed configuration value for the service
213 */
214 function getServiceOption($optionName, $defaultValue='', $includeDefaultConfig=TRUE) {
215 global $TYPO3_CONF_VARS;
216
217 $config = NULL;
218
219 $svOptions = $TYPO3_CONF_VARS['SVCONF'][$this->info['serviceType']];
220
221 if(isset($svOptions[$this->info['serviceKey']][$optionName])) {
222 $config = $svOptions['default'][$optionName];
223 } elseif($includeDefaultConfig AND isset($svOptions['default'][$optionName])) {
224 $config = $svOptions['default'][$optionName];
225 }
226 if(!isset($config)) {
227 $config = $defaultValue;
228 }
229 return $config;
230 }
231
232
233
234 /***************************************
235 *
236 * Error handling
237 *
238 ***************************************/
239
240
241 /**
242 * Logs debug messages to t3lib_div::devLog()
243 *
244 * @param string Debug message
245 * @param integer Severity: 0 is info, 1 is notice, 2 is warning, 3 is fatal error, -1 is "OK" message
246 * @param array Additional data you want to pass to the logger.
247 * @return void
248 */
249 function devLog($msg, $severity=0, $dataVar=FALSE) {
250 if($this->writeDevLog) {
251 t3lib_div::devLog($msg, $this->info['serviceKey'], $severity, $dataVar);
252 }
253 }
254
255
256 /**
257 * Puts an error on the error stack. Calling without parameter adds a general error.
258 *
259 * @param string error message
260 * @param string error number (see T3_ERR_SV_* constants)
261 * @return void
262 */
263 function errorPush($errNum=T3_ERR_SV_GENERAL, $errMsg='Unspecified error occured') {
264 array_push($this->error, array('nr'=>$errNum, 'msg'=>$errMsg));
265
266 if (is_object($GLOBALS["TT"])) {
267 $GLOBALS['TT']->setTSlogMessage($errMsg,2);
268 }
269
270 }
271
272
273 /**
274 * Removes the last error from the error stack.
275 *
276 * @return void
277 */
278 function errorPull() {
279 array_pop($this->error);
280
281 // pop for $GLOBALS['TT']->setTSlogMessage is not supported
282 }
283
284
285 /**
286 * Returns the last error number from the error stack.
287 *
288 * @return string error number
289 */
290 function getLastError() {
291 if(count($this->error)) {
292 $error = end($this->error);
293 return $error['nr'];
294 } else {
295 return TRUE; // means all is ok - no error
296 }
297 }
298
299
300 /**
301 * Returns the last message from the error stack.
302 *
303 * @return string error message
304 */
305 function getLastErrorMsg() {
306 if(count($this->error)) {
307 $error = end($this->error);
308 return $error['msg'];
309 } else {
310 return '';
311 }
312 }
313
314
315 /**
316 * Returns all error messages as array.
317 *
318 * @return array error messages
319 */
320 function getErrorMsgArray() {
321 $errArr = array();
322
323 if(count($this->error)) {
324 reset($this->error);
325 foreach($this->error as $error) {
326 $errArr[] = $error['msg'];
327 }
328 }
329 return $errArr;
330 }
331
332
333 /**
334 * Returns the last array from the error stack.
335 *
336 * @return array error nr and message
337 */
338 function getLastErrorArray() {
339 return end($this->error);
340 }
341
342 /**
343 * Reset the error stack.
344 *
345 * @return void
346 */
347 function resetErrors() {
348 $this->error=array();
349 }
350
351
352
353 /***************************************
354 *
355 * General service functions
356 *
357 ***************************************/
358
359
360
361 /**
362 * check the availability of external programs
363 *
364 * @param string comma list of programs 'perl,python,pdftotext'
365 * @return boolean return FALSE if one program was not found
366 */
367 function checkExec($progList) {
368 $ret = TRUE;
369
370 require_once(PATH_t3lib.'class.t3lib_exec.php');
371
372 $progList = t3lib_div::trimExplode(',', $progList, 1);
373 foreach($progList as $prog) {
374 if (!t3lib_exec::checkCommand($prog)) {
375 // program not found
376 $this->errorPush('External program not found: '.$prog, T3_ERR_SV_PROG_NOT_FOUND);
377 $ret = FALSE;
378 }
379 }
380 return $ret;
381 }
382
383
384 /**
385 * Deactivate the service. Use this if the service fails at runtime and will not be available.
386 *
387 * @return void
388 */
389 function deactivateService() {
390 t3lib_extMgm::deactivateService($this->info['serviceType'], $this->info['serviceKey']);
391 }
392
393
394 /**
395 function available() {
396 global $AB,$BE_USER,$LANG,$BACK_PATH,$TCA_DESCR,$TCA,$CLIENT,$TYPO3_CONF_VARS;
397
398 // check if the service is available at runtime
399 // the sense of this method is that the service might need some more information to check the availablity
400
401 / *
402
403 $excludeServiceKeys='';
404 while (is_object($serviceObj = t3lib_div::makeInstanceService('anyService','', $excludeServiceKeys))) {
405 if ($serviceObj->available('some special parm to check availablity')) {
406 break;
407 }
408 $excludeServiceKeys .= ','.$serviceObj->getServiceKey;
409 unset($serviceObj);
410 }
411
412 * /
413
414 return TRUE;
415 }
416 */
417
418
419 /***************************************
420 *
421 * IO tools
422 *
423 ***************************************/
424
425
426
427 /**
428 * Check if a file exists and is readable.
429 *
430 * @param string File name with absolute path.
431 * @return string File name or FALSE.
432 */
433 function checkInputFile ($absFile) {
434 if(@is_file($absFile)) {
435 if(@is_readable($absFile)) {
436 return $absFile;
437 } else {
438 $this->errorPush(T3_ERR_SV_FILE_READ, 'File is not readable: '.$absFile);
439 }
440 } else {
441 $this->errorPush(T3_ERR_SV_FILE_NOT_FOUND, 'File not found: '.$absFile);
442 }
443 return FALSE;
444 }
445
446
447 /**
448 * Read content from a file a file.
449 *
450 * @param string File name to read from.
451 * @param integer Maximum length to read. If empty the whole file will be read.
452 * @return string $content or FALSE
453 */
454 function readFile ($absFile, $length=0) {
455 $out = FALSE;
456
457 if ($this->checkInputFile ($absFile)) {
458 if ($fd = fopen ($absFile, 'rb')) {
459 $length = intval($length) ? intval($length) : filesize ($absFile);
460 $out = fread ($fd, $length);
461 fclose ($fd);
462 } else {
463 $this->errorPush(T3_ERR_SV_FILE_READ, 'Can not read from file: '.$absFile);
464 }
465 }
466 return $out;
467 }
468
469
470 /**
471 * Write content to a file.
472 *
473 * @param string Content to write to the file
474 * @param string File name to write into. If empty a temp file will be created.
475 * @return string File name or FALSE
476 */
477 function writeFile ($content, $absFile='') {
478 $ret = TRUE;
479
480 if (!$absFile) {
481 $absFile = $this->tempFile($this->prefixId);
482 }
483
484 if($absFile) {
485 if ($fd = @fopen($absFile,'wb')) {
486 @fwrite($fd, $content);
487 @fclose($fd);
488 } else {
489 $this->errorPush(T3_ERR_SV_FILE_WRITE, 'Can not write to file: '.$absFile);
490 $absFile = FALSE;
491 }
492 }
493
494 return $absFile;
495 }
496
497 /**
498 * Create a temporary file.
499 *
500 * @param string File prefix.
501 * @return string File name or FALSE
502 */
503 function tempFile ($filePrefix) {
504 $absFile = t3lib_div::tempnam($filePrefix);
505 if($absFile) {
506 $ret = TRUE;
507 $this->registerTempFile ($absFile);
508 } else {
509 $ret = FALSE;
510 $this->errorPush(T3_ERR_SV_FILE_WRITE, 'Can not create temp file.');
511 }
512 return ($ret ? $absFile : FALSE);
513 }
514
515 /**
516 * Register file which should be deleted afterwards.
517 *
518 * @param string File name with absolute path.
519 * @return void
520 */
521 function registerTempFile ($absFile) {
522 $this->tempFiles[] = $absFile;
523 }
524
525 /**
526 * Delete registered temporary files.
527 *
528 * @param string File name with absolute path.
529 * @return void
530 */
531 function unlinkTempFiles () {
532 foreach ($this->tempFiles as $absFile) {
533 t3lib_div::unlink_tempfile($absFile);
534 }
535 $this->tempFiles = array();
536 }
537
538
539 /***************************************
540 *
541 * IO input
542 *
543 ***************************************/
544
545
546 /**
547 * Set the input content for service processing.
548 *
549 * @param mixed
550 * @param [type] $type: ...
551 * @return [type] ...
552 */
553 function setInput ($content, $type='') {
554 $this->inputContent = $content;
555 $this->inputFile = '';
556 $this->inputType = $type;
557 }
558
559
560 /**
561 * Set the input file name for service processing.
562 *
563 * @param string file name
564 * @param [type] $type: ...
565 * @return [type] ...
566 */
567 function setInputFile ($absFile, $type='') {
568 $this->inputContent = '';
569 $this->inputFile = $absFile;
570 $this->inputType = $type;
571 }
572
573
574 /**
575 * Get the input content.
576 * Will be read from input file if needed.
577 *
578 * @return mixed
579 */
580 function getInput () {
581 if ($this->inputContent=='') {
582 $this->inputContent = $this->readFile($this->inputFile);
583 }
584 return $this->inputContent;
585 }
586
587
588 /**
589 * Get the input file name.
590 * If the content was set by setContent a file will be created.
591 *
592 * @param string File name. If empty a temp file will be created.
593 * @return string File name or FALSE if no input or file error.
594 */
595 function getInputFile ($createFile='') {
596 if($this->inputFile) {
597 $this->inputFile = $this->checkInputFile($this->inputFile);
598 } elseif ($this->inputContent) {
599 $this->inputFile = $this->writeFile($this->inputContent, $createFile);
600 }
601 return $this->inputFile;
602 }
603
604
605
606
607 /***************************************
608 *
609 * IO output
610 *
611 ***************************************/
612
613
614 /**
615 * Set the output file name.
616 *
617 * @param string file name
618 * @return [type] ...
619 */
620 function setOutputFile ($absFile) {
621 $this->outputFile = $absFile;
622 }
623
624
625 /**
626 * Get the output content.
627 *
628 * @return mixed
629 */
630 function getOutput () {
631 if ($this->outputFile) {
632 $this->out = $this->readFile($this->outputFile);
633 }
634 return $this->out;
635 }
636
637
638 /**
639 * Get the output file name.
640 *
641 * @param [type] $absFile: ...
642 * @return mixed
643 */
644 function getOutputFile ($absFile='') {
645 if (!$this->outputFile) {
646 $this->outputFile = $this->writeFile($this->out, $absFile);
647 }
648 return $this->outputFile;
649 }
650
651
652
653
654 /***************************************
655 *
656 * Service implementation
657 *
658 ***************************************/
659
660 /**
661 * Initialization of the service.
662 *
663 * The class have to do a strict check if the service is available.
664 * example: check if the perl interpreter is available which is needed to run an extern perl script.
665 *
666 * @return boolean TRUE if the service is available
667 */
668 function init() {
669 // do not work :-( but will not hurt
670 register_shutdown_function(array(&$this, '__destruct'));
671 // look in makeInstanceService()
672
673 $this->reset();
674
675 // check for external programs which are defined by $info['exec']
676 if (trim($this->info['exec'])) {
677 if (!$this->checkExec($this->info['exec'])) {
678 // nothing todo here or?
679 }
680 }
681
682 return $this->getLastError();
683 }
684
685
686 /**
687 * Resets the service.
688 * Will be called by init(). Should be used before every use if a service instance is used multiple times.
689 *
690 * @return void
691 */
692 function reset() {
693 $this->unlinkTempFiles();
694 $this->resetErrors();
695 $this->out = '';
696 $this->inputFile = '';
697 $this->inputContent = '';
698 $this->inputType = '';
699 $this->outputFile = '';
700 }
701
702 /**
703 * Clean up the service.
704 *
705 * @return void
706 */
707 function __destruct() {
708 $this->unlinkTempFiles();
709 }
710
711
712 /* every service type has it's own API
713 function process($content='', $type='', $conf=array()) {
714 }
715 */
716
717 }
718
719 /**
720 // Does not make sense, because this class is always extended by the service classes..
721 if (defined("TYPO3_MODE") && $TYPO3_CONF_VARS[TYPO3_MODE]["XCLASS"]["t3lib/class.t3lib_svbase.php"]) {
722 include_once($TYPO3_CONF_VARS[TYPO3_MODE]["XCLASS"]["t3lib/class.t3lib_svbase.php"]);
723 }
724 */
725
726 ?>