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