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