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