Fixed bug #10735: Wrong returnUrl with clipboard actions
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_svbase.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 1999-2009 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 Rene 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 Rene Fritz <r.fritz@colorcube.de>
122 * @package TYPO3
123 * @subpackage t3lib
124 */
125 abstract 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 $config = NULL;
226
227 $svOptions = $GLOBALS['TYPO3_CONF_VARS']['SVCONF'][$this->info['serviceType']];
228
229 if(isset($svOptions[$this->info['serviceKey']][$optionName])) {
230 $config = $svOptions[$this->info['serviceKey']][$optionName];
231 } elseif($includeDefaultConfig AND isset($svOptions['default'][$optionName])) {
232 $config = $svOptions['default'][$optionName];
233 }
234 if(!isset($config)) {
235 $config = $defaultValue;
236 }
237 return $config;
238 }
239
240
241
242 /***************************************
243 *
244 * Error handling
245 *
246 ***************************************/
247
248
249 /**
250 * Logs debug messages to t3lib_div::devLog()
251 *
252 * @param string Debug message
253 * @param integer Severity: 0 is info, 1 is notice, 2 is warning, 3 is fatal error, -1 is "OK" message
254 * @param array Additional data you want to pass to the logger.
255 * @return void
256 */
257 function devLog($msg, $severity=0, $dataVar=FALSE) {
258 if($this->writeDevLog) {
259 t3lib_div::devLog($msg, $this->info['serviceKey'], $severity, $dataVar);
260 }
261 }
262
263
264 /**
265 * Puts an error on the error stack. Calling without parameter adds a general error.
266 *
267 * @param string error message
268 * @param string error number (see T3_ERR_SV_* constants)
269 * @return void
270 */
271 function errorPush($errNum=T3_ERR_SV_GENERAL, $errMsg='Unspecified error occured') {
272 array_push($this->error, array('nr'=>$errNum, 'msg'=>$errMsg));
273
274 if (is_object($GLOBALS['TT'])) {
275 $GLOBALS['TT']->setTSlogMessage($errMsg,2);
276 }
277
278 }
279
280
281 /**
282 * Removes the last error from the error stack.
283 *
284 * @return void
285 */
286 function errorPull() {
287 array_pop($this->error);
288
289 // pop for $GLOBALS['TT']->setTSlogMessage is not supported
290 }
291
292
293 /**
294 * Returns the last error number from the error stack.
295 *
296 * @return string error number
297 */
298 function getLastError() {
299 if(count($this->error)) {
300 $error = end($this->error);
301 return $error['nr'];
302 } else {
303 return TRUE; // means all is ok - no error
304 }
305 }
306
307
308 /**
309 * Returns the last message from the error stack.
310 *
311 * @return string error message
312 */
313 function getLastErrorMsg() {
314 if(count($this->error)) {
315 $error = end($this->error);
316 return $error['msg'];
317 } else {
318 return '';
319 }
320 }
321
322
323 /**
324 * Returns all error messages as array.
325 *
326 * @return array error messages
327 */
328 function getErrorMsgArray() {
329 $errArr = array();
330
331 if(count($this->error)) {
332 reset($this->error);
333 foreach($this->error as $error) {
334 $errArr[] = $error['msg'];
335 }
336 }
337 return $errArr;
338 }
339
340
341 /**
342 * Returns the last array from the error stack.
343 *
344 * @return array error nr and message
345 */
346 function getLastErrorArray() {
347 return end($this->error);
348 }
349
350 /**
351 * Reset the error stack.
352 *
353 * @return void
354 */
355 function resetErrors() {
356 $this->error=array();
357 }
358
359
360
361 /***************************************
362 *
363 * General service functions
364 *
365 ***************************************/
366
367
368
369 /**
370 * check the availability of external programs
371 *
372 * @param string comma list of programs 'perl,python,pdftotext'
373 * @return boolean return FALSE if one program was not found
374 */
375 function checkExec($progList) {
376 $ret = TRUE;
377
378 require_once(PATH_t3lib.'class.t3lib_exec.php');
379
380 $progList = t3lib_div::trimExplode(',', $progList, 1);
381 foreach($progList as $prog) {
382 if (!t3lib_exec::checkCommand($prog)) {
383 // program not found
384 $this->errorPush('External program not found: '.$prog, T3_ERR_SV_PROG_NOT_FOUND);
385 $ret = FALSE;
386 }
387 }
388 return $ret;
389 }
390
391
392 /**
393 * Deactivate the service. Use this if the service fails at runtime and will not be available.
394 *
395 * @return void
396 */
397 function deactivateService() {
398 t3lib_extMgm::deactivateService($this->info['serviceType'], $this->info['serviceKey']);
399 }
400
401
402
403
404
405
406
407
408
409 /***************************************
410 *
411 * IO tools
412 *
413 ***************************************/
414
415
416
417 /**
418 * Check if a file exists and is readable.
419 *
420 * @param string File name with absolute path.
421 * @return string File name or FALSE.
422 */
423 function checkInputFile ($absFile) {
424 if(t3lib_div::isAllowedAbsPath($absFile) && @is_file($absFile)) {
425 if(@is_readable($absFile)) {
426 return $absFile;
427 } else {
428 $this->errorPush(T3_ERR_SV_FILE_READ, 'File is not readable: '.$absFile);
429 }
430 } else {
431 $this->errorPush(T3_ERR_SV_FILE_NOT_FOUND, 'File not found: '.$absFile);
432 }
433 return FALSE;
434 }
435
436
437 /**
438 * Read content from a file a file.
439 *
440 * @param string File name to read from.
441 * @param integer Maximum length to read. If empty the whole file will be read.
442 * @return string $content or FALSE
443 */
444 function readFile ($absFile, $length=0) {
445 $out = FALSE;
446
447 if ($this->checkInputFile($absFile)) {
448 $out = file_get_contents($absFile);
449 if ($out===FALSE) {
450 $this->errorPush(T3_ERR_SV_FILE_READ, 'Can not read from file: '.$absFile);
451 }
452 }
453 return $out;
454 }
455
456
457 /**
458 * Write content to a file.
459 *
460 * @param string Content to write to the file
461 * @param string File name to write into. If empty a temp file will be created.
462 * @return string File name or FALSE
463 */
464 function writeFile ($content, $absFile='') {
465 $ret = TRUE;
466
467 if (!$absFile) {
468 $absFile = $this->tempFile($this->prefixId);
469 }
470
471 if($absFile && t3lib_div::isAllowedAbsPath($absFile)) {
472 if ($fd = @fopen($absFile,'wb')) {
473 @fwrite($fd, $content);
474 @fclose($fd);
475 } else {
476 $this->errorPush(T3_ERR_SV_FILE_WRITE, 'Can not write to file: '.$absFile);
477 $absFile = FALSE;
478 }
479 }
480
481 return $absFile;
482 }
483
484 /**
485 * Create a temporary file.
486 *
487 * @param string File prefix.
488 * @return string File name or FALSE
489 */
490 function tempFile ($filePrefix) {
491 $absFile = t3lib_div::tempnam($filePrefix);
492 if($absFile) {
493 $ret = TRUE;
494 $this->registerTempFile ($absFile);
495 } else {
496 $ret = FALSE;
497 $this->errorPush(T3_ERR_SV_FILE_WRITE, 'Can not create temp file.');
498 }
499 return ($ret ? $absFile : FALSE);
500 }
501
502 /**
503 * Register file which should be deleted afterwards.
504 *
505 * @param string File name with absolute path.
506 * @return void
507 */
508 function registerTempFile ($absFile) {
509 $this->tempFiles[] = $absFile;
510 }
511
512 /**
513 * Delete registered temporary files.
514 *
515 * @param string File name with absolute path.
516 * @return void
517 */
518 function unlinkTempFiles () {
519 foreach ($this->tempFiles as $absFile) {
520 t3lib_div::unlink_tempfile($absFile);
521 }
522 $this->tempFiles = array();
523 }
524
525
526 /***************************************
527 *
528 * IO input
529 *
530 ***************************************/
531
532
533 /**
534 * Set the input content for service processing.
535 *
536 * @param mixed Input content (going into ->inputContent)
537 * @param string The type of the input content (or file). Might be the same as the service subtypes.
538 * @return void
539 */
540 function setInput ($content, $type='') {
541 $this->inputContent = $content;
542 $this->inputFile = '';
543 $this->inputType = $type;
544 }
545
546
547 /**
548 * Set the input file name for service processing.
549 *
550 * @param string file name
551 * @param string The type of the input content (or file). Might be the same as the service subtypes.
552 * @return void
553 */
554 function setInputFile ($absFile, $type='') {
555 $this->inputContent = '';
556 $this->inputFile = $absFile;
557 $this->inputType = $type;
558 }
559
560
561 /**
562 * Get the input content.
563 * Will be read from input file if needed. (That is if ->inputContent is empty and ->inputFile is not)
564 *
565 * @return mixed
566 */
567 function getInput () {
568 if ($this->inputContent=='') {
569 $this->inputContent = $this->readFile($this->inputFile);
570 }
571 return $this->inputContent;
572 }
573
574
575 /**
576 * Get the input file name.
577 * If the content was set by setContent a file will be created.
578 *
579 * @param string File name. If empty a temp file will be created.
580 * @return string File name or FALSE if no input or file error.
581 */
582 function getInputFile ($createFile='') {
583 if($this->inputFile) {
584 $this->inputFile = $this->checkInputFile($this->inputFile);
585 } elseif ($this->inputContent) {
586 $this->inputFile = $this->writeFile($this->inputContent, $createFile);
587 }
588 return $this->inputFile;
589 }
590
591
592
593
594 /***************************************
595 *
596 * IO output
597 *
598 ***************************************/
599
600
601 /**
602 * Set the output file name.
603 *
604 * @param string file name
605 * @return void
606 */
607 function setOutputFile ($absFile) {
608 $this->outputFile = $absFile;
609 }
610
611
612 /**
613 * Get the output content.
614 *
615 * @return mixed
616 */
617 function getOutput () {
618 if ($this->outputFile) {
619 $this->out = $this->readFile($this->outputFile);
620 }
621 return $this->out;
622 }
623
624
625 /**
626 * Get the output file name. If no output file is set, the ->out buffer is written to the file given by input parameter filename
627 *
628 * @param string Absolute filename to write to
629 * @return mixed
630 */
631 function getOutputFile ($absFile='') {
632 if (!$this->outputFile) {
633 $this->outputFile = $this->writeFile($this->out, $absFile);
634 }
635 return $this->outputFile;
636 }
637
638
639
640
641 /***************************************
642 *
643 * Service implementation
644 *
645 ***************************************/
646
647 /**
648 * Initialization of the service.
649 *
650 * The class have to do a strict check if the service is available.
651 * example: check if the perl interpreter is available which is needed to run an extern perl script.
652 *
653 * @return boolean TRUE if the service is available
654 */
655 function init() {
656 // do not work :-( but will not hurt
657 register_shutdown_function(array(&$this, '__destruct'));
658 // look in makeInstanceService()
659
660 $this->reset();
661
662 // check for external programs which are defined by $info['exec']
663 if (trim($this->info['exec'])) {
664 if (!$this->checkExec($this->info['exec'])) {
665 // nothing todo here or?
666 }
667 }
668
669 return ($this->getLastError() === true);
670 }
671
672
673 /**
674 * Resets the service.
675 * Will be called by init(). Should be used before every use if a service instance is used multiple times.
676 *
677 * @return void
678 */
679 function reset() {
680 $this->unlinkTempFiles();
681 $this->resetErrors();
682 $this->out = '';
683 $this->inputFile = '';
684 $this->inputContent = '';
685 $this->inputType = '';
686 $this->outputFile = '';
687 }
688
689 /**
690 * Clean up the service.
691 *
692 * @return void
693 */
694 function __destruct() {
695 $this->unlinkTempFiles();
696 }
697
698
699 /* every service type has it's own API
700 function process($content='', $type='', $conf=array()) { //
701 }
702 */
703
704 }
705
706 /**
707 // Does not make sense, because this class is always extended by the service classes..
708 if (defined("TYPO3_MODE") && $TYPO3_CONF_VARS[TYPO3_MODE]["XCLASS"]["t3lib/class.t3lib_svbase.php"]) {
709 include_once($TYPO3_CONF_VARS[TYPO3_MODE]["XCLASS"]["t3lib/class.t3lib_svbase.php"]);
710 }
711 */
712
713 ?>