small fix
[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 if ($length > 0) {
461 $out = fread ($fd, $length);
462 }
463 fclose ($fd);
464 } else {
465 $this->errorPush(T3_ERR_SV_FILE_READ, 'Can not read from file: '.$absFile);
466 }
467 }
468 return $out;
469 }
470
471
472 /**
473 * Write content to a file.
474 *
475 * @param string Content to write to the file
476 * @param string File name to write into. If empty a temp file will be created.
477 * @return string File name or FALSE
478 */
479 function writeFile ($content, $absFile='') {
480 $ret = TRUE;
481
482 if (!$absFile) {
483 $absFile = $this->tempFile($this->prefixId);
484 }
485
486 if($absFile) {
487 if ($fd = @fopen($absFile,'wb')) {
488 @fwrite($fd, $content);
489 @fclose($fd);
490 } else {
491 $this->errorPush(T3_ERR_SV_FILE_WRITE, 'Can not write to file: '.$absFile);
492 $absFile = FALSE;
493 }
494 }
495
496 return $absFile;
497 }
498
499 /**
500 * Create a temporary file.
501 *
502 * @param string File prefix.
503 * @return string File name or FALSE
504 */
505 function tempFile ($filePrefix) {
506 $absFile = t3lib_div::tempnam($filePrefix);
507 if($absFile) {
508 $ret = TRUE;
509 $this->registerTempFile ($absFile);
510 } else {
511 $ret = FALSE;
512 $this->errorPush(T3_ERR_SV_FILE_WRITE, 'Can not create temp file.');
513 }
514 return ($ret ? $absFile : FALSE);
515 }
516
517 /**
518 * Register file which should be deleted afterwards.
519 *
520 * @param string File name with absolute path.
521 * @return void
522 */
523 function registerTempFile ($absFile) {
524 $this->tempFiles[] = $absFile;
525 }
526
527 /**
528 * Delete registered temporary files.
529 *
530 * @param string File name with absolute path.
531 * @return void
532 */
533 function unlinkTempFiles () {
534 foreach ($this->tempFiles as $absFile) {
535 t3lib_div::unlink_tempfile($absFile);
536 }
537 $this->tempFiles = array();
538 }
539
540
541 /***************************************
542 *
543 * IO input
544 *
545 ***************************************/
546
547
548 /**
549 * Set the input content for service processing.
550 *
551 * @param mixed
552 * @param [type] $type: ...
553 * @return [type] ...
554 */
555 function setInput ($content, $type='') {
556 $this->inputContent = $content;
557 $this->inputFile = '';
558 $this->inputType = $type;
559 }
560
561
562 /**
563 * Set the input file name for service processing.
564 *
565 * @param string file name
566 * @param [type] $type: ...
567 * @return [type] ...
568 */
569 function setInputFile ($absFile, $type='') {
570 $this->inputContent = '';
571 $this->inputFile = $absFile;
572 $this->inputType = $type;
573 }
574
575
576 /**
577 * Get the input content.
578 * Will be read from input file if needed.
579 *
580 * @return mixed
581 */
582 function getInput () {
583 if ($this->inputContent=='') {
584 $this->inputContent = $this->readFile($this->inputFile);
585 }
586 return $this->inputContent;
587 }
588
589
590 /**
591 * Get the input file name.
592 * If the content was set by setContent a file will be created.
593 *
594 * @param string File name. If empty a temp file will be created.
595 * @return string File name or FALSE if no input or file error.
596 */
597 function getInputFile ($createFile='') {
598 if($this->inputFile) {
599 $this->inputFile = $this->checkInputFile($this->inputFile);
600 } elseif ($this->inputContent) {
601 $this->inputFile = $this->writeFile($this->inputContent, $createFile);
602 }
603 return $this->inputFile;
604 }
605
606
607
608
609 /***************************************
610 *
611 * IO output
612 *
613 ***************************************/
614
615
616 /**
617 * Set the output file name.
618 *
619 * @param string file name
620 * @return [type] ...
621 */
622 function setOutputFile ($absFile) {
623 $this->outputFile = $absFile;
624 }
625
626
627 /**
628 * Get the output content.
629 *
630 * @return mixed
631 */
632 function getOutput () {
633 if ($this->outputFile) {
634 $this->out = $this->readFile($this->outputFile);
635 }
636 return $this->out;
637 }
638
639
640 /**
641 * Get the output file name.
642 *
643 * @param [type] $absFile: ...
644 * @return mixed
645 */
646 function getOutputFile ($absFile='') {
647 if (!$this->outputFile) {
648 $this->outputFile = $this->writeFile($this->out, $absFile);
649 }
650 return $this->outputFile;
651 }
652
653
654
655
656 /***************************************
657 *
658 * Service implementation
659 *
660 ***************************************/
661
662 /**
663 * Initialization of the service.
664 *
665 * The class have to do a strict check if the service is available.
666 * example: check if the perl interpreter is available which is needed to run an extern perl script.
667 *
668 * @return boolean TRUE if the service is available
669 */
670 function init() {
671 // do not work :-( but will not hurt
672 register_shutdown_function(array(&$this, '__destruct'));
673 // look in makeInstanceService()
674
675 $this->reset();
676
677 // check for external programs which are defined by $info['exec']
678 if (trim($this->info['exec'])) {
679 if (!$this->checkExec($this->info['exec'])) {
680 // nothing todo here or?
681 }
682 }
683
684 return $this->getLastError();
685 }
686
687
688 /**
689 * Resets the service.
690 * Will be called by init(). Should be used before every use if a service instance is used multiple times.
691 *
692 * @return void
693 */
694 function reset() {
695 $this->unlinkTempFiles();
696 $this->resetErrors();
697 $this->out = '';
698 $this->inputFile = '';
699 $this->inputContent = '';
700 $this->inputType = '';
701 $this->outputFile = '';
702 }
703
704 /**
705 * Clean up the service.
706 *
707 * @return void
708 */
709 function __destruct() {
710 $this->unlinkTempFiles();
711 }
712
713
714 /* every service type has it's own API
715 function process($content='', $type='', $conf=array()) {
716 }
717 */
718
719 }
720
721 /**
722 // Does not make sense, because this class is always extended by the service classes..
723 if (defined("TYPO3_MODE") && $TYPO3_CONF_VARS[TYPO3_MODE]["XCLASS"]["t3lib/class.t3lib_svbase.php"]) {
724 include_once($TYPO3_CONF_VARS[TYPO3_MODE]["XCLASS"]["t3lib/class.t3lib_svbase.php"]);
725 }
726 */
727
728 ?>