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