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