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