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