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