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