5b2b4431cc982a9451d787c110fb72dd0afe1c12
[Packages/TYPO3.CMS.git] / typo3 / sysext / statictemplates / media / scripts / fe_adminLib.inc
1 <?php
2 /***************************************************************
3 *  Copyright notice
4 *
5 *  (c) 1999-2009 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  * FE admin lib
29  *
30  * Revised for TYPO3 3.6 June/2003 by Kasper Skårhøj
31  *
32  * @author      Kasper Skårhøj <kasperYYYY@typo3.com>
33  */
34 /**
35  * This library provides a HTML-template file based framework for Front End creating/editing/deleting records authenticated by email or fe_user login.
36  * It is used in the extensions "direct_mail_subscription" and "feuser_admin" (and the deprecated(!) static template "plugin.feadmin.dmailsubscription" and "plugin.feadmin.fe_users" which are the old versions of these two extensions)
37  * Further the extensions "t3consultancies" and "t3references" also uses this library but contrary to the "direct_mail_subscription" and "feuser_admin" extensions which relies on external HTML templates which must be adapted these two extensions delivers the HTML template code from inside.
38  * Generally the fe_adminLib appears to be hard to use. Personally I feel turned off by all the template-file work involved and since it is very feature rich (and for that sake pretty stable!) there are lots of things that can go wrong - you feel. Therefore I like the concept used by "t3consultancies"/"t3references" since those extensions uses the library by supplying the HTML-template code automatically.
39  * Suggestions for improvement and streamlining is welcome so this powerful class could be used more and effectively.
40  *
41  * @author      Kasper Skårhøj <kasperYYYY@typo3.com>
42  * @package TYPO3
43  * @subpackage tslib
44  * @link http://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=270&tx_extrepmgm_pi1[tocEl]=396&cHash=d267c36546
45  */
46 class user_feAdmin {
47
48                 // External, static:
49         var $recInMarkersHSC = TRUE;            // If TRUE, values from the record put into markers going out into HTML will be passed through htmlspecialchars()!
50
51         var $dataArr = array();
52         var $failureMsg = array();
53         var $theTable = '';
54         var $thePid = 0;
55         var $markerArray = array();
56         var $templateCode = '';
57         var $cObj;
58
59         var $cmd;
60         var $preview;
61         var $backURL;
62         var $recUid;
63         var $failure = 0;               // is set if data did not have the required fields set.
64         var $error = '';
65         var $saved = 0;         // is set if data is saved
66         var $requiredArr;
67         var $currentArr = array();
68         var $previewLabel = '';
69         var $nc = '';           // '&no_cache=1' if you want that parameter sent.
70         var $additionalUpdateFields='';
71         var $emailMarkPrefix = 'EMAIL_TEMPLATE_';
72         var $codeLength;
73         var $cmdKey;
74         var $fileFunc='';       // Set to a basic_filefunc object
75         var $filesStoredInUploadFolders=array();                // This array will hold the names of files transferred to the uploads/* folder if any. If the records are NOT saved, these files should be deleted!! Currently this is not working!
76
77                 // Internal vars, dynamic:
78         var $unlinkTempFiles = array();                 // Is loaded with all temporary filenames used for upload which should be deleted before exit...
79
80         /**
81          * Main function. Called from TypoScript.
82          * This
83          * - initializes internal variables,
84          * - fills in the markerArray with default substitution string
85          * - saves/emails if such commands are sent
86          * - calls functions for display of the screen for editing/creation/deletion etc.
87          *
88          * @param       string          Empty string, ignore.
89          * @param       array           TypoScript properties following the USER_INT object which uses this library
90          * @return      string          HTML content
91          * @link http://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=270&tx_extrepmgm_pi1[tocEl]=396&cHash=d267c36546
92          */
93         function init($content, $conf) {
94                 $this->conf = $conf;
95
96                         // template file is fetched.
97                 $this->templateCode = $this->conf['templateContent'] ? $this->conf['templateContent'] : $this->cObj->fileResource($this->conf['templateFile']);
98
99                         // Getting the cmd var
100                 $this->cmd = (string)t3lib_div::_GP('cmd');
101                         // Getting the preview var
102                 $this->preview = (string)t3lib_div::_GP('preview');
103                         // backURL is a given URL to return to when login is performed
104                 $this->backURL = t3lib_div::_GP('backURL');
105                 if (strstr($this->backURL, '"') || strstr($this->backURL, "'") || preg_match('/(javascript|vbscript):/i', $this->backURL) || stristr($this->backURL, "fromcharcode") || strstr($this->backURL, "<") || strstr($this->backURL, ">")) {
106                         $this->backURL = '';    // Clear backURL if it seems to contain XSS code - only URLs are allowed
107                 }
108                         // Remove host from URL: Make sure that $this->backURL maps to the current site
109                 $this->backURL = preg_replace('|[A-Za-z]+://[^/]+|', '', $this->backURL);
110                         // Uid to edit:
111                 $this->recUid = t3lib_div::_GP('rU');
112                         // Authentication code:
113                 $this->authCode = t3lib_div::_GP('aC');
114                         // get table
115                 $this->theTable = $this->conf['table'];
116                         // link configuration
117                 $linkConf = is_array($this->conf['formurl.']) ? $this->conf['formurl.'] : array();
118                         // pid
119                 $this->thePid = intval($this->conf['pid']) ? intval($this->conf['pid']) : $GLOBALS['TSFE']->id;
120                         //
121                 $this->codeLength = intval($this->conf['authcodeFields.']['codeLength']) ? intval($this->conf['authcodeFields.']['codeLength']) : 8;
122
123                         // Setting the hardcoded lists of fields allowed for editing and creation.
124                 $this->fieldList=implode(',', t3lib_div::trimExplode(',', $GLOBALS['TCA'][$this->theTable]['feInterface']['fe_admin_fieldList'], 1));
125
126                         // globally substituted markers, fonts and colors.
127                 $splitMark = md5(microtime());
128                 list($this->markerArray['###GW1B###'], $this->markerArray['###GW1E###']) = explode($splitMark, $this->cObj->stdWrap($splitMark, $this->conf['wrap1.']));
129                 list($this->markerArray['###GW2B###'], $this->markerArray['###GW2E###']) = explode($splitMark, $this->cObj->stdWrap($splitMark, $this->conf['wrap2.']));
130                 $this->markerArray['###GC1###'] = $this->cObj->stdWrap($this->conf['color1'], $this->conf['color1.']);
131                 $this->markerArray['###GC2###'] = $this->cObj->stdWrap($this->conf['color2'], $this->conf['color2.']);
132                 $this->markerArray['###GC3###'] = $this->cObj->stdWrap($this->conf['color3'], $this->conf['color3.']);
133
134                 if (intval($this->conf['no_cache']) && !isset($linkConf['no_cache'])) { // needed for backwards compatibility
135                         $linkConf['no_cache'] = 1;
136                 }
137                 if (!$linkConf['parameter']) {
138                         $linkConf['parameter'] = $GLOBALS['TSFE']->id;
139                 }
140                 if (!$linkConf['additionalParams'])     {       // needed for backwards compatibility
141                         $linkConf['additionalParams'] = $this->conf['addParams'];
142                 }
143
144                 $formURL = $this->cObj->typoLink_URL($linkConf);
145                 if (!strstr($formURL, '?')) {
146                         $formURL .= '?';
147                 }
148
149                         // Initialize markerArray, setting FORM_URL and HIDDENFIELDS
150                 $this->markerArray['###FORM_URL###'] = $formURL;
151                 $this->markerArray['###FORM_URL_ENC###'] = rawurlencode($this->markerArray['###FORM_URL###']);
152                 $this->markerArray['###FORM_URL_HSC###'] = htmlspecialchars($this->markerArray['###FORM_URL###']);
153
154                 $this->markerArray['###BACK_URL###'] = $this->backURL;
155                 $this->markerArray['###BACK_URL_ENC###'] = rawurlencode($this->markerArray['###BACK_URL###']);
156                 $this->markerArray['###BACK_URL_HSC###'] = htmlspecialchars($this->markerArray['###BACK_URL###']);
157
158                 $this->markerArray['###THE_PID###'] = $this->thePid;
159                 $this->markerArray['###REC_UID###'] = $this->recUid;
160                 $this->markerArray['###AUTH_CODE###'] = $this->authCode;
161                 $this->markerArray['###THIS_ID###'] = $GLOBALS['TSFE']->id;
162                 $this->markerArray['###THIS_URL###'] = htmlspecialchars(t3lib_div::getIndpEnv('TYPO3_REQUEST_DIR'));
163                 $this->markerArray['###HIDDENFIELDS###'] =
164                         ($this->cmd ? '<input type="hidden" name="cmd" value="' . htmlspecialchars($this->cmd) . '" />' : '') .
165                         ($this->authCode ? '<input type="hidden" name="aC" value="' . htmlspecialchars($this->authCode) . '" />' : '') .
166                         ($this->backURL ? '<input type="hidden" name="backURL" value="' . htmlspecialchars($this->backURL) . '" />' : '');
167
168
169                         // Setting cmdKey which is either 'edit' or 'create'
170                 switch($this->cmd) {
171                         case 'edit':
172                                 $this->cmdKey = 'edit';
173                                 break;
174
175                         default:
176                                 $this->cmdKey = 'create';
177                                 break;
178                 }
179                         // Setting requiredArr to the fields in 'required' intersected field the total field list in order to remove invalid fields.
180                 $this->requiredArr = array_intersect(
181                         t3lib_div::trimExplode(',', $this->conf[$this->cmdKey . '.']['required'], 1),
182                         t3lib_div::trimExplode(',', $this->conf[$this->cmdKey . '.']['fields'], 1)
183                 );
184
185                         // Setting incoming data. Non-stripped
186                 $fe=t3lib_div::_GP('FE');
187                 $this->dataArr = $fe[$this->theTable];  // Incoming data.
188
189                         // Checking template file and table value
190                 if (!$this->templateCode) {
191                         $content = 'No template file found: ' . $this->conf['templateFile'];
192                         return $content;
193                 }
194
195                 if (!$this->theTable || !$this->fieldList) {
196                         $content = 'Wrong table: ' . $this->theTable;
197                         return $content;                // Not listed or editable table!
198                 }
199
200                 // *****************
201                 // If data is submitted, we take care of it here.
202                 // *******************
203                 if ($this->cmd=='delete' && !$this->preview && !t3lib_div::_GP('doNotSave')) {  // Delete record if delete command is sent + the preview flag is NOT set.
204                         $this->deleteRecord();
205                 }
206
207                         // If incoming data is seen...
208                 if (is_array($this->dataArr)) {
209                                 // Evaluation of data:
210                         $this->parseValues();
211                         $this->overrideValues();
212                         $this->evalValues();
213                         if ($this->conf['evalFunc']) {
214                                 $this->dataArr = $this->userProcess('evalFunc', $this->dataArr);
215                         }
216
217
218                                 // if not preview and no failures, then set data...
219                         if (!$this->failure && !$this->preview && !t3lib_div::_GP('doNotSave')) {       // doNotSave is a global var (eg a 'Cancel' submit button) that prevents the data from being processed
220                                 $this->save();
221                         } else {
222                                 if ($this->conf['debug'])
223                                         debug($this->failure);
224                         }
225                 } else {
226                         $this->defaultValues(); // If no incoming data, this will set the default values.
227                         $this->preview = 0;     // No preview if data is not received
228                 }
229
230                         // No preview flag if a evaluation failure has occured
231                 if ($this->failure) {
232                         $this->preview = 0;
233                 }
234
235                         // Setting preview label prefix.
236                 $this->previewLabel = $this->preview ? '_PREVIEW' : '';
237
238
239                         // *********************
240                         // DISPLAY FORMS:
241                         // ***********************
242                 if ($this->saved) {
243                                 // Clear page cache
244                         $this->clearCacheIfSet();
245
246                                 // Displaying the page here that says, the record has been saved. You're able to include the saved values by markers.
247                         switch($this->cmd) {
248                                 case 'delete':
249                                         $key='DELETE';
250                                         break;
251
252                                 case 'edit':
253                                         $key='EDIT';
254                                         break;
255
256                                 default:
257                                         $key='CREATE';
258                                         break;
259                         }
260                                 // Output message
261                         $templateCode = $this->cObj->getSubpart($this->templateCode, '###TEMPLATE_' . $key . '_SAVED###');
262                         $this->setCObjects($templateCode, $this->currentArr);
263                         $markerArray = $this->cObj->fillInMarkerArray($this->markerArray, $this->currentArr, '', TRUE, 'FIELD_', $this->recInMarkersHSC);
264                         $content = $this->cObj->substituteMarkerArray($templateCode, $markerArray);
265
266                                 // email message:
267                         $this->compileMail(
268                                 $key.'_SAVED',
269                                 array($this->currentArr),
270                                 $this->currentArr[$this->conf['email.']['field']],
271                                 $this->conf['setfixed.']
272                         );
273
274                 } elseif ($this->error) {       // If there was an error, we return the template-subpart with the error message
275                         $templateCode = $this->cObj->getSubpart($this->templateCode, $this->error);
276                         $this->setCObjects($templateCode);
277                         $content = $this->cObj->substituteMarkerArray($templateCode, $this->markerArray);
278                 } else {
279                                 // Finally, if there has been no attempt to save. That is either preview or just displaying and empty or not correctly filled form:
280                         if (!$this->cmd) {
281                                 $this->cmd=$this->conf['defaultCmd'];
282                         }
283                         if ($this->conf['debug'])
284                                 debug('Display form: ' . $this->cmd, 1);
285
286                         switch($this->cmd) {
287                                 case 'setfixed':
288                                         $content = $this->procesSetFixed();
289                                         break;
290
291                                 case 'infomail':
292                                         $content = $this->sendInfoMail();
293                                         break;
294
295                                 case 'delete':
296                                         $content = $this->displayDeleteScreen();
297                                         break;
298
299                                 case 'edit':
300                                         $content = $this->displayEditScreen();
301                                         break;
302
303                                 case 'create':
304                                         $content = $this->displayCreateScreen();
305                                         break;
306                         }
307                 }
308
309                         // Delete temp files:
310                 foreach($this->unlinkTempFiles as $tempFileName) {
311                         t3lib_div::unlink_tempfile($tempFileName);
312                 }
313
314                         // Return content:
315                 return $content;
316         }
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340         /*****************************************
341          *
342          * Data processing
343          *
344          *****************************************/
345
346         /**
347          * Performs processing on the values found in the input data array, $this->dataArr.
348          * The processing is done according to configuration found in TypoScript
349          * Examples of this could be to force a value to an integer, remove all non-alphanumeric characters, trimming a value, upper/lowercase it, or process it due to special types like files submitted etc.
350          * Called from init() if the $this->dataArr is found to be an array
351          *
352          * @return      void
353          * @see init()
354          */
355         function parseValues() {
356                 if (is_array($this->conf['parseValues.'])) {
357                         foreach ($this->conf['parseValues.'] as $theField => $theValue) {
358                                 $listOfCommands = t3lib_div::trimExplode(',', $theValue, 1);
359                                 foreach ($listOfCommands as $cmd) {
360                                         $cmdParts = preg_split('/\[|\]/', $cmd);        // Point is to enable parameters after each command enclosed in brackets [..]. These will be in position 1 in the array.
361                                         $theCmd=trim($cmdParts[0]);
362
363                                         switch($theCmd) {
364                                                 case 'int':
365                                                         $this->dataArr[$theField]=intval($this->dataArr[$theField]);
366                                                         break;
367
368                                                 case 'lower':
369                                                 case 'upper':
370                                                         $this->dataArr[$theField] = $this->cObj->caseshift($this->dataArr[$theField], $theCmd);
371                                                         break;
372
373                                                 case 'nospace':
374                                                         $this->dataArr[$theField] = str_replace(' ', '', $this->dataArr[$theField]);
375                                                         break;
376
377                                                 case 'alpha':
378                                                         $this->dataArr[$theField] = preg_replace('/[^a-zA-Z]/', '', $this->dataArr[$theField]);
379                                                         break;
380
381                                                 case 'num':
382                                                         $this->dataArr[$theField] = preg_replace('/[^0-9]/', '', $this->dataArr[$theField]);
383                                                         break;
384
385                                                 case 'alphanum':
386                                                         $this->dataArr[$theField] = preg_replace('/[^a-zA-Z0-9]/', '', $this->dataArr[$theField]);
387                                                         break;
388
389                                                 case 'alphanum_x':
390                                                         $this->dataArr[$theField] = preg_replace('/[^a-zA-Z0-9_-]/', '', $this->dataArr[$theField]);
391                                                         break;
392
393                                                 case 'trim':
394                                                         $this->dataArr[$theField] = trim($this->dataArr[$theField]);
395                                                         break;
396
397                                                 case 'random':
398                                                         $this->dataArr[$theField] = substr(md5(uniqid(microtime(), 1)), 0, intval($cmdParts[1]));
399                                                         break;
400
401                                                 case 'files':
402                                                         if ($this->cmdKey == 'create' && !t3lib_div::_GP('doNotSave')) {
403                                                                 $this->processFiles($cmdParts, $theField);
404                                                         } else
405                                                                 unset($this->dataArr[$theField]);       // Fields with files cannot be edited - only created.
406                                                         break;
407
408                                                 case 'setEmptyIfAbsent':
409                                                         if (!isset($this->dataArr[$theField])) {
410                                                                 $this->dataArr[$theField] = '';
411                                                         }
412                                                         break;
413
414                                                 case 'multiple':
415                                                         if (is_array($this->dataArr[$theField])) {
416                                                                 $this->dataArr[$theField] = implode(',', $this->dataArr[$theField]);
417                                                         }
418                                                         break;
419
420                                                 case 'checkArray':
421                                                         if (is_array($this->dataArr[$theField])) {
422                                                                 $val = 0;
423                                                                 foreach ($this->dataArr[$theField] as $kk => $vv) {
424                                                                         $kk = t3lib_utility_Math::forceIntegerInRange($kk, 0);
425                                                                         if ($kk<=30) {
426                                                                                 if ($vv) {
427                                                                                         $val |= pow(2, $kk);
428                                                                                 }
429                                                                         }
430                                                                 }
431                                                                 $this->dataArr[$theField] = $val;
432                                                         } else {
433                                                                 $this->dataArr[$theField] = 0;
434                                                         }
435                                                         break;
436
437                                                 case 'uniqueHashInt':
438                                                         $otherFields = t3lib_div::trimExplode(';', $cmdParts[1], 1);
439                                                         $hashArray = array();
440                                                         foreach ($otherFields as $fN) {
441                                                                 $vv = $this->dataArr[$fN];
442                                                                 $vv = preg_replace('/[[:space:]]/', '', $vv);
443                                                                 $vv = preg_replace('/[^[:alnum:]]/', '', $vv);
444                                                                 $vv = strtolower($vv);
445                                                                 $hashArray[] = $vv;
446                                                         }
447                                                         $this->dataArr[$theField] = hexdec(substr(md5(serialize($hashArray)), 0, 8));
448                                                         break;
449                                         }
450                                 }
451                         }
452                 }
453         }
454
455         /**
456          * Processing of files.
457          * NOTICE: for now files can be handled only on creation of records. But a more advanced feature is that PREVIEW of files is handled.
458          *
459          * @param       array           Array with cmd-parts (from parseValues()). This will for example contain information about allowed file extensions and max size of uploaded files.
460          * @param       string          The fieldname with the files.
461          * @return      void
462          * @access private
463          * @see parseValues()
464          */
465         function processFiles($cmdParts, $theField) {
466                         // First, make an array with the filename and file reference, whether the file is just uploaded or a preview
467                 $filesArr = array();
468
469                 if (is_string($this->dataArr[$theField])) {             // files from preview.
470                         $tmpArr = explode(',', $this->dataArr[$theField]);
471                         foreach ($tmpArr as $val) {
472                                 $valParts = explode('|', $val);
473                                 $filesArr[] = array (
474                                         'name' => $valParts[1],
475                                         'tmp_name' => PATH_site . 'typo3temp/' . $valParts[0]
476                                 );
477                         }
478                 } elseif (is_array($_FILES['FE'][$this->theTable][$theField]['name'])) {        // Files from upload
479                         foreach ($_FILES['FE'][$this->theTable][$theField]['name'] as $kk => $vv) {
480                                 if ($vv) {
481                                         $tmpFile = t3lib_div::upload_to_tempfile($_FILES['FE'][$this->theTable][$theField]['tmp_name'][$kk]);
482                                         if ($tmpFile) {
483                                                 $this->unlinkTempFiles[] = $tmpFile;
484                                                 $filesArr[] = array(
485                                                         'name' => $vv,
486                                                         'tmp_name' => $tmpFile
487                                                 );
488                                         }
489                                 }
490                         }
491                 } elseif (is_array($_FILES['FE']['name'][$this->theTable][$theField])) {        // Files from upload
492                         foreach ($_FILES['FE']['name'][$this->theTable][$theField] as $kk => $vv) {
493                                 if ($vv) {
494                                         $tmpFile = t3lib_div::upload_to_tempfile($_FILES['FE']['tmp_name'][$this->theTable][$theField][$kk]);
495                                         if ($tmpFile) {
496                                                 $this->unlinkTempFiles[] = $tmpFile;
497                                                 $filesArr[] = array(
498                                                         'name' => $vv,
499                                                         'tmp_name' => $tmpFile
500                                                 );
501                                         }
502                                 }
503                         }
504                 }
505
506                         // Then verify the files in that array; check existence, extension and size
507                 $this->dataArr[$theField] = '';
508                 $finalFilesArr = array();
509                 if (count($filesArr)) {
510                         $extArray = t3lib_div::trimExplode(';', strtolower($cmdParts[1]), 1);
511                         $maxSize = intval($cmdParts[3]);
512                         foreach ($filesArr as $infoArr) {
513                                 $fI = pathinfo($infoArr['name']);
514                                 if (t3lib_div::verifyFilenameAgainstDenyPattern($fI['name'])) {
515                                         if (!count($extArray) || in_array(strtolower($fI['extension']), $extArray)) {
516                                                 $tmpFile = $infoArr['tmp_name'];
517                                                 if (@is_file($tmpFile)) {
518                                                         if (!$maxSize || filesize($tmpFile) < $maxSize * 1024) {
519                                                                 $finalFilesArr[]=$infoArr;
520                                                         } elseif ($this->conf['debug']) {
521                                                                 debug('Size is beyond ' . $maxSize . ' kb (' . filesize($tmpFile) . ' bytes) and the file cannot be saved.');
522                                                         }
523                                                 } elseif ($this->conf['debug']) {
524                                                         debug('Surprisingly there was no file for ' . $vv . ' in ' . $tmpFile);
525                                                 }
526                                         } elseif ($this->conf['debug']) {
527                                                 debug('Extension "' . $fI['extension'] . '" not allowed');
528                                         }
529                                 } elseif ($this->conf['debug']) {
530                                         debug('Filename matched illegal pattern.');
531                                 }
532                         }
533                 }
534                         // Copy the files in the resulting array to the proper positions based on preview/non-preview.
535                 $fileNameList=array();
536                 foreach ($finalFilesArr as $infoArr) {
537                         if ($this->isPreview()) {               // If the form is a preview form (and data is therefore not going into the database...) do this.
538                                 $this->createFileFuncObj();
539                                 $fI = pathinfo($infoArr['name']);
540                                 $tmpFilename = $this->theTable.'_'.t3lib_div::shortmd5(uniqid($infoArr['name'])).'.'.$fI['extension'];
541                                 $theDestFile = $this->fileFunc->getUniqueName($this->fileFunc->cleanFileName($tmpFilename), PATH_site.'typo3temp/');
542                                 t3lib_div::upload_copy_move($infoArr['tmp_name'], $theDestFile);
543                                         // Setting the filename in the list
544                                 $fI2 = pathinfo($theDestFile);
545                                 $fileNameList[] = $fI2['basename'].'|'.$infoArr['name'];
546                         } else {
547                                 $this->createFileFuncObj();
548                                 $GLOBALS['TSFE']->includeTCA();
549                                 t3lib_div::loadTCA($this->theTable);
550                                 if (is_array($GLOBALS['TCA'][$this->theTable]['columns'][$theField])) {
551                                         $uploadPath = $GLOBALS['TCA'][$this->theTable]['columns'][$theField]['config']['uploadfolder'];
552                                 }
553                                 if ($uploadPath) {
554                                         $theDestFile = $this->fileFunc->getUniqueName($this->fileFunc->cleanFileName($infoArr['name']), PATH_site.$uploadPath);
555                                         t3lib_div::upload_copy_move($infoArr['tmp_name'], $theDestFile);
556                                                 // Setting the filename in the list
557                                         $fI2 = pathinfo($theDestFile);
558                                         $fileNameList[] = $fI2['basename'];
559                                         $this->filesStoredInUploadFolders[]=$theDestFile;
560                                 }
561                         }
562                                 // Implode the list of filenames
563                         $this->dataArr[$theField] = implode(',', $fileNameList);
564                 }
565         }
566
567         /**
568          * Overriding values in $this->dataArr if configured for that in TypoScript ([edit/create].overrideValues)
569          *
570          * @return      void
571          * @see init()
572          */
573         function overrideValues() {
574                 // Addition of overriding values
575                 if (is_array($this->conf[$this->cmdKey . '.']['overrideValues.'])) {
576                         foreach ($this->conf[$this->cmdKey . '.']['overrideValues.'] as $theField => $theValue) {
577                                 $this->dataArr[$theField] = $theValue;
578                         }
579                 }
580         }
581
582         /**
583          * Called if there is no input array in $this->dataArr. Then this function sets the default values configured in TypoScript
584          *
585          * @return      void
586          * @see init()
587          */
588         function defaultValues() {
589                         // Addition of default values
590                 if (is_array($this->conf[$this->cmdKey . '.']['defaultValues.'])) {
591                         foreach ($this->conf[$this->cmdKey . '.']['defaultValues.'] as $theField => $theValue) {
592                                 $this->dataArr[$theField] = $theValue;
593                         }
594                 }
595         }
596
597         /**
598          * This will evaluate the input values from $this->dataArr to see if they conforms with the requirements configured in TypoScript per field.
599          * For example this could be checking if a field contains a valid email address, a unique value, a value within a certain range etc.
600          * It will populate arrays like $this->failure and $this->failureMsg with error messages (which can later be displayed in the template). Mostly it does NOT alter $this->dataArr (such parsing of values was done by parseValues())
601          * Works based on configuration in TypoScript key [create/edit].evalValues
602          *
603          * @return      void
604          * @see init(), parseValues()
605          */
606         function evalValues() {
607                 // Check required, set failure if not ok.
608                 $tempArr = array();
609                 foreach ($this->requiredArr as $theField) {
610                         if (!trim($this->dataArr[$theField])) {
611                                 $tempArr[] = $theField;
612                         }
613                 }
614
615                 // Evaluate: This evaluates for more advanced things than 'required' does. But it returns the same error code, so you must let the required-message tell, if further evaluation has failed!
616                 $recExist=0;
617                 if (is_array($this->conf[$this->cmdKey.'.']['evalValues.'])) {
618                         switch($this->cmd) {
619                                 case 'edit':
620                                         if (isset($this->dataArr['pid'])) {                     // This may be tricked if the input has the pid-field set but the edit-field list does NOT allow the pid to be edited. Then the pid may be false.
621                                                 $recordTestPid = intval($this->dataArr['pid']);
622                                         } else {
623                                                 $tempRecArr = $GLOBALS['TSFE']->sys_page->getRawRecord($this->theTable, $this->dataArr['uid']);
624                                                 $recordTestPid = intval($tempRecArr['pid']);
625                                         }
626                                         $recExist = 1;
627                                         break;
628
629                                 default:
630                                         $recordTestPid = $this->thePid ? $this->thePid : t3lib_utility_Math::convertToPositiveInteger($this->dataArr['pid']);
631                                         break;
632                         }
633
634                         foreach ($this->conf[$this->cmdKey.'.']['evalValues.'] as $theField => $theValue) {
635                                 $listOfCommands = t3lib_div::trimExplode(',', $theValue, 1);
636                                 foreach ($listOfCommands as $cmd) {
637                                         $cmdParts = preg_split('/\[|\]/', $cmd);        // Point is to enable parameters after each command enclosed in brackets [..]. These will be in position 1 in the array.
638                                         $theCmd = trim($cmdParts[0]);
639
640                                         switch($theCmd) {
641                                                 case 'uniqueGlobal':
642                                                         if ($DBrows = $GLOBALS['TSFE']->sys_page->getRecordsByField($this->theTable, $theField, $this->dataArr[$theField], '', '', '', '1')) {
643                                                                 if (!$recExist || $DBrows[0]['uid']!= $this->dataArr['uid']) {  // Only issue an error if the record is not existing (if new...) and if the record with the false value selected was not our self.
644                                                                         $tempArr[] = $theField;
645                                                                         $this->failureMsg[$theField][] = $this->getFailure($theField, $theCmd, 'The value existed already. Enter a new value.');
646                                                                 }
647                                                         }
648                                                         break;
649
650                                                 case 'uniqueLocal':
651                                                         if ($DBrows = $GLOBALS['TSFE']->sys_page->getRecordsByField($this->theTable, $theField, $this->dataArr[$theField], 'AND pid IN (' . $recordTestPid . ')', '', '', '1')) {
652                                                                 if (!$recExist || $DBrows[0]['uid']!=$this->dataArr['uid'])     { // Only issue an error if the record is not existing (if new...) and if the record with the false value selected was not our self.
653                                                                         $tempArr[] = $theField;
654                                                                         $this->failureMsg[$theField][] = $this->getFailure($theField, $theCmd, 'The value existed already. Enter a new value.');
655                                                                 }
656                                                         }
657                                                         break;
658
659                                                 case 'twice':
660                                                         if (strcmp($this->dataArr[$theField], $this->dataArr[$theField.'_again'])) {
661                                                                 $tempArr[]=$theField;
662                                                                 $this->failureMsg[$theField][] = $this->getFailure($theField, $theCmd, 'You must enter the same value twice');
663                                                         }
664                                                         break;
665
666                                                 case 'email':
667                                                         if (!t3lib_div::validEmail($this->dataArr[$theField])) {
668                                                                 $tempArr[]=$theField;
669                                                                 $this->failureMsg[$theField][] = $this->getFailure($theField, $theCmd, 'You must enter a valid email address');
670                                                         }
671                                                         break;
672
673                                                 case 'required':
674                                                         if (!trim($this->dataArr[$theField])) {
675                                                                 $tempArr[]=$theField;
676                                                                 $this->failureMsg[$theField][] = $this->getFailure($theField, $theCmd, 'You must enter a value!');
677                                                         }
678                                                         break;
679
680                                                 case 'atLeast':
681                                                         $chars=intval($cmdParts[1]);
682                                                         if (strlen($this->dataArr[$theField]) < $chars) {
683                                                                 $tempArr[]=$theField;
684                                                                 $this->failureMsg[$theField][] = sprintf($this->getFailure($theField, $theCmd, 'You must enter at least %s characters!'), $chars);
685                                                         }
686                                                         break;
687
688                                                 case 'atMost':
689                                                         $chars = intval($cmdParts[1]);
690                                                         if (strlen($this->dataArr[$theField])>$chars) {
691                                                                 $tempArr[] = $theField;
692                                                                 $this->failureMsg[$theField][] = sprintf($this->getFailure($theField, $theCmd, 'You must enter at most %s characters!'), $chars);
693                                                         }
694                                                         break;
695
696                                                 case 'inBranch':
697                                                         $pars = explode(';', $cmdParts[1]);
698                                                         if (intval($pars[0])) {
699                                                                 $pid_list = $this->cObj->getTreeList(
700                                                                         intval($pars[0]),
701                                                                         intval($pars[1]) ? intval($pars[1]) : 999,
702                                                                         intval($pars[2])
703                                                                 );
704                                                                 if (!$pid_list || !t3lib_div::inList($pid_list, $this->dataArr[$theField])) {
705                                                                         $tempArr[] = $theField;
706                                                                         $this->failureMsg[$theField][] = sprintf($this->getFailure($theField, $theCmd, 'The value was not a valid valud from this list: %s'), $pid_list);
707                                                                 }
708                                                         }
709                                                         break;
710
711                                                 case 'unsetEmpty':
712                                                         if (!$this->dataArr[$theField]) {
713                                                                 $hash = array_flip($tempArr);
714                                                                 unset($hash[$theField]);
715                                                                 $tempArr = array_keys($hash);
716                                                                 unset($this->failureMsg[$theField]);
717                                                                 unset($this->dataArr[$theField]);       // This should prevent the field from entering the database.
718                                                         }
719                                                         break;
720                                         }
721                                 }
722                                 $this->markerArray['###EVAL_ERROR_FIELD_' . $theField . '###'] = is_array($this->failureMsg[$theField]) ? implode('<br />', $this->failureMsg[$theField]) : '';
723                         }
724                 }
725                 $this->failure=implode(',', $tempArr);   //$failure will show which fields were not OK
726         }
727
728         /**
729          * Preforms user processing of input array - triggered right after the function call to evalValues() IF TypoScript property "evalFunc" was set.
730          *
731          * @param       string          Key pointing to the property in TypoScript holding the configuration for this processing (here: "evalFunc.*"). Well: at least its safe to say that "parentObj" in this array passed to the function is a reference back to this object.
732          * @param       array           The $this->dataArr passed for processing
733          * @return      array           The processed $passVar ($this->dataArr)
734          * @see init(), evalValues()
735          */
736         function userProcess($mConfKey, $passVar) {
737                 if ($this->conf[$mConfKey]) {
738                         $funcConf = $this->conf[$mConfKey . '.'];
739                         $funcConf['parentObj'] = $this;
740                         $passVar = $GLOBALS['TSFE']->cObj->callUserFunction($this->conf[$mConfKey], $funcConf, $passVar);
741                 }
742                 return $passVar;
743         }
744
745         /**
746          * User processing of contnet
747          *
748          * @param       string          Value of the TypoScript object triggering the processing.
749          * @param       array           Properties of the TypoScript object triggering the processing. The key "parentObj" in this array is passed to the function as a reference back to this object.
750          * @param       mixed           Input variable to process
751          * @return      mixed           Processed input variable, $passVar
752          * @see userProcess(), save(), modifyDataArrForFormUpdate()
753          */
754         function userProcess_alt($confVal, $confArr, $passVar) {
755                 if ($confVal) {
756                         $funcConf = $confArr;
757                         $funcConf['parentObj'] = $this;
758                         $passVar = $GLOBALS['TSFE']->cObj->callUserFunction($confVal, $funcConf, $passVar);
759                 }
760                 return $passVar;
761         }
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784         /*****************************************
785          *
786          * Database manipulation functions
787          *
788          *****************************************/
789
790         /**
791          * Performs the saving of records, either edited or created.
792          *
793          * @return      void
794          * @see init()
795          */
796         function save() {
797                 switch($this->cmd) {
798                         case 'edit':
799                                 $theUid = $this->dataArr['uid'];
800                                         // Fetches the original record to check permissions
801                                 $origArr = $GLOBALS['TSFE']->sys_page->getRawRecord($this->theTable, $theUid);
802                                         // Must be logged in in order to edit  (OR be validated by email)
803                                 if ($this->conf['edit'] && ($GLOBALS['TSFE']->loginUser || $this->aCAuth($origArr)))    {
804                                         $newFieldList = implode(',', array_intersect(explode(',', $this->fieldList), t3lib_div::trimExplode(',', $this->conf['edit.']['fields'], 1)));
805                                         if ($this->aCAuth($origArr) || $this->cObj->DBmayFEUserEdit($this->theTable, $origArr, $GLOBALS['TSFE']->fe_user->user, $this->conf['allowedGroups'], $this->conf['fe_userEditSelf'])) {
806                                                 $this->cObj->DBgetUpdate($this->theTable, $theUid, $this->dataArr, $newFieldList, TRUE);
807                                                 $this->currentArr = $GLOBALS['TSFE']->sys_page->getRawRecord($this->theTable, $theUid);
808                                                 $this->userProcess_alt($this->conf['edit.']['userFunc_afterSave'], $this->conf['edit.']['userFunc_afterSave.'], array('rec' => $this->currentArr, 'origRec' => $origArr));
809                                                 $this->saved = 1;
810                                         } else {
811                                                 $this->error = '###TEMPLATE_NO_PERMISSIONS###';
812                                         }
813                                 }
814                         break;
815
816                         default:
817                                 if ($this->conf['create']) {
818                                         $newFieldList = implode(',', array_intersect(explode(',', $this->fieldList), t3lib_div::trimExplode(',', $this->conf['create.']['fields'], 1)));
819                                         $this->cObj->DBgetInsert($this->theTable, $this->thePid, $this->dataArr, $newFieldList, TRUE);
820                                         $newId = $GLOBALS['TYPO3_DB']->sql_insert_id();
821
822                                         if ($this->theTable=='fe_users' && $this->conf['fe_userOwnSelf']) {             // enables users, creating logins, to own them self.
823                                                 $extraList = '';
824                                                 $dataArr = array();
825
826                                                 if ($GLOBALS['TCA'][$this->theTable]['ctrl']['fe_cruser_id']) {
827                                                         $field = $GLOBALS['TCA'][$this->theTable]['ctrl']['fe_cruser_id'];
828                                                         $dataArr[$field] = $newId;
829                                                         $extraList .= ',' . $field;
830                                                 }
831
832                                                 if ($GLOBALS['TCA'][$this->theTable]['ctrl']['fe_crgroup_id']) {
833                                                         $field = $GLOBALS['TCA'][$this->theTable]['ctrl']['fe_crgroup_id'];
834                                                         list($dataArr[$field]) = explode(',', $this->dataArr['usergroup']);
835                                                         $dataArr[$field] = intval($dataArr[$field]);
836                                                         $extraList .= ',' . $field;
837                                                 }
838                                                 if (count($dataArr)) {
839                                                         $this->cObj->DBgetUpdate($this->theTable, $newId, $dataArr, $extraList, TRUE);
840                                                 }
841                                         }
842
843                                         $this->currentArr = $GLOBALS['TSFE']->sys_page->getRawRecord($this->theTable, $newId);
844                                         $this->userProcess_alt($this->conf['create.']['userFunc_afterSave'], $this->conf['create.']['userFunc_afterSave.'], array('rec' => $this->currentArr));
845                                         $this->saved = 1;
846                                 }
847                         break;
848                 }
849         }
850
851         /**
852          * Deletes the record from table/uid, $this->theTable/$this->recUid, IF the fe-user has permission to do so.
853          * If the deleted flag should just be set, then it is done so. Otherwise the record truely is deleted along with any attached files.
854          * Called from init() if "cmd" was set to "delete" (and some other conditions)
855          *
856          * @return      string          void
857          * @see init()
858          */
859         function deleteRecord() {
860                         // If deleting is enabled
861                 if ($this->conf['delete']) {
862                         $origArr = $GLOBALS['TSFE']->sys_page->getRawRecord($this->theTable, $this->recUid);
863                         if ($GLOBALS['TSFE']->loginUser || $this->aCAuth($origArr))     {       // Must be logged in OR be authenticated by the aC code in order to delete
864                                         // If the recUid selects a record.... (no check here)
865                                 if (is_array($origArr)) {
866                                                 // Display the form, if access granted.
867                                         if ($this->aCAuth($origArr) || $this->cObj->DBmayFEUserEdit($this->theTable, $origArr, $GLOBALS['TSFE']->fe_user->user, $this->conf['allowedGroups'], $this->conf['fe_userEditSelf'])) {
868                                                 if (!$GLOBALS['TCA'][$this->theTable]['ctrl']['delete']) {      // If the record is fully deleted... then remove the image (or any file) attached.
869                                                         $this->deleteFilesFromRecord($this->recUid);
870                                                 }
871                                                 $this->cObj->DBgetDelete($this->theTable, $this->recUid, TRUE);
872                                                 $this->currentArr = $origArr;
873                                                 $this->saved = 1;
874                                         } else {
875                                                 $this->error = '###TEMPLATE_NO_PERMISSIONS###';
876                                         }
877                                 }
878                         }
879                 }
880         }
881
882         /**
883          * Deletes the files attached to a record and updates the record.
884          * Table/uid is $this->theTable/$uid
885          *
886          * @param       integer         Uid number of the record to delete from $this->theTable
887          * @return      void
888          * @access private
889          * @see deleteRecord()
890          */
891         function deleteFilesFromRecord($uid) {
892                 $table = $this->theTable;
893                 $rec = $GLOBALS['TSFE']->sys_page->getRawRecord($table, $uid);
894
895                 $GLOBALS['TSFE']->includeTCA();
896                 t3lib_div::loadTCA($table);
897
898                 $iFields = array();
899                 foreach ($GLOBALS['TCA'][$table]['columns'] as $field => $conf) {
900                         if ($conf['config']['type'] == 'group' && $conf['config']['internal_type'] == 'file') {
901
902                                 $GLOBALS['TYPO3_DB']->exec_UPDATEquery($table, 'uid=' . intval($uid), array($field => ''));
903
904                                 $delFileArr = explode(',', $rec[$field]);
905                                 foreach ($delFileArr as $n) {
906                                         if ($n) {
907                                                 $fpath = $conf['config']['uploadfolder'] . '/' . $n;
908                                                 unlink($fpath);
909                                         }
910                                 }
911                         }
912                 }
913         }
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935         /*****************************************
936          *
937          * Command "display" functions
938          *
939          *****************************************/
940
941         /**
942          * Creates the preview display of delete actions
943          *
944          * @return      string          HTML content
945          * @see init()
946          */
947         function displayDeleteScreen() {
948                         // If deleting is enabled
949                 if ($this->conf['delete']) {
950                         $origArr = $GLOBALS['TSFE']->sys_page->getRawRecord($this->theTable, $this->recUid);
951                         if ($GLOBALS['TSFE']->loginUser || $this->aCAuth($origArr))     {       // Must be logged in OR be authenticated by the aC code in order to delete
952                                         // If the recUid selects a record.... (no check here)
953                                 if (is_array($origArr)) {
954                                         if ($this->aCAuth($origArr) || $this->cObj->DBmayFEUserEdit($this->theTable, $origArr, $GLOBALS['TSFE']->fe_user->user, $this->conf['allowedGroups'], $this->conf['fe_userEditSelf'])) {        // Display the form, if access granted.
955                                                 $this->markerArray['###HIDDENFIELDS###'] .= '<input type="hidden" name="rU" value="' . $this->recUid . '" />';
956                                                 $content = $this->getPlainTemplate('###TEMPLATE_DELETE_PREVIEW###', $origArr);
957                                         } else {        // Else display error, that you could not edit that particular record...
958                                                 $content = $this->getPlainTemplate('###TEMPLATE_NO_PERMISSIONS###');
959                                         }
960                                 }
961                         } else {        // Finally this is if there is no login user. This must tell that you must login. Perhaps link to a page with create-user or login information.
962                                 $content = $this->getPlainTemplate('###TEMPLATE_AUTH###');
963                         }
964                 } else {
965                         $content .= 'Delete-option is not set in TypoScript';
966                 }
967                 return $content;
968         }
969
970         /**
971          * Creates the "create" screen for records
972          *
973          * @return      string          HTML content
974          * @see init()
975          */
976         function displayCreateScreen() {
977                 if ($this->conf['create']) {
978                         $templateCode = $this->cObj->getSubpart($this->templateCode, ((!$GLOBALS['TSFE']->loginUser || $this->conf['create.']['noSpecialLoginForm']) ?
979                                         '###TEMPLATE_CREATE' . $this->previewLabel . '###' :
980                                         '###TEMPLATE_CREATE_LOGIN' . $this->previewLabel . '###')
981                         );
982                         $failure = t3lib_div::_GP('noWarnings') ? '' : $this->failure;
983                         if (!$failure)
984                                 $templateCode = $this->cObj->substituteSubpart($templateCode, '###SUB_REQUIRED_FIELDS_WARNING###', '');
985
986                         $templateCode = $this->removeRequired($templateCode, $failure);
987                         $this->setCObjects($templateCode);
988
989                         if (!is_array($this->dataArr)) {
990                                 $this->dataArr = array();
991                         }
992
993                         $markerArray = $this->cObj->fillInMarkerArray($this->markerArray, $this->dataArr, '', TRUE, 'FIELD_', $this->recInMarkersHSC);
994                         if ($this->conf['create.']['preview'] && !$this->previewLabel) {
995                                 $markerArray['###HIDDENFIELDS###'] .= '<input type="hidden" name="preview" value="1" />';
996                         }
997
998                         $content = $this->cObj->substituteMarkerArray($templateCode, $markerArray);
999                         $content .= $this->cObj->getUpdateJS($this->modifyDataArrForFormUpdate($this->dataArr), $this->theTable . '_form', 'FE[' . $this->theTable . ']', $this->fieldList . $this->additionalUpdateFields);
1000                 }
1001                 return $content;
1002         }
1003
1004         /**
1005          * Creates the edit-screen for records
1006          *
1007          * @return      string          HTML content
1008          * @see init()
1009          */
1010         function displayEditScreen() {
1011                         // If editing is enabled
1012                 if ($this->conf['edit']) {
1013                         $origArr = $GLOBALS['TSFE']->sys_page->getRawRecord($this->theTable, $this->dataArr['uid'] ? $this->dataArr['uid'] : $this->recUid);
1014
1015                                 // Must be logged in OR be authenticated by the aC code in order to edit
1016                         if ($GLOBALS['TSFE']->loginUser || $this->aCAuth($origArr)) {
1017                                         // If the recUid selects a record.... (no check here)
1018                                 if (is_array($origArr)) {
1019                                         if ($this->aCAuth($origArr) || $this->cObj->DBmayFEUserEdit($this->theTable, $origArr, $GLOBALS['TSFE']->fe_user->user, $this->conf['allowedGroups'], $this->conf['fe_userEditSelf'])) {        // Display the form, if access granted.
1020                                                 $content=$this->displayEditForm($origArr);
1021                                         } else {        // Else display error, that you could not edit that particular record...
1022                                                 $content = $this->getPlainTemplate('###TEMPLATE_NO_PERMISSIONS###');
1023                                         }
1024                                 } elseif ($GLOBALS['TSFE']->loginUser) {        // If the recUid did not select a record, we display a menu of records. (eg. if no recUid)
1025                                         $lockPid = $this->conf['edit.']['menuLockPid'] ? ' AND pid='.intval($this->thePid) : '';
1026
1027                                         $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', $this->theTable, '1 ' . $lockPid.$this->cObj->DBmayFEUserEditSelect($this->theTable, $GLOBALS['TSFE']->fe_user->user, $this->conf['allowedGroups'], $this->conf['fe_userEditSelf']) . $GLOBALS['TSFE']->sys_page->deleteClause($this->theTable));
1028
1029                                         if ($GLOBALS['TYPO3_DB']->sql_num_rows($res))   {       // If there are menu-items ...
1030                                                 $templateCode = $this->getPlainTemplate('###TEMPLATE_EDITMENU###');
1031                                                 $out='';
1032                                                 $itemCode = $this->cObj->getSubpart($templateCode, '###ITEM###');
1033                                                 while($menuRow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
1034                                                         $markerArray = $this->cObj->fillInMarkerArray(array(), $menuRow, '', TRUE, 'FIELD_', $this->recInMarkersHSC);
1035                                                         $markerArray = $this->setCObjects($itemCode, $menuRow, $markerArray, 'ITEM_');
1036                                                         $out.= $this->cObj->substituteMarkerArray($itemCode, $markerArray);
1037                                                 }
1038                                                 $content=$this->cObj->substituteSubpart($templateCode, '###ALLITEMS###', $out);
1039                                         } else {        // If there are not menu items....
1040                                                 $content = $this->getPlainTemplate('###TEMPLATE_EDITMENU_NOITEMS###');
1041                                         }
1042                                 } else {
1043                                         $content = $this->getPlainTemplate('###TEMPLATE_AUTH###');
1044                                 }
1045                         } else {        // Finally this is if there is no login user. This must tell that you must login. Perhaps link to a page with create-user or login information.
1046                                 $content = $this->getPlainTemplate('###TEMPLATE_AUTH###');
1047                         }
1048                 } else {
1049                         $content .= 'Edit-option is not set in TypoScript';
1050                 }
1051                 return $content;
1052         }
1053
1054         /**
1055          * Subfunction for displayEditScreen(); Takes a record and creates an edit form based on the template code for it.
1056          * This function is called if the user is editing a record and permitted to do so. Checked in displayEditScreen()
1057          *
1058          * @param       array           The array with the record to edit
1059          * @return      string          HTML content
1060          * @access private
1061          * @see displayEditScreen()
1062          */
1063         function displayEditForm($origArr) {
1064                 $currentArr = is_array($this->dataArr) ? $this->dataArr + $origArr : $origArr;
1065
1066                 if ($this->conf['debug'])
1067                         debug('displayEditForm(): ' . '###TEMPLATE_EDIT' . $this->previewLabel . '###', 1);
1068
1069                 $templateCode = $this->cObj->getSubpart($this->templateCode, '###TEMPLATE_EDIT' . $this->previewLabel . '###');
1070                 $failure = t3lib_div::_GP('noWarnings') ? '' : $this->failure;
1071                 if (!$failure) {
1072                         $templateCode = $this->cObj->substituteSubpart($templateCode, '###SUB_REQUIRED_FIELDS_WARNING###', '');
1073                 }
1074
1075                 $templateCode = $this->removeRequired($templateCode, $failure);
1076
1077                 $this->setCObjects($templateCode, $currentArr);
1078
1079                 $markerArray = $this->cObj->fillInMarkerArray($this->markerArray, $currentArr, '', TRUE, 'FIELD_', $this->recInMarkersHSC);
1080
1081                 $markerArray['###HIDDENFIELDS###'].= '<input type="hidden" name="FE[' . $this->theTable . '][uid]" value="' . $currentArr['uid'] . '" />';
1082                 if ($this->conf['edit.']['preview'] && !$this->previewLabel) {
1083                         $markerArray['###HIDDENFIELDS###'] .= '<input type="hidden" name="preview" value="1" />';
1084                 }
1085                 $content = $this->cObj->substituteMarkerArray($templateCode, $markerArray);
1086                 $content .= $this->cObj->getUpdateJS($this->modifyDataArrForFormUpdate($currentArr), $this->theTable . '_form', 'FE[' . $this->theTable . ']', $this->fieldList . $this->additionalUpdateFields);
1087
1088                 return $content;
1089         }
1090
1091         /**
1092          * Processes socalled "setfixed" commands. These are commands setting a certain field in a certain record to a certain value. Like a link you can click in an email which will unhide a record to enable something. Or likewise a link which can delete a record by a single click.
1093          * The idea is that only some allowed actions like this is allowed depending on the configured TypoScript.
1094          *
1095          * @return      string          HTML content displaying the status of the action
1096          */
1097         function procesSetFixed() {
1098                 if ($this->conf['setfixed']) {
1099                         $theUid = intval($this->recUid);
1100                         $origArr = $GLOBALS['TSFE']->sys_page->getRawRecord($this->theTable, $theUid);
1101                         $fD = t3lib_div::_GP('fD');
1102                         $sFK = t3lib_div::_GP('sFK');
1103
1104                         $fieldArr=array();
1105                         if (is_array($fD) || $sFK == 'DELETE') {
1106                                 if (is_array($fD)) {
1107                                         foreach ($fD as $field => $value) {
1108                                                 $origArr[$field]=$value;
1109                                                 $fieldArr[] = $field;
1110                                         }
1111                                 }
1112                                 $theCode = $this->setfixedHash($origArr, $origArr['_FIELDLIST']);
1113                                 if (!strcmp($this->authCode, $theCode)) {
1114                                         if ($sFK == 'DELETE') {
1115                                                 $this->cObj->DBgetDelete($this->theTable, $theUid, TRUE);
1116                                         } else {
1117                                                 $newFieldList = implode(',', array_intersect(t3lib_div::trimExplode(',', $this->fieldList), t3lib_div::trimExplode(',', implode($fieldArr, ','), 1)));
1118                                                 $this->cObj->DBgetUpdate($this->theTable, $theUid, $fD, $newFieldList, TRUE);
1119                                                 $this->currentArr = $GLOBALS['TSFE']->sys_page->getRawRecord($this->theTable, $theUid);
1120                                                 $this->userProcess_alt(
1121                                                         $this->conf['setfixed.']['userFunc_afterSave'],
1122                                                         $this->conf['setfixed.']['userFunc_afterSave.'],
1123                                                         array('rec' => $this->currentArr, 'origRec' => $origArr)
1124                                                 );
1125                                         }
1126
1127                                                 // Outputting template
1128                                         $this->markerArray = $this->cObj->fillInMarkerArray($this->markerArray, $origArr, '', TRUE, 'FIELD_', $this->recInMarkersHSC);
1129                                         $content = $this->getPlainTemplate('###TEMPLATE_SETFIXED_OK_' . $sFK . '###');
1130                                         if (!$content) {
1131                                                 $content = $this->getPlainTemplate('###TEMPLATE_SETFIXED_OK###');
1132                                         }
1133
1134                                                 // Compiling email
1135                                         $this->compileMail(
1136                                                 'SETFIXED_' . $sFK,
1137                                                 array($origArr),
1138                                                 $origArr[$this->conf['email.']['field']],
1139                                                 $this->conf['setfixed.']
1140                                         );
1141
1142                                                 // Clearing cache if set:
1143                                         $this->clearCacheIfSet();
1144                                 } else $content = $this->getPlainTemplate('###TEMPLATE_SETFIXED_FAILED###');
1145                         } else $content = $this->getPlainTemplate('###TEMPLATE_SETFIXED_FAILED###');
1146                 }
1147                 return $content;
1148         }
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172         /*****************************************
1173          *
1174          * Template processing functions
1175          *
1176          *****************************************/
1177
1178
1179
1180         /**
1181          * Remove required parts from template code string
1182          *       Works like this:
1183          *               - You insert subparts like this ###SUB_REQUIRED_FIELD_'.$theField.'### in the template that tells what is required for the field, if it's not correct filled in.
1184          *               - These subparts are all removed, except if the field is listed in $failure string!
1185          *
1186          *              Only fields that are found in $this->requiredArr is processed.
1187          *
1188          * @param       string          The template HTML code
1189          * @param       string          Comma list of fields which has errors (and therefore should not be removed)
1190          * @return      string          The processed template HTML code
1191          */
1192         function removeRequired($templateCode, $failure) {
1193                 foreach ($this->requiredArr as $theField) {
1194                         if (!t3lib_div::inList($failure, $theField)) {
1195                                 $templateCode = $this->cObj->substituteSubpart($templateCode, '###SUB_REQUIRED_FIELD_'.$theField.'###', '');
1196                         }
1197                 }
1198                 return $templateCode;
1199         }
1200
1201         /**
1202          * Returns template subpart HTML code for the key given
1203          *
1204          * @param       string          Subpart marker to return subpart for.
1205          * @param       array           Optional data record array. If set, then all fields herein will also be substituted if found as markers in the template
1206          * @return      string          The subpart with all markers found in current $this->markerArray substituted.
1207          * @see tslib_cObj::fillInMarkerArray()
1208          */
1209         function getPlainTemplate($key, $r = '') {
1210                 if ($this->conf['debug'])
1211                         debug('getPlainTemplate(): ' . $key, 1);
1212
1213                 $templateCode = $this->cObj->getSubpart($this->templateCode, $key);
1214                 $this->setCObjects($templateCode, is_array($r) ? $r : array());
1215                 return  $this->cObj->substituteMarkerArray(
1216                                 $templateCode,
1217                                 is_array($r) ? $this->cObj->fillInMarkerArray($this->markerArray, $r, '', TRUE, 'FIELD_', $this->recInMarkersHSC) : $this->markerArray
1218                 );
1219         }
1220
1221         /**
1222          * Modifies input array for passing on to tslib_cObj::getUpdateJS() which produces some JavaScript for form evaluation or the like.
1223          *
1224          * @param       array           The data array
1225          * @return      array           The processed input array
1226          * @see displayCreateScreen(), displayEditForm(), tslib_cObj::getUpdateJS()
1227          */
1228         function modifyDataArrForFormUpdate($inputArr) {
1229                 if (is_array($this->conf[$this->cmdKey . '.']['evalValues.'])) {
1230                         foreach ($this->conf[$this->cmdKey . '.']['evalValues.'] as $theField => $theValue) {
1231                                 $listOfCommands = t3lib_div::trimExplode(',', $theValue, 1);
1232                                 foreach ($listOfCommands as $cmd) {
1233                                         $cmdParts = preg_split('/\[|\]/', $cmd);        // Point is to enable parameters after each command enclosed in brackets [..]. These will be in position 1 in the array.
1234                                         $theCmd = trim($cmdParts[0]);
1235
1236                                         switch($theCmd) {
1237                                                 case 'twice':
1238                                                         if (isset($inputArr[$theField])) {
1239                                                                 if (!isset($inputArr[$theField.'_again'])) {
1240                                                                         $inputArr[$theField . '_again'] = $inputArr[$theField];
1241                                                                 }
1242                                                                 $this->additionalUpdateFields .= ',' . $theField . '_again';
1243                                                         }
1244                                                 break;
1245                                         }
1246                                 }
1247                         }
1248                 }
1249                 if (is_array($this->conf['parseValues.'])) {
1250                         foreach ($this->conf['parseValues.'] as $theField => $theValue) {
1251                                 $listOfCommands = t3lib_div::trimExplode(',', $theValue, 1);
1252                                 foreach ($listOfCommands as $cmd) {
1253                                         $cmdParts = preg_split('/\[|\]/', $cmd);        // Point is to enable parameters after each command enclosed in brackets [..]. These will be in position 1 in the array.
1254                                         $theCmd = trim($cmdParts[0]);
1255                                         switch($theCmd) {
1256                                                 case 'multiple':
1257                                                         if (isset($inputArr[$theField]) && !$this->isPreview()) {
1258                                                                 $inputArr[$theField] = explode(',', $inputArr[$theField]);
1259                                                         }
1260                                                 break;
1261
1262                                                 case 'checkArray':
1263                                                         if ($inputArr[$theField] && !$this->isPreview()) {
1264                                                                 for($a=0; $a <= 30; $a++) {
1265                                                                         if ($inputArr[$theField] & pow(2, $a)) {
1266                                                                                 $alt_theField = $theField . '][' . $a;
1267                                                                                 $inputArr[$alt_theField] = 1;
1268                                                                                 $this->additionalUpdateFields .= ',' . $alt_theField;
1269                                                                         }
1270                                                                 }
1271                                                         }
1272                                                 break;
1273                                         }
1274                                 }
1275                         }
1276                 }
1277
1278
1279                 $inputArr = $this->userProcess_alt(
1280                         $this->conf['userFunc_updateArray'],
1281                         $this->conf['userFunc_updateArray.'],
1282                         $inputArr
1283                 );
1284
1285                 return $this->escapeHTML($inputArr);
1286         }
1287
1288         /**
1289          * Will render TypoScript cObjects (configured in $this->conf['cObjects.']) and add their content to keys in a markerArray, either the array passed to the function or the internal one ($this->markerArray) if the input $markerArray is not set.
1290          *
1291          * @param       string          The current template code string. Is used to check if the marker string is found and if not, the content object is not rendered!
1292          * @param       array           An alternative data record array (if empty then $this->dataArr is used)
1293          * @param       mixed           An alternative markerArray to fill in (instead of $this->markerArray). If you want to set the cobjects in the internal $this->markerArray, then just set this to non-array value.
1294          * @param       string          Optional prefix to set for the marker strings.
1295          * @return      array           The processed $markerArray (if given).
1296          */
1297         function setCObjects($templateCode, $currentArr = array(), $markerArray = '', $specialPrefix = '') {
1298                 if (is_array($this->conf['cObjects.'])) {
1299
1300                         foreach ($this->conf['cObjects.'] as $theKey => $theConf) {
1301                                 if (!strstr($theKey, '.')) {
1302                                         if (strstr($templateCode, '###' . $specialPrefix . 'CE_' . $theKey . '###')) {
1303                                                 $cObjCode = $this->cObj->cObjGetSingle($this->conf['cObjects.'][$theKey], $this->conf['cObjects.'][$theKey . '.'], 'cObjects.' . $theKey);
1304
1305                                                 if (!is_array($markerArray)) {
1306                                                         $this->markerArray['###' . $specialPrefix . 'CE_' . $theKey . '###'] = $cObjCode;
1307                                                 } else {
1308                                                         $markerArray['###' . $specialPrefix . 'CE_' . $theKey . '###'] = $cObjCode;
1309                                                 }
1310                                         }
1311                                         if (strstr($templateCode, '###' . $specialPrefix . 'PCE_' . $theKey . '###')) {
1312                                                 $local_cObj = t3lib_div::makeInstance('tslib_cObj');
1313                                                 $local_cObj->start(count($currentArr) ? $currentArr : $this->dataArr, $this->theTable);
1314                                                 $cObjCode = $local_cObj->cObjGetSingle($this->conf['cObjects.'][$theKey], $this->conf['cObjects.'][$theKey . '.'], 'cObjects.' . $theKey);
1315
1316                                                 if (!is_array($markerArray)) {
1317                                                         $this->markerArray['###' . $specialPrefix . 'PCE_' . $theKey . '###'] = $cObjCode;
1318                                                 } else {
1319                                                         $markerArray['###' . $specialPrefix . 'PCE_' . $theKey . '###'] = $cObjCode;
1320                                                 }
1321                                         }
1322                                 }
1323                         }
1324                 }
1325                 return $markerArray;
1326         }
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346         /*****************************************
1347          *
1348          * Emailing
1349          *
1350          *****************************************/
1351
1352         /**
1353          * Sends info mail to user
1354          *
1355          * @return      string          HTML content message
1356          * @see init(),compileMail(), sendMail()
1357          */
1358         function sendInfoMail() {
1359                 if ($this->conf['infomail'] && $this->conf['email.']['field']) {
1360                         $fetch = t3lib_div::_GP('fetch');
1361                         if ($fetch) {
1362                                         // Getting infomail config.
1363                                 $key = trim(t3lib_div::_GP('key'));
1364                                 if (is_array($this->conf['infomail.'][$key.'.'])) {
1365                                         $config = $this->conf['infomail.'][$key.'.'];
1366                                 } else {
1367                                         $config = $this->conf['infomail.']['default.'];
1368                                 }
1369                                 $pidLock = '';
1370                                 if (!$config['dontLockPid']) {
1371                                         $pidLock = 'AND pid IN (' . $this->thePid . ') ';
1372                                 }
1373
1374                                         // Getting records
1375                                 if (t3lib_utility_Math::canBeInterpretedAsInteger($fetch)) {
1376                                         $DBrows = $GLOBALS['TSFE']->sys_page->getRecordsByField($this->theTable, 'uid', $fetch, $pidLock, '', '', '1');
1377                                 } elseif ($fetch) {     // $this->conf['email.']['field'] must be a valid field in the table!
1378                                         $DBrows = $GLOBALS['TSFE']->sys_page->getRecordsByField($this->theTable, $this->conf['email.']['field'], $fetch, $pidLock, '', '', '100');
1379                                 }
1380
1381                                         // Processing records
1382                                 if (is_array($DBrows)) {
1383                                         $recipient = $DBrows[0][$this->conf['email.']['field']];
1384                                         $this->compileMail($config['label'], $DBrows, $recipient, $this->conf['setfixed.']);
1385                                 } elseif (t3lib_div::validEmail($fetch)) {
1386                                         $this->sendMail($fetch, '', trim($this->cObj->getSubpart($this->templateCode, '###' . $this->emailMarkPrefix . 'NORECORD###')));
1387                                 }
1388
1389                                 $content = $this->getPlainTemplate('###TEMPLATE_INFOMAIL_SENT###');
1390                         } else {
1391                                 $content = $this->getPlainTemplate('###TEMPLATE_INFOMAIL###');
1392                         }
1393                 } else $content='Error: infomail option is not available or emailField is not setup in TypoScript';
1394                 return $content;
1395         }
1396
1397         /**
1398          * Compiles and sends a mail based on input values + template parts. Looks for a normal and an "-admin" template and may send both kinds of emails. See documentation in TSref.
1399          *
1400          * @param       string          A key which together with $this->emailMarkPrefix will identify the part from the template code to use for the email.
1401          * @param       array           An array of records which fields are substituted in the templates
1402          * @param       mixed           Mail recipient. If string then its supposed to be an email address. If integer then its a uid of a fe_users record which is looked up and the email address from here is used for sending the mail.
1403          * @param       array           Additional fields to set in the markerArray used in the substitution process
1404          * @return      void
1405          */
1406         function compileMail($key, $DBrows, $recipient, $setFixedConfig = array()) {
1407                 $GLOBALS['TT']->push('compileMail');
1408                 $mailContent = '';
1409                 $key = $this->emailMarkPrefix.$key;
1410
1411                 $userContent['all'] = trim($this->cObj->getSubpart($this->templateCode, '###'.$key.'###'));
1412                 $adminContent['all'] = trim($this->cObj->getSubpart($this->templateCode, '###'.$key.'-ADMIN###'));
1413                 $userContent['rec'] = $this->cObj->getSubpart($userContent['all'], '###SUB_RECORD###');
1414                 $adminContent['rec'] = $this->cObj->getSubpart($adminContent['all'], '###SUB_RECORD###');
1415
1416                 foreach ($DBrows as $r) {
1417                         $markerArray = $this->cObj->fillInMarkerArray($this->markerArray, $r, '', 0);
1418                         $markerArray = $this->setCObjects($userContent['rec'].$adminContent['rec'], $r, $markerArray, 'ITEM_');
1419                         $markerArray['###SYS_AUTHCODE###'] = $this->authCode($r);
1420                         $markerArray = $this->setfixed($markerArray, $setFixedConfig, $r);
1421
1422                         if ($userContent['rec'])
1423                                 $userContent['accum'] .= $this->cObj->substituteMarkerArray($userContent['rec'], $markerArray);
1424                         if ($adminContent['rec'])
1425                                 $adminContent['accum'] .= $this->cObj->substituteMarkerArray($adminContent['rec'], $markerArray);
1426                 }
1427
1428                 if ($userContent['all'])        $userContent['final'] .=$this->cObj->substituteSubpart($userContent['all'], '###SUB_RECORD###', $userContent['accum']);
1429                 if ($adminContent['all'])       $adminContent['final'].=$this->cObj->substituteSubpart($adminContent['all'], '###SUB_RECORD###', $adminContent['accum']);
1430
1431                 if (t3lib_utility_Math::canBeInterpretedAsInteger($recipient)) {
1432                         $fe_userRec = $GLOBALS['TSFE']->sys_page->getRawRecord('fe_users', $recipient);
1433                         $recipient=$fe_userRec['email'];
1434                 }
1435
1436                 $GLOBALS['TT']->setTSlogMessage('Template key: ###' . $key . '###, userContentLength: ' . strlen($userContent['final']) . ', adminContentLength: ' . strlen($adminContent['final']));
1437
1438                 $this->sendMail($recipient, $this->conf['email.']['admin'], $userContent['final'], $adminContent['final']);
1439                 $GLOBALS['TT']->pull();
1440         }
1441
1442         /**
1443          * Actually sends the requested mails (through $this->cObj->sendNotifyEmail or through $this->sendHTMLMail).
1444          * As of TYPO3 v4.3 with autoloader, a check for $GLOBALS['TSFE']->config['config']['incT3Lib_htmlmail'] has been included for backwards compatibility.
1445          *
1446          * @param       string          Recipient email address (or list)
1447          * @param       string          Possible "admin" email address. Will enable sending of admin emails if also $adminContent is provided
1448          * @param       string          Content for the regular email to user
1449          * @param       string          Content for the admin email to administrator
1450          * @return      void
1451          * @access private
1452          * @see compileMail(), sendInfoMail()
1453          */
1454         function sendMail($recipient, $admin, $content = '', $adminContent = '') {
1455                         // Admin mail:
1456                 if ($admin && $adminContent) {
1457                         if (!$this->isHTMLContent($adminContent) || !$GLOBALS['TSFE']->config['config']['incT3Lib_htmlmail']) {
1458                                 $admMail = $this->cObj->sendNotifyEmail(
1459                                                 strip_tags($adminContent),
1460                                                 $admin,
1461                                                 '',
1462                                                 $this->conf['email.']['from'],
1463                                                 $this->conf['email.']['fromName'],
1464                                                 $recipient
1465                                 );
1466                         } else {
1467                                 $this->sendHTMLMail(
1468                                                 $adminContent,
1469                                                 $admin,
1470                                                 '',
1471                                                 $this->conf['email.']['from'],
1472                                                 $this->conf['email.']['fromName'],
1473                                                 $recipient
1474                                 );
1475                         }
1476                 }
1477
1478                         // user mail:
1479                 if (!$this->isHTMLContent($content) || !$GLOBALS['TSFE']->config['config']['incT3Lib_htmlmail']) {
1480                         $this->cObj->sendNotifyEmail(
1481                                 strip_tags($content),
1482                                 $recipient,
1483                                 '',
1484                                 $this->conf['email.']['from'],
1485                                 $this->conf['email.']['fromName']
1486                         );
1487                 } else {
1488                         $this->sendHTMLMail($content,
1489                                 $recipient,
1490                                 '',
1491                                 $this->conf['email.']['from'],
1492                                 $this->conf['email.']['fromName']
1493                         );
1494                 }
1495         }
1496
1497         /**
1498          * Detects if content is HTML (looking for <html> tag as first and last in string)
1499          *
1500          * @param       string          Content string to test
1501          * @return      boolean         Returns TRUE if the content begins and ends with <html></html>-tags
1502          */
1503         function isHTMLContent($c) {
1504                 $c = trim($c);
1505                 $first = strtolower(substr($c, 0, 6));
1506                 $last = strtolower(substr($c, -7));
1507                 if ($first . $last == '<html></html>')
1508                         return 1;
1509         }
1510
1511         /**
1512          * Sending HTML email, using same parameters as tslib_cObj::sendNotifyEmail()
1513          *
1514          * @param       string          The message content. If blank, no email is sent.
1515          * @param       string          Comma list of recipient email addresses
1516          * @param       string          IGNORE this parameter
1517          * @param       string          "From" email address
1518          * @param       string          Optional "From" name
1519          * @param       string          Optional "Reply-To" header email address.
1520          * @return      void
1521          * @access private
1522          * @see sendMail(), tslib_cObj::sendNotifyEmail()
1523          */
1524         function sendHTMLMail($content, $recipient, $dummy, $fromEmail, $fromName, $replyTo = '') {
1525                 if (trim($recipient) && trim($content)) {
1526                         $parts = spliti('<title>|</title>', $content, 3);
1527                         $subject = trim($parts[1]) ? trim($parts[1]) : 'TYPO3 FE Admin message';
1528
1529                         $Typo3_htmlmail = t3lib_div::makeInstance('t3lib_htmlmail');
1530                         $Typo3_htmlmail->start();
1531                         $Typo3_htmlmail->useBase64();
1532
1533                         $Typo3_htmlmail->subject = $subject;
1534                         $Typo3_htmlmail->from_email = $fromEmail;
1535                         $Typo3_htmlmail->from_name = $fromName;
1536                         $Typo3_htmlmail->replyto_email = $replyTo ? $replyTo : $fromEmail;
1537                         $Typo3_htmlmail->replyto_name = $replyTo ? '' : $fromName;
1538                         $Typo3_htmlmail->organisation = '';
1539                         $Typo3_htmlmail->priority = 3;
1540
1541                                 // HTML
1542                         $Typo3_htmlmail->theParts['html']['content'] = $content; // Fetches the content of the page
1543                         $Typo3_htmlmail->theParts['html']['path'] = '';
1544                         $Typo3_htmlmail->extractMediaLinks();
1545                         $Typo3_htmlmail->extractHyperLinks();
1546                         $Typo3_htmlmail->fetchHTMLMedia();
1547                         $Typo3_htmlmail->substMediaNamesInHTML(0); // 0 = relative
1548                         $Typo3_htmlmail->substHREFsInHTML();
1549                         $Typo3_htmlmail->setHTML($Typo3_htmlmail->encodeMsg($Typo3_htmlmail->theParts['html']['content']));
1550
1551                                 // PLAIN
1552                         $Typo3_htmlmail->addPlain('');
1553
1554                                 // SET Headers and Content
1555                         $Typo3_htmlmail->setHeaders();
1556                         $Typo3_htmlmail->setContent();
1557                         $Typo3_htmlmail->setRecipient($recipient);
1558
1559                         $Typo3_htmlmail->sendtheMail();
1560                 }
1561         }
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586         /*****************************************
1587          *
1588          * Various helper functions
1589          *
1590          *****************************************/
1591
1592         /**
1593          * Returns TRUE if authentication is OK based on the "aC" code which is a GET parameter set from outside with a hash string which must match some internal hash string.
1594          * This allows to authenticate editing without having a fe_users login
1595          * Uses $this->authCode which is set in init() by "t3lib_div::_GP('aC');"
1596          *
1597          * @param       array           The data array for which to evaluate authentication
1598          * @return      boolean         TRUE if authenticated OK
1599          * @see authCode(), init()
1600          */
1601         function aCAuth($r) {
1602                 if ($this->authCode && !strcmp($this->authCode, $this->authCode($r))) {
1603                         return TRUE;
1604                 }
1605         }
1606
1607         /**
1608          * Creating authentication hash string based on input record and the fields listed in TypoScript property "authcodeFields"
1609          *
1610          * @param       array           The data record
1611          * @param       string          Additional string to include in the hash
1612          * @return      string          Hash string of $this->codeLength (if TypoScript "authcodeFields" was set)
1613          * @see aCAuth()
1614          */
1615         function authCode($r, $extra = '') {
1616                 $l = $this->codeLength;
1617                 if ($this->conf['authcodeFields']) {
1618                         $fieldArr = t3lib_div::trimExplode(',', $this->conf['authcodeFields'], 1);
1619                         $value = '';
1620                         foreach ($fieldArr as $field) {
1621                                 $value .= $r[$field] . '|';
1622                         }
1623                         $value .= $extra . '|' . $this->conf['authcodeFields.']['addKey'];
1624                         if ($this->conf['authcodeFields.']['addDate']) {
1625                                 $value .= '|' . date($this->conf['authcodeFields.']['addDate']);
1626                         }
1627                         $value .= $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'];
1628                         return substr(md5($value), 0, $l);
1629                 }
1630         }
1631
1632         /**
1633          * Adding keys to the marker array with "setfixed" GET parameters
1634          *
1635          * @param       array           Marker-array to modify/add a key to.
1636          * @param       array           TypoScript properties configuring "setfixed" for the plugin. Basically this is $this->conf['setfixed.'] passed along.
1637          * @param       array           The data record
1638          * @return      array           Processed $markerArray
1639          * @see compileMail()
1640          */
1641         function setfixed($markerArray, $setfixed, $r) {
1642                 if (is_array($setfixed)) {
1643                         foreach ($setfixed as $theKey => $data) {
1644                                 if (!strcmp($theKey, 'DELETE')) {
1645                                         $recCopy = $r;
1646                                         $string = '&cmd=setfixed&sFK=' . rawurlencode($theKey) . '&rU=' . $r['uid'];
1647                                         $string .= '&aC=' . $this->setfixedHash($recCopy, $data['_FIELDLIST']);
1648                                         $markerArray['###SYS_SETFIXED_DELETE###'] = $string;
1649                                         $markerArray['###SYS_SETFIXED_HSC_DELETE###'] = htmlspecialchars($string);
1650                                 } elseif (strstr($theKey, '.')) {
1651                                         $theKey = substr($theKey, 0, -1);
1652                                         if (is_array($data)) {
1653                                                 $recCopy = $r;
1654                                                 $string = '&cmd=setfixed&sFK=' . rawurlencode($theKey) . '&rU=' . $r['uid'];
1655                                                 foreach ($data as $fieldName => $fieldValue) {
1656                                                         $string .= '&fD%5B' . $fieldName . '%5D=' . rawurlencode($fieldValue);
1657                                                         $recCopy[$fieldName] = $fieldValue;
1658                                                 }
1659                                                 $string .= '&aC=' . $this->setfixedHash($recCopy, $data['_FIELDLIST']);
1660                                                 $markerArray['###SYS_SETFIXED_' . $theKey . '###'] = $string;
1661                                                 $markerArray['###SYS_SETFIXED_HSC_' . $theKey . '###'] = htmlspecialchars($string);
1662                                         }
1663                                 }
1664                         }
1665                 }
1666                 return $markerArray;
1667         }
1668
1669         /**
1670          * Creating hash string for setFixed. Much similar to authCode()
1671          *
1672          * @param       array           The data record
1673          * @param       string          List of fields to use
1674          * @return      string          Hash string of $this->codeLength (if TypoScript "authcodeFields" was set)
1675          * @see setfixed(),authCode()
1676          */
1677         function setfixedHash($recCopy, $fields = '') {
1678                 if ($fields) {
1679                         $fieldArr = t3lib_div::trimExplode(',', $fields, 1);
1680                         foreach ($fieldArr as $k => $v) {
1681                                 $recCopy_temp[$k] = $recCopy[$v];
1682                         }
1683                 } else {
1684                         $recCopy_temp = $recCopy;
1685                 }
1686                 $encStr = implode('|', $recCopy_temp) . '|' . $this->conf['authcodeFields.']['addKey'] . '|' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'];
1687                 $hash = substr(md5($encStr), 0, $this->codeLength);
1688                 return $hash;
1689         }
1690
1691         /**
1692          * Returns TRUE if preview display is on.
1693          *
1694          * @return      boolean
1695          */
1696         function isPreview() {
1697                 return ($this->conf[$this->cmdKey . '.']['preview'] && $this->preview);
1698         }
1699
1700         /**
1701          * Creates an instance of class "t3lib_basicFileFunctions" in $this->fileFunc (if not already done)
1702          *
1703          * @return      void
1704          */
1705         function createFileFuncObj() {
1706                 if (!$this->fileFunc) {
1707                         $this->fileFunc = t3lib_div::makeInstance('t3lib_basicFileFunctions');
1708                 }
1709         }
1710
1711         /**
1712          * If TypoScript property clearCacheOfPages is set then all page ids in this value will have their cache cleared
1713          *
1714          * @return      void
1715          */
1716         function clearCacheIfSet() {
1717                 if ($this->conf['clearCacheOfPages']) {
1718                         $cc_pidList = $GLOBALS['TYPO3_DB']->cleanIntList($this->conf['clearCacheOfPages']);
1719                         $GLOBALS['TSFE']->clearPageCacheContent_pidList($cc_pidList);
1720                 }
1721         }
1722
1723         /**
1724          * Returns an error message for the field/command combination inputted. The error message is looked up in the TypoScript properties (evalErrors.[fieldname].[command]) and if empty then the $label value is returned
1725          *
1726          * @param       string          Field name
1727          * @param       string          Command identifier string
1728          * @param       string          Alternative label, shown if no other error string was found
1729          * @return      string          The error message string
1730          */
1731         function getFailure($theField, $theCmd, $label) {
1732                 return isset($this->conf['evalErrors.'][$theField . '.'][$theCmd]) ?
1733                                 $this->conf['evalErrors.'][$theField . '.'][$theCmd] :
1734                                 $label;
1735         }
1736
1737         /**
1738          * Will escape HTML-tags
1739          *
1740          * @param       mixed           The unescaped data
1741          * @return      mixed           The processed input data
1742          */
1743         function escapeHTML($var) {
1744                 if (is_array($var)) {
1745                         foreach ($var as $k => $value) {
1746                                 $var[$k] = $this->escapeHTML($var[$k]);
1747                         }
1748                 } else {
1749                         $var = htmlspecialchars($var, ENT_NOQUOTES);
1750                 }
1751                 return $var;
1752         }
1753 }
1754
1755
1756 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['media/scripts/fe_adminLib.inc'])) {
1757         include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['media/scripts/fe_adminLib.inc']);
1758 }
1759 ?>