TYPO3 API  SVNRelease
fe_adminLib.inc
Go to the documentation of this file.
00001 <?php
00002 /***************************************************************
00003 *  Copyright notice
00004 *
00005 *  (c) 1999-2009 Kasper Skårhøj (kasperYYYY@typo3.com)
00006 *  All rights reserved
00007 *
00008 *  This script is part of the TYPO3 project. The TYPO3 project is
00009 *  free software; you can redistribute it and/or modify
00010 *  it under the terms of the GNU General Public License as published by
00011 *  the Free Software Foundation; either version 2 of the License, or
00012 *  (at your option) any later version.
00013 *
00014 *  The GNU General Public License can be found at
00015 *  http://www.gnu.org/copyleft/gpl.html.
00016 *  A copy is found in the textfile GPL.txt and important notices to the license
00017 *  from the author is found in LICENSE.txt distributed with these scripts.
00018 *
00019 *
00020 *  This script is distributed in the hope that it will be useful,
00021 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00022 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023 *  GNU General Public License for more details.
00024 *
00025 *  This copyright notice MUST APPEAR in all copies of the script!
00026 ***************************************************************/
00027 /**
00028  * FE admin lib
00029  *
00030  * $Id: fe_adminLib.inc 10317 2011-01-26 00:56:49Z baschny $
00031  * Revised for TYPO3 3.6 June/2003 by Kasper Skårhøj
00032  *
00033  * @author  Kasper Skårhøj <kasperYYYY@typo3.com>
00034  */
00035 /**
00036  * [CLASS/FUNCTION INDEX of SCRIPT]
00037  *
00038  *
00039  *
00040  *  132: class user_feAdmin
00041  *  179:     function init($content,$conf)
00042  *
00043  *              SECTION: Data processing
00044  *  423:     function parseValues()
00045  *  518:     function processFiles($cmdParts,$theField)
00046  *  624:     function overrideValues()
00047  *  640:     function defaultValues()
00048  *  659:     function evalValues()
00049  *  781:     function userProcess($mConfKey,$passVar)
00050  *  799:     function userProcess_alt($confVal,$confArr,$passVar)
00051  *
00052  *              SECTION: Database manipulation functions
00053  *  841:     function save()
00054  *  899:     function deleteRecord()
00055  *  929:     function deleteFilesFromRecord($uid)
00056  *
00057  *              SECTION: Command "display" functions
00058  *  986:     function displayDeleteScreen()
00059  * 1014:     function displayCreateScreen()
00060  * 1037:     function displayEditScreen()
00061  * 1088:     function displayEditForm($origArr)
00062  * 1116:     function procesSetFixed()
00063  *
00064  *              SECTION: Template processing functions
00065  * 1205:     function removeRequired($templateCode,$failure)
00066  * 1223:     function getPlainTemplate($key,$r='')
00067  * 1240:     function modifyDataArrForFormUpdate($inputArr)
00068  * 1309:     function setCObjects($templateCode,$currentArr=array(),$markerArray='',$specialPrefix='')
00069  *
00070  *              SECTION: Emailing
00071  * 1371:     function sendInfoMail()
00072  * 1419:     function compileMail($key, $DBrows, $recipient, $setFixedConfig=array())
00073  * 1465:     function sendMail($recipient, $admin, $content='', $adminContent='')
00074  * 1510:     function isHTMLContent($c)
00075  * 1531:     function sendHTMLMail($content,$recipient,$dummy,$fromEmail,$fromName,$replyTo='')
00076  *
00077  *              SECTION: Various helper functions
00078  * 1615:     function aCAuth($r)
00079  * 1629:     function authCode($r,$extra='')
00080  * 1655:     function setfixed($markerArray, $setfixed, $r)
00081  * 1693:     function setfixedHash($recCopy,$fields='')
00082  * 1714:     function isPreview()
00083  * 1723:     function createFileFuncObj()
00084  * 1734:     function clearCacheIfSet()
00085  * 1749:     function getFailure($theField, $theCmd, $label)
00086  *
00087  * TOTAL FUNCTIONS: 33
00088  * (This index is automatically created/updated by the extension "extdeveval")
00089  *
00090  */
00091 /**
00092  * This library provides a HTML-template file based framework for Front End creating/editing/deleting records authenticated by email or fe_user login.
00093  * It is used in the extensions "direct_mail_subscription" and "feuser_admin" (and the deprecated(!) static template "plugin.feadmin.dmailsubscription" and "plugin.feadmin.fe_users" which are the old versions of these two extensions)
00094  * 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.
00095  * 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.
00096  * Suggestions for improvement and streamlining is welcome so this powerful class could be used more and effectively.
00097  *
00098  * @author  Kasper Skårhøj <kasperYYYY@typo3.com>
00099  * @package TYPO3
00100  * @subpackage tslib
00101  */
00102 class user_feAdmin  {
00103 
00104         // External, static:
00105     var $recInMarkersHSC = TRUE;        // If true, values from the record put into markers going out into HTML will be passed through htmlspecialchars()!
00106 
00107     var $dataArr = array();
00108     var $failureMsg = array();
00109     var $theTable = '';
00110     var $thePid = 0;
00111     var $markerArray = array();
00112     var $templateCode='';
00113     var $cObj;
00114 
00115     var $cmd;
00116     var $preview;
00117     var $backURL;
00118     var $recUid;
00119     var $failure=0;     // is set if data did not have the required fields set.
00120     var $error='';
00121     var $saved=0;       // is set if data is saved
00122     var $requiredArr;
00123     var $currentArr = array();
00124     var $previewLabel='';
00125     var $nc = '';       // '&no_cache=1' if you want that parameter sent.
00126     var $additionalUpdateFields='';
00127     var $emailMarkPrefix = 'EMAIL_TEMPLATE_';
00128     var $codeLength;
00129     var $cmdKey;
00130     var $fileFunc='';   // Set to a basic_filefunc object
00131     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!
00132 
00133         // Internal vars, dynamic:
00134     var $unlinkTempFiles = array();         // Is loaded with all temporary filenames used for upload which should be deleted before exit...
00135 
00136     /**
00137      * Main function. Called from TypoScript.
00138      * This
00139      * - initializes internal variables,
00140      * - fills in the markerArray with default substitution string
00141      * - saves/emails if such commands are sent
00142      * - calls functions for display of the screen for editing/creation/deletion etc.
00143      *
00144      * @param   string      Empty string, ignore.
00145      * @param   array       TypoScript properties following the USER_INT object which uses this library
00146      * @return  string      HTML content
00147      */
00148     function init($content,$conf)   {
00149         $this->conf = $conf;
00150 
00151             // template file is fetched.
00152         $this->templateCode = $this->conf['templateContent'] ? $this->conf['templateContent'] : $this->cObj->fileResource($this->conf['templateFile']);
00153 
00154             // Getting the cmd var
00155         $this->cmd = (string)t3lib_div::_GP('cmd');
00156             // Getting the preview var
00157         $this->preview = (string)t3lib_div::_GP('preview');
00158             // backURL is a given URL to return to when login is performed
00159         $this->backURL = t3lib_div::_GP('backURL');
00160         if (strstr($this->backURL, '"') || strstr($this->backURL, "'") || preg_match('/(javascript|vbscript):/i', $this->backURL)  || stristr($this->backURL, "fromcharcode") || strstr($this->backURL, "<") || strstr($this->backURL, ">"))    {
00161             $this->backURL = '';    // Clear backURL if it seems to contain XSS code - only URLs are allowed
00162         }
00163             // Remove host from URL: Make sure that $this->backURL maps to the current site
00164         $this->backURL = preg_replace('|[A-Za-z]+://[^/]+|', '', $this->backURL);
00165             // Uid to edit:
00166         $this->recUid = t3lib_div::_GP('rU');
00167             // Authentication code:
00168         $this->authCode = t3lib_div::_GP('aC');
00169             // get table
00170         $this->theTable = $this->conf['table'];
00171             // link configuration
00172         $linkConf = is_array($this->conf['formurl.']) ? $this->conf['formurl.'] : array();
00173             // pid
00174         $this->thePid = intval($this->conf['pid']) ? intval($this->conf['pid']) : $GLOBALS['TSFE']->id;
00175             //
00176         $this->codeLength = intval($this->conf['authcodeFields.']['codeLength']) ? intval($this->conf['authcodeFields.']['codeLength']) : 8;
00177 
00178             // Setting the hardcoded lists of fields allowed for editing and creation.
00179         $this->fieldList=implode(',',t3lib_div::trimExplode(',',$GLOBALS['TCA'][$this->theTable]['feInterface']['fe_admin_fieldList'],1));
00180 
00181             // globally substituted markers, fonts and colors.
00182         $splitMark = md5(microtime());
00183         list($this->markerArray['###GW1B###'],$this->markerArray['###GW1E###']) = explode($splitMark,$this->cObj->stdWrap($splitMark,$this->conf['wrap1.']));
00184         list($this->markerArray['###GW2B###'],$this->markerArray['###GW2E###']) = explode($splitMark,$this->cObj->stdWrap($splitMark,$this->conf['wrap2.']));
00185         $this->markerArray['###GC1###'] = $this->cObj->stdWrap($this->conf['color1'],$this->conf['color1.']);
00186         $this->markerArray['###GC2###'] = $this->cObj->stdWrap($this->conf['color2'],$this->conf['color2.']);
00187         $this->markerArray['###GC3###'] = $this->cObj->stdWrap($this->conf['color3'],$this->conf['color3.']);
00188 
00189         if (intval($this->conf['no_cache']) && !isset($linkConf['no_cache']))   {   // needed for backwards compatibility
00190             $linkConf['no_cache'] = 1;
00191         }
00192         if(!$linkConf['parameter']) {
00193             $linkConf['parameter'] = $GLOBALS['TSFE']->id;
00194         }
00195         if(!$linkConf['additionalParams'])  {   // needed for backwards compatibility
00196             $linkConf['additionalParams'] = $this->conf['addParams'];
00197         }
00198 
00199         $formURL = $this->cObj->typoLink_URL($linkConf);
00200         if(!strstr($formURL,'?')) {
00201             $formURL .= '?';
00202         }
00203 
00204             // Initialize markerArray, setting FORM_URL and HIDDENFIELDS
00205         $this->markerArray['###FORM_URL###'] = $formURL;
00206         $this->markerArray['###FORM_URL_ENC###'] = rawurlencode($this->markerArray['###FORM_URL###']);
00207         $this->markerArray['###FORM_URL_HSC###'] = htmlspecialchars($this->markerArray['###FORM_URL###']);
00208 
00209         $this->markerArray['###BACK_URL###'] = $this->backURL;
00210         $this->markerArray['###BACK_URL_ENC###'] = rawurlencode($this->markerArray['###BACK_URL###']);
00211         $this->markerArray['###BACK_URL_HSC###'] = htmlspecialchars($this->markerArray['###BACK_URL###']);
00212 
00213         $this->markerArray['###THE_PID###'] = $this->thePid;
00214         $this->markerArray['###REC_UID###'] = $this->recUid;
00215         $this->markerArray['###AUTH_CODE###'] = $this->authCode;
00216         $this->markerArray['###THIS_ID###'] = $GLOBALS['TSFE']->id;
00217         $this->markerArray['###THIS_URL###'] = htmlspecialchars(t3lib_div::getIndpEnv('TYPO3_REQUEST_DIR'));
00218         $this->markerArray['###HIDDENFIELDS###'] =
00219             ($this->cmd?'<input type="hidden" name="cmd" value="'.htmlspecialchars($this->cmd).'" />':'').
00220             ($this->authCode?'<input type="hidden" name="aC" value="'.htmlspecialchars($this->authCode).'" />':'').
00221             ($this->backURL?'<input type="hidden" name="backURL" value="'.htmlspecialchars($this->backURL).'" />':'');
00222 
00223 
00224             // Setting cmdKey which is either 'edit' or 'create'
00225         switch($this->cmd)  {
00226             case 'edit':
00227                 $this->cmdKey='edit';
00228             break;
00229             default:
00230                 $this->cmdKey='create';
00231             break;
00232         }
00233             // Setting requiredArr to the fields in 'required' intersected field the total field list in order to remove invalid fields.
00234         $this->requiredArr = array_intersect(
00235             t3lib_div::trimExplode(',',$this->conf[$this->cmdKey.'.']['required'],1),
00236             t3lib_div::trimExplode(',',$this->conf[$this->cmdKey.'.']['fields'],1)
00237         );
00238 
00239             // Setting incoming data. Non-stripped
00240         $fe=t3lib_div::_GP('FE');
00241         $this->dataArr = $fe[$this->theTable];  // Incoming data.
00242 
00243             // Checking template file and table value
00244         if (!$this->templateCode)   {
00245             $content = 'No template file found: '.$this->conf['templateFile'];
00246             return $content;
00247         }
00248 
00249         if (!$this->theTable || !$this->fieldList)  {
00250             $content = 'Wrong table: '.$this->theTable;
00251             return $content;        // Not listed or editable table!
00252         }
00253 
00254         // *****************
00255         // If data is submitted, we take care of it here.
00256         // *******************
00257         if ($this->cmd=='delete' && !$this->preview && !t3lib_div::_GP('doNotSave'))    {   // Delete record if delete command is sent + the preview flag is NOT set.
00258             $this->deleteRecord();
00259         }
00260             // If incoming data is seen...
00261         if (is_array($this->dataArr))   {
00262                 // Evaluation of data:
00263             $this->parseValues();
00264             $this->overrideValues();
00265             $this->evalValues();
00266             if ($this->conf['evalFunc'])    {
00267                 $this->dataArr = $this->userProcess('evalFunc',$this->dataArr);
00268             }
00269 
00270         /*
00271         debug($this->dataArr);
00272         debug($this->failure);
00273         debug($this->preview);
00274         */
00275                 // if not preview and no failures, then set data...
00276             if (!$this->failure && !$this->preview && !t3lib_div::_GP('doNotSave')) {   // doNotSave is a global var (eg a 'Cancel' submit button) that prevents the data from being processed
00277                 $this->save();
00278             } else {
00279                 if ($this->conf['debug'])       debug($this->failure);
00280             }
00281         } else {
00282             $this->defaultValues(); // If no incoming data, this will set the default values.
00283             $this->preview = 0; // No preview if data is not received
00284         }
00285         if ($this->failure) {$this->preview=0;} // No preview flag if a evaluation failure has occured
00286         $this->previewLabel = $this->preview ? '_PREVIEW' : ''; // Setting preview label prefix.
00287 
00288 
00289             // *********************
00290             // DISPLAY FORMS:
00291             // ***********************
00292         if ($this->saved) {
00293                 // Clear page cache
00294             $this->clearCacheIfSet();
00295 
00296                 // Displaying the page here that says, the record has been saved. You're able to include the saved values by markers.
00297             switch($this->cmd)  {
00298                 case 'delete':
00299                     $key='DELETE';
00300                 break;
00301                 case 'edit':
00302                     $key='EDIT';
00303                 break;
00304                 default:
00305                     $key='CREATE';
00306                 break;
00307             }
00308                 // Output message
00309             $templateCode = $this->cObj->getSubpart($this->templateCode, '###TEMPLATE_'.$key.'_SAVED###');
00310             $this->setCObjects($templateCode,$this->currentArr);
00311             $markerArray = $this->cObj->fillInMarkerArray($this->markerArray, $this->currentArr, '', TRUE, 'FIELD_', $this->recInMarkersHSC);
00312             $content = $this->cObj->substituteMarkerArray($templateCode, $markerArray);
00313 
00314                 // email message:
00315             $this->compileMail(
00316                 $key.'_SAVED',
00317                 array($this->currentArr),
00318                 $this->currentArr[$this->conf['email.']['field']],
00319                 $this->conf['setfixed.']
00320             );
00321 
00322         } elseif ($this->error) {   // If there was an error, we return the template-subpart with the error message
00323             $templateCode = $this->cObj->getSubpart($this->templateCode, $this->error);
00324             $this->setCObjects($templateCode);
00325             $content = $this->cObj->substituteMarkerArray($templateCode, $this->markerArray);
00326         } else {
00327                 // Finally, if there has been no attempt to save. That is either preview or just displaying and empty or not correctly filled form:
00328             if (!$this->cmd)    {
00329                 $this->cmd=$this->conf['defaultCmd'];
00330             }
00331             if ($this->conf['debug'])       debug('Display form: '.$this->cmd,1);
00332             switch($this->cmd)  {
00333                 case 'setfixed':
00334                     $content = $this->procesSetFixed();
00335                 break;
00336                 case 'infomail':
00337                     $content = $this->sendInfoMail();
00338                 break;
00339                 case 'delete':
00340                     $content = $this->displayDeleteScreen();
00341                 break;
00342                 case 'edit':
00343                     $content = $this->displayEditScreen();
00344                 break;
00345                 case 'create':
00346                     $content = $this->displayCreateScreen();
00347                 break;
00348             }
00349         }
00350 
00351             // Delete temp files:
00352         foreach($this->unlinkTempFiles as $tempFileName)    {
00353             t3lib_div::unlink_tempfile($tempFileName);
00354         }
00355 
00356             // Return content:
00357         return $content;
00358     }
00359 
00360 
00361 
00362 
00363 
00364 
00365 
00366 
00367 
00368 
00369 
00370 
00371 
00372 
00373 
00374 
00375 
00376 
00377 
00378 
00379 
00380 
00381 
00382     /*****************************************
00383      *
00384      * Data processing
00385      *
00386      *****************************************/
00387 
00388     /**
00389      * Performs processing on the values found in the input data array, $this->dataArr.
00390      * The processing is done according to configuration found in TypoScript
00391      * 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.
00392      * Called from init() if the $this->dataArr is found to be an array
00393      *
00394      * @return  void
00395      * @see init()
00396      */
00397     function parseValues()  {
00398         if (is_array($this->conf['parseValues.']))  {
00399             foreach ($this->conf['parseValues.'] as $theField => $theValue) {
00400                 $listOfCommands = t3lib_div::trimExplode(',',$theValue,1);
00401                 foreach ($listOfCommands as $cmd) {
00402                     $cmdParts = preg_split('/\[|\]/', $cmd);    // Point is to enable parameters after each command enclosed in brackets [..]. These will be in position 1 in the array.
00403                     $theCmd=trim($cmdParts[0]);
00404                     switch($theCmd) {
00405                         case 'int':
00406                             $this->dataArr[$theField]=intval($this->dataArr[$theField]);
00407                         break;
00408                         case 'lower':
00409                         case 'upper':
00410                             $this->dataArr[$theField] = $this->cObj->caseshift($this->dataArr[$theField],$theCmd);
00411                         break;
00412                         case 'nospace':
00413                             $this->dataArr[$theField] = str_replace(' ', '', $this->dataArr[$theField]);
00414                         break;
00415                         case 'alpha':
00416                             $this->dataArr[$theField] = preg_replace('/[^a-zA-Z]/','',$this->dataArr[$theField]);
00417                         break;
00418                         case 'num':
00419                             $this->dataArr[$theField] = preg_replace('/[^0-9]/','',$this->dataArr[$theField]);
00420                         break;
00421                         case 'alphanum':
00422                             $this->dataArr[$theField] = preg_replace('/[^a-zA-Z0-9]/','',$this->dataArr[$theField]);
00423                         break;
00424                         case 'alphanum_x':
00425                             $this->dataArr[$theField] = preg_replace('/[^a-zA-Z0-9_-]/','',$this->dataArr[$theField]);
00426                         break;
00427                         case 'trim':
00428                             $this->dataArr[$theField] = trim($this->dataArr[$theField]);
00429                         break;
00430                         case 'random':
00431                             $this->dataArr[$theField] = substr(md5(uniqid(microtime(),1)),0,intval($cmdParts[1]));
00432                         break;
00433                         case 'files':
00434                             if ($this->cmdKey=='create' && !t3lib_div::_GP('doNotSave'))    {
00435                                 $this->processFiles($cmdParts,$theField);
00436                             } else unset($this->dataArr[$theField]);    // Fields with files cannot be edited - only created.
00437                         break;
00438                         case 'setEmptyIfAbsent':
00439                             if (!isset($this->dataArr[$theField]))  {
00440                                 $this->dataArr[$theField]='';
00441                             }
00442                         break;
00443                         case 'multiple':
00444                             if (is_array($this->dataArr[$theField]))    {
00445                                 $this->dataArr[$theField] = implode(',',$this->dataArr[$theField]);
00446                             }
00447                         break;
00448                         case 'checkArray':
00449                             if (is_array($this->dataArr[$theField]))    {
00450                                 $val = 0;
00451                                 foreach ($this->dataArr[$theField] as $kk => $vv) {
00452                                     $kk = t3lib_div::intInRange($kk,0);
00453                                     if ($kk<=30)    {
00454                                         if ($vv)    {
00455                                             $val|=pow(2,$kk);
00456                                         }
00457                                     }
00458                                 }
00459                                 $this->dataArr[$theField] = $val;
00460                             } else {$this->dataArr[$theField]=0;}
00461                         break;
00462                         case 'uniqueHashInt':
00463                             $otherFields = t3lib_div::trimExplode(';',$cmdParts[1],1);
00464                             $hashArray=array();
00465                             foreach ($otherFields as $fN) {
00466                                 $vv = $this->dataArr[$fN];
00467                                 $vv = preg_replace('/[[:space:]]/','',$vv);
00468                                 $vv = preg_replace('/[^[:alnum:]]/','',$vv);
00469                                 $vv = strtolower($vv);
00470                                 $hashArray[]=$vv;
00471                             }
00472                             $this->dataArr[$theField]=hexdec(substr(md5(serialize($hashArray)),0,8));
00473                         break;
00474                     }
00475                 }
00476             }
00477         }
00478     }
00479 
00480     /**
00481      * Processing of files.
00482      * NOTICE: for now files can be handled only on creation of records. But a more advanced feature is that PREVIEW of files is handled.
00483      *
00484      * @param   array       Array with cmd-parts (from parseValues()). This will for example contain information about allowed file extensions and max size of uploaded files.
00485      * @param   string      The fieldname with the files.
00486      * @return  void
00487      * @access private
00488      * @see parseValues()
00489      */
00490     function processFiles($cmdParts,$theField)  {
00491 //debug($_FILES);
00492             // First, make an array with the filename and file reference, whether the file is just uploaded or a preview
00493         $filesArr = array();
00494 
00495         if (is_string($this->dataArr[$theField]))   {       // files from preview.
00496             $tmpArr = explode(',',$this->dataArr[$theField]);
00497             foreach ($tmpArr as $val) {
00498                 $valParts = explode('|',$val);
00499                 $filesArr[] = array (
00500                     'name'=>$valParts[1],
00501                     'tmp_name'=>PATH_site.'typo3temp/'.$valParts[0]
00502                 );
00503             }
00504         } elseif (is_array($_FILES['FE'][$this->theTable][$theField]['name']))  {   // Files from upload
00505             foreach ($_FILES['FE'][$this->theTable][$theField]['name'] as $kk => $vv) {
00506                 if ($vv)    {
00507                     $tmpFile = t3lib_div::upload_to_tempfile($_FILES['FE'][$this->theTable][$theField]['tmp_name'][$kk]);
00508                     if ($tmpFile)   {
00509                         $this->unlinkTempFiles[]=$tmpFile;
00510                         $filesArr[] = array (
00511                             'name'=>$vv,
00512                             'tmp_name'=>$tmpFile
00513                         );
00514                     }
00515                 }
00516             }
00517         } elseif (is_array($_FILES['FE']['name'][$this->theTable][$theField]))  {   // Files from upload
00518             foreach ($_FILES['FE']['name'][$this->theTable][$theField] as $kk => $vv) {
00519                 if ($vv)    {
00520                     $tmpFile = t3lib_div::upload_to_tempfile($_FILES['FE']['tmp_name'][$this->theTable][$theField][$kk]);
00521                     if ($tmpFile)   {
00522                         $this->unlinkTempFiles[]=$tmpFile;
00523                         $filesArr[] = array (
00524                             'name'=>$vv,
00525                             'tmp_name'=>$tmpFile
00526                         );
00527                     }
00528                 }
00529             }
00530         }
00531 
00532             // Then verify the files in that array; check existence, extension and size
00533         $this->dataArr[$theField]='';
00534         $finalFilesArr=array();
00535         if (count($filesArr))   {
00536             $extArray = t3lib_div::trimExplode(';',strtolower($cmdParts[1]),1);
00537             $maxSize = intval($cmdParts[3]);
00538             foreach ($filesArr as $infoArr) {
00539                 $fI = pathinfo($infoArr['name']);
00540                 if (t3lib_div::verifyFilenameAgainstDenyPattern($fI['name']))   {
00541                     if (!count($extArray) || in_array(strtolower($fI['extension']), $extArray)) {
00542                         $tmpFile = $infoArr['tmp_name'];
00543                         if (@is_file($tmpFile)) {
00544                             if (!$maxSize || filesize($tmpFile)<$maxSize*1024)  {
00545                                 $finalFilesArr[]=$infoArr;
00546                             } elseif ($this->conf['debug']) {debug('Size is beyond '.$maxSize.' kb ('.filesize($tmpFile).' bytes) and the file cannot be saved.');}
00547                         } elseif ($this->conf['debug']) {debug('Surprisingly there was no file for '.$vv.' in '.$tmpFile);}
00548                     } elseif ($this->conf['debug']) {debug('Extension "'.$fI['extension'].'" not allowed');}
00549                 } elseif ($this->conf['debug']) {debug('Filename matched illegal pattern.');}
00550             }
00551         }
00552             // Copy the files in the resulting array to the proper positions based on preview/non-preview.
00553         $fileNameList=array();
00554         foreach ($finalFilesArr as $infoArr) {
00555             if ($this->isPreview()) {       // If the form is a preview form (and data is therefore not going into the database...) do this.
00556                 $this->createFileFuncObj();
00557                 $fI = pathinfo($infoArr['name']);
00558                 $tmpFilename = $this->theTable.'_'.t3lib_div::shortmd5(uniqid($infoArr['name'])).'.'.$fI['extension'];
00559                 $theDestFile = $this->fileFunc->getUniqueName($this->fileFunc->cleanFileName($tmpFilename), PATH_site.'typo3temp/');
00560                 t3lib_div::upload_copy_move($infoArr['tmp_name'],$theDestFile);
00561                     // Setting the filename in the list
00562                 $fI2 = pathinfo($theDestFile);
00563                 $fileNameList[] = $fI2['basename'].'|'.$infoArr['name'];
00564             } else {
00565                 $this->createFileFuncObj();
00566                 $GLOBALS['TSFE']->includeTCA();
00567                 t3lib_div::loadTCA($this->theTable);
00568                 if (is_array($GLOBALS['TCA'][$this->theTable]['columns'][$theField]))   {
00569                     $uploadPath = $GLOBALS['TCA'][$this->theTable]['columns'][$theField]['config']['uploadfolder'];
00570                 }
00571                 if ($uploadPath)    {
00572                     $theDestFile = $this->fileFunc->getUniqueName($this->fileFunc->cleanFileName($infoArr['name']), PATH_site.$uploadPath);
00573                     t3lib_div::upload_copy_move($infoArr['tmp_name'],$theDestFile);
00574                         // Setting the filename in the list
00575                     $fI2 = pathinfo($theDestFile);
00576                     $fileNameList[] = $fI2['basename'];
00577                     $this->filesStoredInUploadFolders[]=$theDestFile;
00578                 }
00579             }
00580                 // Implode the list of filenames
00581             $this->dataArr[$theField] = implode(',',$fileNameList);
00582         }
00583     }
00584 
00585     /**
00586      * Overriding values in $this->dataArr if configured for that in TypoScript ([edit/create].overrideValues)
00587      *
00588      * @return  void
00589      * @see init()
00590      */
00591     function overrideValues()   {
00592         // Addition of overriding values
00593         if (is_array($this->conf[$this->cmdKey.'.']['overrideValues.']))    {
00594             foreach ($this->conf[$this->cmdKey.'.']['overrideValues.'] as $theField => $theValue) {
00595                 $this->dataArr[$theField] = $theValue;
00596             }
00597         }
00598     }
00599 
00600     /**
00601      * Called if there is no input array in $this->dataArr. Then this function sets the default values configured in TypoScript
00602      *
00603      * @return  void
00604      * @see init()
00605      */
00606     function defaultValues()    {
00607             // Addition of default values
00608         if (is_array($this->conf[$this->cmdKey.'.']['defaultValues.'])) {
00609             foreach ($this->conf[$this->cmdKey.'.']['defaultValues.'] as $theField => $theValue) {
00610                 $this->dataArr[$theField] = $theValue;
00611             }
00612         }
00613     }
00614 
00615     /**
00616      * This will evaluate the input values from $this->dataArr to see if they conforms with the requirements configured in TypoScript per field.
00617      * For example this could be checking if a field contains a valid email address, a unique value, a value within a certain range etc.
00618      * 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())
00619      * Works based on configuration in TypoScript key [create/edit].evalValues
00620      *
00621      * @return  void
00622      * @see init(), parseValues()
00623      */
00624     function evalValues()   {
00625         // Check required, set failure if not ok.
00626         $tempArr=array();
00627         foreach ($this->requiredArr as $theField) {
00628             if (!trim($this->dataArr[$theField]))   {
00629                 $tempArr[]=$theField;
00630             }
00631         }
00632 
00633         // 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!
00634         $recExist=0;
00635         if (is_array($this->conf[$this->cmdKey.'.']['evalValues.']))    {
00636             switch($this->cmd)  {
00637                 case 'edit':
00638                     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.
00639                         $recordTestPid = intval($this->dataArr['pid']);
00640                     } else {
00641                         $tempRecArr = $GLOBALS['TSFE']->sys_page->getRawRecord($this->theTable,$this->dataArr['uid']);
00642                         $recordTestPid = intval($tempRecArr['pid']);
00643                     }
00644                     $recExist=1;
00645                 break;
00646                 default:
00647                     $recordTestPid = $this->thePid ? $this->thePid : t3lib_div::intval_positive($this->dataArr['pid']);
00648                 break;
00649             }
00650 
00651             foreach ($this->conf[$this->cmdKey.'.']['evalValues.'] as $theField => $theValue) {
00652                 $listOfCommands = t3lib_div::trimExplode(',',$theValue,1);
00653                 foreach ($listOfCommands as $cmd) {
00654                     $cmdParts = preg_split('/\[|\]/', $cmd);    // Point is to enable parameters after each command enclosed in brackets [..]. These will be in position 1 in the array.
00655                     $theCmd = trim($cmdParts[0]);
00656                     switch($theCmd) {
00657                         case 'uniqueGlobal':
00658                             if ($DBrows = $GLOBALS['TSFE']->sys_page->getRecordsByField($this->theTable,$theField,$this->dataArr[$theField],'','','','1'))  {
00659                                 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.
00660                                     $tempArr[]=$theField;
00661                                     $this->failureMsg[$theField][] = $this->getFailure($theField, $theCmd, 'The value existed already. Enter a new value.');
00662                                 }
00663                             }
00664                         break;
00665                         case 'uniqueLocal':
00666                             if ($DBrows = $GLOBALS['TSFE']->sys_page->getRecordsByField($this->theTable,$theField,$this->dataArr[$theField], 'AND pid IN ('.$recordTestPid.')','','','1'))  {
00667                                 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.
00668                                     $tempArr[]=$theField;
00669                                     $this->failureMsg[$theField][] = $this->getFailure($theField, $theCmd, 'The value existed already. Enter a new value.');
00670                                 }
00671                             }
00672                         break;
00673                         case 'twice':
00674                             if (strcmp($this->dataArr[$theField], $this->dataArr[$theField.'_again']))  {
00675                                 $tempArr[]=$theField;
00676                                 $this->failureMsg[$theField][] = $this->getFailure($theField, $theCmd, 'You must enter the same value twice');
00677                             }
00678                         break;
00679                         case 'email':
00680                             if (!$this->cObj->checkEmail($this->dataArr[$theField]))    {
00681                                 $tempArr[]=$theField;
00682                                 $this->failureMsg[$theField][] = $this->getFailure($theField, $theCmd, 'You must enter a valid email address');
00683                             }
00684                         break;
00685                         case 'required':
00686                             if (!trim($this->dataArr[$theField]))   {
00687                                 $tempArr[]=$theField;
00688                                 $this->failureMsg[$theField][] = $this->getFailure($theField, $theCmd, 'You must enter a value!');
00689                             }
00690                         break;
00691                         case 'atLeast':
00692                             $chars=intval($cmdParts[1]);
00693                             if (strlen($this->dataArr[$theField])<$chars)   {
00694                                 $tempArr[]=$theField;
00695                                 $this->failureMsg[$theField][] = sprintf($this->getFailure($theField, $theCmd, 'You must enter at least %s characters!'), $chars);
00696                             }
00697                         break;
00698                         case 'atMost':
00699                             $chars=intval($cmdParts[1]);
00700                             if (strlen($this->dataArr[$theField])>$chars)   {
00701                                 $tempArr[]=$theField;
00702                                 $this->failureMsg[$theField][] = sprintf($this->getFailure($theField, $theCmd, 'You must enter at most %s characters!'), $chars);
00703                             }
00704                         break;
00705                         case 'inBranch':
00706                             $pars = explode(';',$cmdParts[1]);
00707                             if (intval($pars[0]))   {
00708                                 $pid_list = $this->cObj->getTreeList(
00709                                     intval($pars[0]),
00710                                     intval($pars[1]) ? intval($pars[1]) : 999,
00711                                     intval($pars[2])
00712                                 );
00713                                 if (!$pid_list || !t3lib_div::inList($pid_list,$this->dataArr[$theField]))  {
00714                                     $tempArr[]=$theField;
00715                                     $this->failureMsg[$theField][] = sprintf($this->getFailure($theField, $theCmd, 'The value was not a valid valud from this list: %s'), $pid_list);
00716                                 }
00717                             }
00718                         break;
00719                         case 'unsetEmpty':
00720                             if (!$this->dataArr[$theField]) {
00721                                 $hash = array_flip($tempArr);
00722                                 unset($hash[$theField]);
00723                                 $tempArr = array_keys($hash);
00724                                 unset($this->failureMsg[$theField]);
00725                                 unset($this->dataArr[$theField]);   // This should prevent the field from entering the database.
00726                             }
00727                         break;
00728                     }
00729                 }
00730                 $this->markerArray['###EVAL_ERROR_FIELD_'.$theField.'###'] = is_array($this->failureMsg[$theField]) ? implode('<br />',$this->failureMsg[$theField]) : '';
00731             }
00732         }
00733         $this->failure=implode(',',$tempArr);    //$failure will show which fields were not OK
00734     }
00735 
00736     /**
00737      * Preforms user processing of input array - triggered right after the function call to evalValues() IF TypoScript property "evalFunc" was set.
00738      *
00739      * @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.
00740      * @param   array       The $this->dataArr passed for processing
00741      * @return  array       The processed $passVar ($this->dataArr)
00742      * @see init(), evalValues()
00743      */
00744     function userProcess($mConfKey,$passVar)    {
00745         if ($this->conf[$mConfKey]) {
00746             $funcConf = $this->conf[$mConfKey.'.'];
00747             $funcConf['parentObj'] = $this;
00748             $passVar = $GLOBALS['TSFE']->cObj->callUserFunction($this->conf[$mConfKey], $funcConf, $passVar);
00749         }
00750         return $passVar;
00751     }
00752 
00753     /**
00754      * User processing of contnet
00755      *
00756      * @param   string      Value of the TypoScript object triggering the processing.
00757      * @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.
00758      * @param   mixed       Input variable to process
00759      * @return  mixed       Processed input variable, $passVar
00760      * @see userProcess(), save(), modifyDataArrForFormUpdate()
00761      */
00762     function userProcess_alt($confVal,$confArr,$passVar)    {
00763         if ($confVal)   {
00764             $funcConf = $confArr;
00765             $funcConf['parentObj'] = $this;
00766             $passVar = $GLOBALS['TSFE']->cObj->callUserFunction($confVal, $funcConf, $passVar);
00767         }
00768         return $passVar;
00769     }
00770 
00771 
00772 
00773 
00774 
00775 
00776 
00777 
00778 
00779 
00780 
00781 
00782 
00783 
00784 
00785 
00786 
00787 
00788 
00789 
00790 
00791 
00792     /*****************************************
00793      *
00794      * Database manipulation functions
00795      *
00796      *****************************************/
00797 
00798     /**
00799      * Performs the saving of records, either edited or created.
00800      *
00801      * @return  void
00802      * @see init()
00803      */
00804     function save() {
00805         switch($this->cmd)  {
00806             case 'edit':
00807                 $theUid = $this->dataArr['uid'];
00808                 $origArr = $GLOBALS['TSFE']->sys_page->getRawRecord($this->theTable,$theUid);       // Fetches the original record to check permissions
00809                 if ($this->conf['edit'] && ($GLOBALS['TSFE']->loginUser || $this->aCAuth($origArr)))    {   // Must be logged in in order to edit  (OR be validated by email)
00810                     $newFieldList = implode(',',array_intersect(explode(',',$this->fieldList),t3lib_div::trimExplode(',',$this->conf['edit.']['fields'],1)));
00811                     if ($this->aCAuth($origArr) || $this->cObj->DBmayFEUserEdit($this->theTable,$origArr,$GLOBALS['TSFE']->fe_user->user,$this->conf['allowedGroups'],$this->conf['fe_userEditSelf']))  {
00812                         $this->cObj->DBgetUpdate($this->theTable, $theUid, $this->dataArr, $newFieldList, TRUE);
00813                         $this->currentArr = $GLOBALS['TSFE']->sys_page->getRawRecord($this->theTable,$theUid);
00814                         $this->userProcess_alt($this->conf['edit.']['userFunc_afterSave'],$this->conf['edit.']['userFunc_afterSave.'],array('rec'=>$this->currentArr, 'origRec'=>$origArr));
00815                         $this->saved=1;
00816                     } else {
00817                         $this->error='###TEMPLATE_NO_PERMISSIONS###';
00818                     }
00819                 }
00820             break;
00821             default:
00822                 if ($this->conf['create'])  {
00823                     $newFieldList = implode(',',array_intersect(explode(',',$this->fieldList),t3lib_div::trimExplode(',',$this->conf['create.']['fields'],1)));
00824                     $this->cObj->DBgetInsert($this->theTable, $this->thePid, $this->dataArr, $newFieldList, TRUE);
00825                     $newId = $GLOBALS['TYPO3_DB']->sql_insert_id();
00826 
00827                     if ($this->theTable=='fe_users' && $this->conf['fe_userOwnSelf'])   {       // enables users, creating logins, to own them self.
00828                         $extraList='';
00829                         $dataArr = array();
00830                         if ($GLOBALS['TCA'][$this->theTable]['ctrl']['fe_cruser_id'])       {
00831                             $field=$GLOBALS['TCA'][$this->theTable]['ctrl']['fe_cruser_id'];
00832                             $dataArr[$field]=$newId;
00833                             $extraList.=','.$field;
00834                         }
00835                         if ($GLOBALS['TCA'][$this->theTable]['ctrl']['fe_crgroup_id'])  {
00836                             $field=$GLOBALS['TCA'][$this->theTable]['ctrl']['fe_crgroup_id'];
00837                             list($dataArr[$field])=explode(',',$this->dataArr['usergroup']);
00838                             $dataArr[$field]=intval($dataArr[$field]);
00839                             $extraList.=','.$field;
00840                         }
00841                         if (count($dataArr))    {
00842                             $this->cObj->DBgetUpdate($this->theTable, $newId, $dataArr, $extraList, TRUE);
00843                         }
00844                     }
00845 
00846                     $this->currentArr = $GLOBALS['TSFE']->sys_page->getRawRecord($this->theTable,$newId);
00847                     $this->userProcess_alt($this->conf['create.']['userFunc_afterSave'],$this->conf['create.']['userFunc_afterSave.'],array('rec'=>$this->currentArr));
00848                     $this->saved=1;
00849                 }
00850             break;
00851         }
00852     }
00853 
00854     /**
00855      * Deletes the record from table/uid, $this->theTable/$this->recUid, IF the fe-user has permission to do so.
00856      * If the deleted flag should just be set, then it is done so. Otherwise the record truely is deleted along with any attached files.
00857      * Called from init() if "cmd" was set to "delete" (and some other conditions)
00858      *
00859      * @return  string      void
00860      * @see init()
00861      */
00862     function deleteRecord() {
00863         if ($this->conf['delete'])  {   // If deleting is enabled
00864             $origArr = $GLOBALS['TSFE']->sys_page->getRawRecord($this->theTable,  $this->recUid);
00865             if ($GLOBALS['TSFE']->loginUser || $this->aCAuth($origArr)) {   // Must be logged in OR be authenticated by the aC code in order to delete
00866                     // If the recUid selects a record.... (no check here)
00867                 if (is_array($origArr)) {
00868                     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.
00869                         if (!$GLOBALS['TCA'][$this->theTable]['ctrl']['delete'])    {   // If the record is fully deleted... then remove the image (or any file) attached.
00870                             $this->deleteFilesFromRecord($this->recUid);
00871                         }
00872                         $this->cObj->DBgetDelete($this->theTable, $this->recUid, TRUE);
00873                         $this->currentArr = $origArr;
00874                         $this->saved = 1;
00875                     } else {
00876                         $this->error = '###TEMPLATE_NO_PERMISSIONS###';
00877                     }
00878                 }
00879             }
00880         }
00881     }
00882 
00883     /**
00884      * Deletes the files attached to a record and updates the record.
00885      * Table/uid is $this->theTable/$uid
00886      *
00887      * @param   integer     Uid number of the record to delete from $this->theTable
00888      * @return  void
00889      * @access private
00890      * @see deleteRecord()
00891      */
00892     function deleteFilesFromRecord($uid)    {
00893         $table = $this->theTable;
00894         $rec = $GLOBALS['TSFE']->sys_page->getRawRecord($table,$uid);
00895 
00896         $GLOBALS['TSFE']->includeTCA();
00897         t3lib_div::loadTCA($table);
00898         $iFields=array();
00899         foreach ($GLOBALS['TCA'][$table]['columns'] as $field => $conf) {
00900             if ($conf['config']['type']=='group' && $conf['config']['internal_type']=='file')   {
00901 
00902                 $GLOBALS['TYPO3_DB']->exec_UPDATEquery($table, 'uid='.intval($uid), array($field => ''));
00903 
00904                 $delFileArr = explode(',',$rec[$field]);
00905                 foreach ($delFileArr as $n) {
00906                     if ($n) {
00907                         $fpath = $conf['config']['uploadfolder'].'/'.$n;
00908                         unlink($fpath);
00909                     }
00910                 }
00911             }
00912         }
00913     }
00914 
00915 
00916 
00917 
00918 
00919 
00920 
00921 
00922 
00923 
00924 
00925 
00926 
00927 
00928 
00929 
00930 
00931 
00932 
00933 
00934 
00935     /*****************************************
00936      *
00937      * Command "display" functions
00938      *
00939      *****************************************/
00940 
00941     /**
00942      * Creates the preview display of delete actions
00943      *
00944      * @return  string      HTML content
00945      * @see init()
00946      */
00947     function displayDeleteScreen()  {
00948         if ($this->conf['delete'])  {   // If deleting is enabled
00949             $origArr = $GLOBALS['TSFE']->sys_page->getRawRecord($this->theTable,  $this->recUid);
00950             if ($GLOBALS['TSFE']->loginUser || $this->aCAuth($origArr)) {   // Must be logged in OR be authenticated by the aC code in order to delete
00951                     // If the recUid selects a record.... (no check here)
00952                 if (is_array($origArr)) {
00953                     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.
00954                         $this->markerArray['###HIDDENFIELDS###'].= '<input type="hidden" name="rU" value="'.$this->recUid.'" />';
00955                         $content = $this->getPlainTemplate('###TEMPLATE_DELETE_PREVIEW###', $origArr);
00956                     } else {    // Else display error, that you could not edit that particular record...
00957                         $content = $this->getPlainTemplate('###TEMPLATE_NO_PERMISSIONS###');
00958                     }
00959                 }
00960             } 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.
00961                 $content = $this->getPlainTemplate('###TEMPLATE_AUTH###');
00962             }
00963         } else {
00964             $content.='Delete-option is not set in TypoScript';
00965         }
00966         return $content;
00967     }
00968 
00969     /**
00970      * Creates the "create" screen for records
00971      *
00972      * @return  string      HTML content
00973      * @see init()
00974      */
00975     function displayCreateScreen()  {
00976         if ($this->conf['create'])  {
00977             $templateCode = $this->cObj->getSubpart($this->templateCode, ((!$GLOBALS['TSFE']->loginUser||$this->conf['create.']['noSpecialLoginForm'])?'###TEMPLATE_CREATE'.$this->previewLabel.'###':'###TEMPLATE_CREATE_LOGIN'.$this->previewLabel.'###'));
00978             $failure = t3lib_div::_GP('noWarnings')?'':$this->failure;
00979             if (!$failure)  $templateCode = $this->cObj->substituteSubpart($templateCode, '###SUB_REQUIRED_FIELDS_WARNING###', '');
00980 
00981             $templateCode = $this->removeRequired($templateCode,$failure);
00982             $this->setCObjects($templateCode);
00983 
00984             if (!is_array($this->dataArr)) {
00985                 $this->dataArr = array();
00986             }
00987 
00988             $markerArray = $this->cObj->fillInMarkerArray($this->markerArray, $this->dataArr, '', TRUE, 'FIELD_', $this->recInMarkersHSC);
00989             if ($this->conf['create.']['preview'] && !$this->previewLabel)  {$markerArray['###HIDDENFIELDS###'].= '<input type="hidden" name="preview" value="1" />';}
00990             $content = $this->cObj->substituteMarkerArray($templateCode, $markerArray);
00991             $content.=$this->cObj->getUpdateJS($this->modifyDataArrForFormUpdate($this->dataArr), $this->theTable.'_form', 'FE['.$this->theTable.']', $this->fieldList.$this->additionalUpdateFields);
00992         }
00993         return $content;
00994     }
00995 
00996     /**
00997      * Creates the edit-screen for records
00998      *
00999      * @return  string      HTML content
01000      * @see init()
01001      */
01002     function displayEditScreen()    {
01003         if ($this->conf['edit'])    {   // If editing is enabled
01004             $origArr = $GLOBALS['TSFE']->sys_page->getRawRecord($this->theTable,  $this->dataArr['uid']?$this->dataArr['uid']:$this->recUid);
01005 
01006             if ($GLOBALS['TSFE']->loginUser || $this->aCAuth($origArr)) {   // Must be logged in OR be authenticated by the aC code in order to edit
01007                     // If the recUid selects a record.... (no check here)
01008                 if (is_array($origArr)) {
01009                     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.
01010                         $content=$this->displayEditForm($origArr);
01011                     } else {    // Else display error, that you could not edit that particular record...
01012                         $content = $this->getPlainTemplate('###TEMPLATE_NO_PERMISSIONS###');
01013                     }
01014                 } elseif ($GLOBALS['TSFE']->loginUser) {    // If the recUid did not select a record, we display a menu of records. (eg. if no recUid)
01015                     $lockPid = $this->conf['edit.']['menuLockPid'] ? ' AND pid='.intval($this->thePid) : '';
01016 
01017                     $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', $this->theTable, '1 '.$lockPid.$this->cObj->DBmayFEUserEditSelect($this->theTable,$GLOBALS['TSFE']->fe_user->user, $this->conf['allowedGroups'],$this->conf['fe_userEditSelf']).$GLOBALS['TSFE']->sys_page->deleteClause($this->theTable));
01018 
01019                     if ($GLOBALS['TYPO3_DB']->sql_num_rows($res))   {   // If there are menu-items ...
01020                         $templateCode = $this->getPlainTemplate('###TEMPLATE_EDITMENU###');
01021                         $out='';
01022                         $itemCode = $this->cObj->getSubpart($templateCode, '###ITEM###');
01023                         while($menuRow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))   {
01024                             $markerArray = $this->cObj->fillInMarkerArray(array(), $menuRow, '', TRUE, 'FIELD_', $this->recInMarkersHSC);
01025                             $markerArray = $this->setCObjects($itemCode,$menuRow,$markerArray,'ITEM_');
01026                             $out.= $this->cObj->substituteMarkerArray($itemCode, $markerArray);
01027                         }
01028                         $content=$this->cObj->substituteSubpart($templateCode, '###ALLITEMS###', $out);
01029                     } else {    // If there are not menu items....
01030                         $content = $this->getPlainTemplate('###TEMPLATE_EDITMENU_NOITEMS###');
01031                     }
01032                 } else {
01033                     $content = $this->getPlainTemplate('###TEMPLATE_AUTH###');
01034                 }
01035             } 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.
01036                 $content = $this->getPlainTemplate('###TEMPLATE_AUTH###');
01037             }
01038         } else {
01039             $content.='Edit-option is not set in TypoScript';
01040         }
01041         return $content;
01042     }
01043 
01044     /**
01045      * Subfunction for displayEditScreen(); Takes a record and creates an edit form based on the template code for it.
01046      * This function is called if the user is editing a record and permitted to do so. Checked in displayEditScreen()
01047      *
01048      * @param   array       The array with the record to edit
01049      * @return  string      HTML content
01050      * @access private
01051      * @see displayEditScreen()
01052      */
01053     function displayEditForm($origArr)  {
01054         $currentArr = is_array($this->dataArr) ? $this->dataArr+$origArr : $origArr;
01055 
01056         if ($this->conf['debug'])   debug('displayEditForm(): '.'###TEMPLATE_EDIT'.$this->previewLabel.'###',1);
01057         $templateCode = $this->cObj->getSubpart($this->templateCode, '###TEMPLATE_EDIT'.$this->previewLabel.'###');
01058         $failure = t3lib_div::_GP('noWarnings')?'':$this->failure;
01059         if (!$failure)  {$templateCode = $this->cObj->substituteSubpart($templateCode, '###SUB_REQUIRED_FIELDS_WARNING###', '');}
01060 
01061         $templateCode = $this->removeRequired($templateCode,$failure);
01062 
01063         $this->setCObjects($templateCode,$currentArr);
01064 
01065         $markerArray = $this->cObj->fillInMarkerArray($this->markerArray, $currentArr, '', TRUE, 'FIELD_', $this->recInMarkersHSC);
01066 
01067         $markerArray['###HIDDENFIELDS###'].= '<input type="hidden" name="FE['.$this->theTable.'][uid]" value="'.$currentArr['uid'].'" />';
01068         if ($this->conf['edit.']['preview'] && !$this->previewLabel)    {$markerArray['###HIDDENFIELDS###'].= '<input type="hidden" name="preview" value="1" />';}
01069         $content = $this->cObj->substituteMarkerArray($templateCode, $markerArray);
01070         $content.=$this->cObj->getUpdateJS($this->modifyDataArrForFormUpdate($currentArr), $this->theTable.'_form',  'FE['.$this->theTable.']', $this->fieldList.$this->additionalUpdateFields);
01071 
01072         return $content;
01073     }
01074 
01075     /**
01076      * 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.
01077      * The idea is that only some allowed actions like this is allowed depending on the configured TypoScript.
01078      *
01079      * @return  string      HTML content displaying the status of the action
01080      */
01081     function procesSetFixed()   {
01082         if ($this->conf['setfixed'])    {
01083             $theUid = intval($this->recUid);
01084             $origArr = $GLOBALS['TSFE']->sys_page->getRawRecord($this->theTable,  $theUid);
01085             $fD = t3lib_div::_GP('fD');
01086             $sFK = t3lib_div::_GP('sFK');
01087 
01088             $fieldArr=array();
01089             if (is_array($fD) || $sFK=='DELETE')    {
01090                 if (is_array($fD))  {
01091                     foreach ($fD as $field => $value) {
01092                         $origArr[$field]=$value;
01093                         $fieldArr[]=$field;
01094                     }
01095                 }
01096                 $theCode = $this->setfixedHash($origArr,$origArr['_FIELDLIST']);
01097                 if (!strcmp($this->authCode,$theCode))  {
01098                     if ($sFK=='DELETE') {
01099                         $this->cObj->DBgetDelete($this->theTable, $theUid, TRUE);
01100                     } else {
01101                         $newFieldList = implode(',',array_intersect(t3lib_div::trimExplode(',',$this->fieldList),t3lib_div::trimExplode(',',implode($fieldArr,','),1)));
01102                         $this->cObj->DBgetUpdate($this->theTable, $theUid, $fD, $newFieldList, TRUE);
01103                         $this->currentArr = $GLOBALS['TSFE']->sys_page->getRawRecord($this->theTable,$theUid);
01104                         $this->userProcess_alt($this->conf['setfixed.']['userFunc_afterSave'],$this->conf['setfixed.']['userFunc_afterSave.'],array('rec'=>$this->currentArr, 'origRec'=>$origArr));
01105                     }
01106 
01107                         // Outputting template
01108                     $this->markerArray = $this->cObj->fillInMarkerArray($this->markerArray, $origArr, '', TRUE, 'FIELD_', $this->recInMarkersHSC);
01109                     $content = $this->getPlainTemplate('###TEMPLATE_SETFIXED_OK_'.$sFK.'###');
01110                     if (!$content)  {$content = $this->getPlainTemplate('###TEMPLATE_SETFIXED_OK###');}
01111 
01112                         // Compiling email
01113                     $this->compileMail(
01114                         'SETFIXED_'.$sFK,
01115                         array($origArr),
01116                         $origArr[$this->conf['email.']['field']],
01117                         $this->conf['setfixed.']
01118                     );
01119                         // Clearing cache if set:
01120                     $this->clearCacheIfSet();
01121                 } else $content = $this->getPlainTemplate('###TEMPLATE_SETFIXED_FAILED###');
01122             } else $content = $this->getPlainTemplate('###TEMPLATE_SETFIXED_FAILED###');
01123         }
01124         return $content;
01125     }
01126 
01127 
01128 
01129 
01130 
01131 
01132 
01133 
01134 
01135 
01136 
01137 
01138 
01139 
01140 
01141 
01142 
01143 
01144 
01145 
01146 
01147 
01148 
01149     /*****************************************
01150      *
01151      * Template processing functions
01152      *
01153      *****************************************/
01154 
01155 
01156 
01157     /**
01158      * Remove required parts from template code string
01159      *   Works like this:
01160      *       - 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.
01161      *       - These subparts are all removed, except if the field is listed in $failure string!
01162      *
01163      *      Only fields that are found in $this->requiredArr is processed.
01164      *
01165      * @param   string      The template HTML code
01166      * @param   string      Comma list of fields which has errors (and therefore should not be removed)
01167      * @return  string      The processed template HTML code
01168      */
01169     function removeRequired($templateCode,$failure) {
01170         foreach ($this->requiredArr as $theField) {
01171             if (!t3lib_div::inList($failure,$theField)) {
01172                 $templateCode = $this->cObj->substituteSubpart($templateCode, '###SUB_REQUIRED_FIELD_'.$theField.'###', '');
01173             }
01174         }
01175         return $templateCode;
01176     }
01177 
01178     /**
01179      * Returns template subpart HTML code for the key given
01180      *
01181      * @param   string      Subpart marker to return subpart for.
01182      * @param   array       Optional data record array. If set, then all fields herein will also be substituted if found as markers in the template
01183      * @return  string      The subpart with all markers found in current $this->markerArray substituted.
01184      * @see tslib_cObj::fillInMarkerArray()
01185      */
01186     function getPlainTemplate($key,$r='')   {
01187         if ($this->conf['debug'])   debug('getPlainTemplate(): '.$key,1);
01188         $templateCode = $this->cObj->getSubpart($this->templateCode, $key);
01189         $this->setCObjects($templateCode,is_array($r)?$r:array());
01190         return  $this->cObj->substituteMarkerArray(
01191                 $templateCode,
01192                 is_array($r) ? $this->cObj->fillInMarkerArray($this->markerArray, $r, '', TRUE, 'FIELD_', $this->recInMarkersHSC) : $this->markerArray
01193             );
01194     }
01195 
01196     /**
01197      * Modifies input array for passing on to tslib_cObj::getUpdateJS() which produces some JavaScript for form evaluation or the like.
01198      *
01199      * @param   array       The data array
01200      * @return  array       The processed input array
01201      * @see displayCreateScreen(), displayEditForm(), tslib_cObj::getUpdateJS()
01202      */
01203     function modifyDataArrForFormUpdate($inputArr)  {
01204         if (is_array($this->conf[$this->cmdKey.'.']['evalValues.']))    {
01205             foreach ($this->conf[$this->cmdKey.'.']['evalValues.'] as $theField => $theValue) {
01206                 $listOfCommands = t3lib_div::trimExplode(',',$theValue,1);
01207                 foreach ($listOfCommands as $cmd) {
01208                     $cmdParts = preg_split('/\[|\]/', $cmd);    // Point is to enable parameters after each command enclosed in brackets [..]. These will be in position 1 in the array.
01209                     $theCmd = trim($cmdParts[0]);
01210                     switch($theCmd) {
01211                         case 'twice':
01212                             if (isset($inputArr[$theField]))    {
01213                                 if (!isset($inputArr[$theField.'_again']))  {
01214                                     $inputArr[$theField.'_again'] = $inputArr[$theField];
01215                                 }
01216                                 $this->additionalUpdateFields.=','.$theField.'_again';
01217                             }
01218                         break;
01219                     }
01220                 }
01221             }
01222         }
01223         if (is_array($this->conf['parseValues.']))  {
01224             foreach ($this->conf['parseValues.'] as $theField => $theValue) {
01225                 $listOfCommands = t3lib_div::trimExplode(',',$theValue,1);
01226                 foreach ($listOfCommands as $cmd) {
01227                     $cmdParts = preg_split('/\[|\]/', $cmd);    // Point is to enable parameters after each command enclosed in brackets [..]. These will be in position 1 in the array.
01228                     $theCmd = trim($cmdParts[0]);
01229                     switch($theCmd) {
01230                         case 'multiple':
01231                             if (isset($inputArr[$theField]) && !$this->isPreview()) {
01232                                 $inputArr[$theField] = explode(',',$inputArr[$theField]);
01233                             }
01234                         break;
01235                         case 'checkArray':
01236                             if ($inputArr[$theField] && !$this->isPreview())    {
01237                                 for($a=0;$a<=30;$a++)   {
01238                                     if ($inputArr[$theField] & pow(2,$a))   {
01239                                         $alt_theField = $theField.']['.$a;
01240                                         $inputArr[$alt_theField] = 1;
01241                                         $this->additionalUpdateFields.=','.$alt_theField;
01242                                     }
01243                                 }
01244                             }
01245                         break;
01246                     }
01247                 }
01248             }
01249         }
01250 
01251 
01252         $inputArr = $this->userProcess_alt(
01253             $this->conf['userFunc_updateArray'],
01254             $this->conf['userFunc_updateArray.'],
01255             $inputArr
01256         );
01257 
01258         return $this->escapeHTML($inputArr);
01259     }
01260 
01261     /**
01262      * 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.
01263      *
01264      * @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!
01265      * @param   array       An alternative data record array (if empty then $this->dataArr is used)
01266      * @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.
01267      * @param   string      Optional prefix to set for the marker strings.
01268      * @return  array       The processed $markerArray (if given).
01269      */
01270     function setCObjects($templateCode,$currentArr=array(),$markerArray='',$specialPrefix='')   {
01271         if (is_array($this->conf['cObjects.'])) {
01272 
01273             foreach ($this->conf['cObjects.'] as $theKey => $theConf) {
01274                 if (!strstr($theKey,'.'))   {
01275                     if (strstr($templateCode,'###'.$specialPrefix.'CE_'.$theKey.'###')) {
01276                         $cObjCode = $this->cObj->cObjGetSingle($this->conf['cObjects.'][$theKey], $this->conf['cObjects.'][$theKey.'.'], 'cObjects.'.$theKey);
01277 
01278                         if (!is_array($markerArray))    {
01279                             $this->markerArray['###'.$specialPrefix.'CE_'.$theKey.'###'] = $cObjCode;
01280                         } else {
01281                             $markerArray['###'.$specialPrefix.'CE_'.$theKey.'###'] = $cObjCode;
01282                         }
01283                     }
01284                     if (strstr($templateCode,'###'.$specialPrefix.'PCE_'.$theKey.'###'))    {
01285                         $local_cObj =t3lib_div::makeInstance('tslib_cObj');
01286                         $local_cObj->start(count($currentArr)?$currentArr:$this->dataArr,$this->theTable);
01287                         $cObjCode = $local_cObj->cObjGetSingle($this->conf['cObjects.'][$theKey], $this->conf['cObjects.'][$theKey.'.'], 'cObjects.'.$theKey);
01288 
01289                         if (!is_array($markerArray))    {
01290                             $this->markerArray['###'.$specialPrefix.'PCE_'.$theKey.'###'] = $cObjCode;
01291                         } else {
01292                             $markerArray['###'.$specialPrefix.'PCE_'.$theKey.'###'] = $cObjCode;
01293                         }
01294                     }
01295                 }
01296             }
01297         }
01298         return $markerArray;
01299     }
01300 
01301 
01302 
01303 
01304 
01305 
01306 
01307 
01308 
01309 
01310 
01311 
01312 
01313 
01314 
01315 
01316 
01317 
01318 
01319     /*****************************************
01320      *
01321      * Emailing
01322      *
01323      *****************************************/
01324 
01325     /**
01326      * Sends info mail to user
01327      *
01328      * @return  string      HTML content message
01329      * @see init(),compileMail(), sendMail()
01330      */
01331     function sendInfoMail() {
01332         if ($this->conf['infomail'] && $this->conf['email.']['field'])  {
01333             $fetch = t3lib_div::_GP('fetch');
01334             if ($fetch) {
01335                     // Getting infomail config.
01336                 $key= trim(t3lib_div::_GP('key'));
01337                 if (is_array($this->conf['infomail.'][$key.'.']))       {
01338                     $config = $this->conf['infomail.'][$key.'.'];
01339                 } else {
01340                     $config = $this->conf['infomail.']['default.'];
01341                 }
01342                 $pidLock='';
01343                 if (!$config['dontLockPid'])    {
01344                     $pidLock='AND pid IN ('.$this->thePid.') ';
01345                 }
01346 
01347                     // Getting records
01348                 if (t3lib_div::testInt($fetch)) {
01349                     $DBrows = $GLOBALS['TSFE']->sys_page->getRecordsByField($this->theTable,'uid',$fetch,$pidLock,'','','1');
01350                 } elseif ($fetch) { // $this->conf['email.']['field'] must be a valid field in the table!
01351                     $DBrows = $GLOBALS['TSFE']->sys_page->getRecordsByField($this->theTable,$this->conf['email.']['field'],$fetch,$pidLock,'','','100');
01352                 }
01353 
01354                     // Processing records
01355                 if (is_array($DBrows))  {
01356                     $recipient = $DBrows[0][$this->conf['email.']['field']];
01357                     $this->compileMail($config['label'], $DBrows, $recipient, $this->conf['setfixed.']);
01358                 } elseif ($this->cObj->checkEmail($fetch)) {
01359                     $this->sendMail($fetch, '', trim($this->cObj->getSubpart($this->templateCode, '###'.$this->emailMarkPrefix.'NORECORD###')));
01360                 }
01361 
01362                 $content = $this->getPlainTemplate('###TEMPLATE_INFOMAIL_SENT###');
01363             } else {
01364                 $content = $this->getPlainTemplate('###TEMPLATE_INFOMAIL###');
01365             }
01366         } else $content='Error: infomail option is not available or emailField is not setup in TypoScript';
01367         return $content;
01368     }
01369 
01370     /**
01371      * 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.
01372      *
01373      * @param   string      A key which together with $this->emailMarkPrefix will identify the part from the template code to use for the email.
01374      * @param   array       An array of records which fields are substituted in the templates
01375      * @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.
01376      * @param   array       Additional fields to set in the markerArray used in the substitution process
01377      * @return  void
01378      */
01379     function compileMail($key, $DBrows, $recipient, $setFixedConfig=array())    {
01380         $GLOBALS['TT']->push('compileMail');
01381         $mailContent='';
01382         $key = $this->emailMarkPrefix.$key;
01383 
01384         $userContent['all'] = trim($this->cObj->getSubpart($this->templateCode, '###'.$key.'###'));
01385         $adminContent['all'] = trim($this->cObj->getSubpart($this->templateCode, '###'.$key.'-ADMIN###'));
01386         $userContent['rec'] = $this->cObj->getSubpart($userContent['all'], '###SUB_RECORD###');
01387         $adminContent['rec'] = $this->cObj->getSubpart($adminContent['all'], '###SUB_RECORD###');
01388 
01389         foreach ($DBrows as $r) {
01390             $markerArray = $this->cObj->fillInMarkerArray($this->markerArray, $r,'',0);
01391             $markerArray = $this->setCObjects($userContent['rec'].$adminContent['rec'],$r,$markerArray,'ITEM_');
01392             $markerArray['###SYS_AUTHCODE###'] = $this->authCode($r);
01393             $markerArray = $this->setfixed($markerArray, $setFixedConfig, $r);
01394 
01395             if ($userContent['rec'])    $userContent['accum'] .=$this->cObj->substituteMarkerArray($userContent['rec'], $markerArray);
01396             if ($adminContent['rec'])   $adminContent['accum'].=$this->cObj->substituteMarkerArray($adminContent['rec'], $markerArray);
01397         }
01398 
01399         if ($userContent['all'])    $userContent['final'] .=$this->cObj->substituteSubpart($userContent['all'], '###SUB_RECORD###', $userContent['accum']);
01400         if ($adminContent['all'])   $adminContent['final'].=$this->cObj->substituteSubpart($adminContent['all'], '###SUB_RECORD###', $adminContent['accum']);
01401 
01402         if (t3lib_div::testInt($recipient)) {
01403             $fe_userRec = $GLOBALS['TSFE']->sys_page->getRawRecord('fe_users',$recipient);
01404             $recipient=$fe_userRec['email'];
01405         }
01406 
01407         $GLOBALS['TT']->setTSlogMessage('Template key: ###'.$key.'###, userContentLength: '.strlen($userContent['final']).', adminContentLength: '.strlen($adminContent['final']));
01408 
01409         $this->sendMail($recipient, $this->conf['email.']['admin'], $userContent['final'], $adminContent['final']);
01410         $GLOBALS['TT']->pull();
01411     }
01412 
01413     /**
01414      * Actually sends the requested mails (through $this->cObj->sendNotifyEmail or through $this->sendHTMLMail).
01415      * As of TYPO3 v4.3 with autoloader, a check for $GLOBALS['TSFE']->config['config']['incT3Lib_htmlmail'] has been included for backwards compatibility.
01416      *
01417      * @param   string      Recipient email address (or list)
01418      * @param   string      Possible "admin" email address. Will enable sending of admin emails if also $adminContent is provided
01419      * @param   string      Content for the regular email to user
01420      * @param   string      Content for the admin email to administrator
01421      * @return  void
01422      * @access private
01423      * @see compileMail(), sendInfoMail()
01424      */
01425     function sendMail($recipient, $admin, $content='', $adminContent='')    {
01426             // Admin mail:
01427         if ($admin && $adminContent)    {
01428             if (!$this->isHTMLContent($adminContent) || !$GLOBALS['TSFE']->config['config']['incT3Lib_htmlmail']) {
01429                 $admMail = $this->cObj->sendNotifyEmail(
01430                                     strip_tags($adminContent),
01431                                     $admin,
01432                                     '',
01433                                     $this->conf['email.']['from'],
01434                                     $this->conf['email.']['fromName'],
01435                                     $recipient
01436                             );
01437             } else {
01438                 $this->sendHTMLMail($adminContent,
01439                                     $admin,
01440                                     '',
01441                                     $this->conf['email.']['from'],
01442                                     $this->conf['email.']['fromName'],
01443                                     $recipient
01444                             );
01445             }
01446         }
01447             // user mail:
01448         if (!$this->isHTMLContent($content) || !$GLOBALS['TSFE']->config['config']['incT3Lib_htmlmail']) {
01449             $this->cObj->sendNotifyEmail(
01450                                 strip_tags($content),
01451                                 $recipient,
01452                                 '',         // ($admMail ? '' : $admin),        // If the special administration mail was not found and send, the regular is...
01453                                 $this->conf['email.']['from'],
01454                                 $this->conf['email.']['fromName']
01455                         );
01456         } else {
01457             $this->sendHTMLMail($content,
01458                                 $recipient,
01459                                 '',         // ($admMail ? '' : $admin),        // If the special administration mail was not found and send, the regular is...
01460                                 $this->conf['email.']['from'],
01461                                 $this->conf['email.']['fromName']
01462                         );
01463         }
01464     }
01465 
01466     /**
01467      * Detects if content is HTML (looking for <html> tag as first and last in string)
01468      *
01469      * @param   string      Content string to test
01470      * @return  boolean     Returns true if the content begins and ends with <html></html>-tags
01471      */
01472     function isHTMLContent($c)  {
01473         $c = trim($c);
01474         $first = strtolower(substr($c,0,6));
01475         $last = strtolower(substr($c,-7));
01476         if ($first.$last=='<html></html>')  return 1;
01477     }
01478 
01479     /**
01480      * Sending HTML email, using same parameters as tslib_cObj::sendNotifyEmail()
01481      *
01482      * @param   string      The message content. If blank, no email is sent.
01483      * @param   string      Comma list of recipient email addresses
01484      * @param   string      IGNORE this parameter
01485      * @param   string      "From" email address
01486      * @param   string      Optional "From" name
01487      * @param   string      Optional "Reply-To" header email address.
01488      * @return  void
01489      * @access private
01490      * @see sendMail(), tslib_cObj::sendNotifyEmail()
01491      */
01492     function sendHTMLMail($content,$recipient,$dummy,$fromEmail,$fromName,$replyTo='')  {
01493         if (trim($recipient) && trim($content)) {
01494             $parts = preg_spliti('<title>|</title>', $content, 3);
01495             $subject = trim($parts[1]) ? trim($parts[1]) : 'TYPO3 FE Admin message';
01496 
01497             $Typo3_htmlmail = t3lib_div::makeInstance('t3lib_htmlmail');
01498             $Typo3_htmlmail->start();
01499             $Typo3_htmlmail->useBase64();
01500 
01501             $Typo3_htmlmail->subject = $subject;
01502             $Typo3_htmlmail->from_email = $fromEmail;
01503             $Typo3_htmlmail->from_name = $fromName;
01504             $Typo3_htmlmail->replyto_email = $replyTo ? $replyTo : $fromEmail;
01505             $Typo3_htmlmail->replyto_name = $replyTo ? '' : $fromName;
01506             $Typo3_htmlmail->organisation = '';
01507             $Typo3_htmlmail->priority = 3;
01508 
01509                 // HTML
01510             $Typo3_htmlmail->theParts['html']['content'] = $content;    // Fetches the content of the page
01511             $Typo3_htmlmail->theParts['html']['path'] = '';
01512             $Typo3_htmlmail->extractMediaLinks();
01513             $Typo3_htmlmail->extractHyperLinks();
01514             $Typo3_htmlmail->fetchHTMLMedia();
01515             $Typo3_htmlmail->substMediaNamesInHTML(0);  // 0 = relative
01516             $Typo3_htmlmail->substHREFsInHTML();
01517             $Typo3_htmlmail->setHTML($Typo3_htmlmail->encodeMsg($Typo3_htmlmail->theParts['html']['content']));
01518 
01519                 // PLAIN
01520             $Typo3_htmlmail->addPlain('');
01521 
01522                 // SET Headers and Content
01523             $Typo3_htmlmail->setHeaders();
01524             $Typo3_htmlmail->setContent();
01525             $Typo3_htmlmail->setRecipient($recipient);
01526 
01527             $Typo3_htmlmail->sendtheMail();
01528         }
01529     }
01530 
01531 
01532 
01533 
01534 
01535 
01536 
01537 
01538 
01539 
01540 
01541 
01542 
01543 
01544 
01545 
01546 
01547 
01548 
01549 
01550 
01551 
01552 
01553 
01554     /*****************************************
01555      *
01556      * Various helper functions
01557      *
01558      *****************************************/
01559 
01560 
01561     /**
01562      * 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.
01563      * This allows to authenticate editing without having a fe_users login
01564      * Uses $this->authCode which is set in init() by "t3lib_div::_GP('aC');"
01565      *
01566      * @param   array       The data array for which to evaluate authentication
01567      * @return  boolean     True if authenticated OK
01568      * @see authCode(), init()
01569      */
01570     function aCAuth($r) {
01571         if ($this->authCode && !strcmp($this->authCode,$this->authCode($r)))    {
01572             return true;
01573         }
01574     }
01575 
01576     /**
01577      * Creating authentication hash string based on input record and the fields listed in TypoScript property "authcodeFields"
01578      *
01579      * @param   array       The data record
01580      * @param   string      Additional string to include in the hash
01581      * @return  string      Hash string of $this->codeLength (if TypoScript "authcodeFields" was set)
01582      * @see aCAuth()
01583      */
01584     function authCode($r,$extra='') {
01585         $l=$this->codeLength;
01586         if ($this->conf['authcodeFields'])  {
01587             $fieldArr = t3lib_div::trimExplode(',', $this->conf['authcodeFields'], 1);
01588             $value='';
01589             foreach ($fieldArr as $field) {
01590                 $value.=$r[$field].'|';
01591             }
01592             $value.=$extra.'|'.$this->conf['authcodeFields.']['addKey'];
01593             if ($this->conf['authcodeFields.']['addDate'])  {
01594                 $value.='|'.date($this->conf['authcodeFields.']['addDate']);
01595             }
01596             $value.=$GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'];
01597             return substr(md5($value), 0,$l);
01598         }
01599     }
01600 
01601     /**
01602      * Adding keys to the marker array with "setfixed" GET parameters
01603      *
01604      * @param   array       Marker-array to modify/add a key to.
01605      * @param   array       TypoScript properties configuring "setfixed" for the plugin. Basically this is $this->conf['setfixed.'] passed along.
01606      * @param   array       The data record
01607      * @return  array       Processed $markerArray
01608      * @see compileMail()
01609      */
01610     function setfixed($markerArray, $setfixed, $r)  {
01611         if (is_array($setfixed))    {
01612             foreach ($setfixed as $theKey => $data) {
01613                 if (!strcmp($theKey,'DELETE'))  {
01614                     $recCopy = $r;
01615                     $string='&cmd=setfixed&sFK='.rawurlencode($theKey).'&rU='.$r['uid'];
01616                     $string.='&aC='.$this->setfixedHash($recCopy,$data['_FIELDLIST']);
01617                     $markerArray['###SYS_SETFIXED_DELETE###'] = $string;
01618                     $markerArray['###SYS_SETFIXED_HSC_DELETE###'] = htmlspecialchars($string);
01619                 } elseif (strstr($theKey,'.'))  {
01620                     $theKey = substr($theKey,0,-1);
01621                     if (is_array($data))    {
01622                         $recCopy = $r;
01623                         $string='&cmd=setfixed&sFK='.rawurlencode($theKey).'&rU='.$r['uid'];
01624                         foreach ($data as $fieldName => $fieldValue) {
01625                             $string.='&fD%5B'.$fieldName.'%5D='.rawurlencode($fieldValue);
01626                             $recCopy[$fieldName]=$fieldValue;
01627                         }
01628                         $string.='&aC='.$this->setfixedHash($recCopy,$data['_FIELDLIST']);
01629                         $markerArray['###SYS_SETFIXED_'.$theKey.'###'] = $string;
01630                         $markerArray['###SYS_SETFIXED_HSC_'.$theKey.'###'] = htmlspecialchars($string);
01631                     }
01632                 }
01633             }
01634         }
01635         return $markerArray;
01636     }
01637 
01638     /**
01639      * Creating hash string for setFixed. Much similar to authCode()
01640      *
01641      * @param   array       The data record
01642      * @param   string      List of fields to use
01643      * @return  string      Hash string of $this->codeLength (if TypoScript "authcodeFields" was set)
01644      * @see setfixed(),authCode()
01645      */
01646     function setfixedHash($recCopy,$fields='')  {
01647         if ($fields)    {
01648             $fieldArr = t3lib_div::trimExplode(',',$fields,1);
01649             foreach ($fieldArr as $k => $v) {
01650                 $recCopy_temp[$k]=$recCopy[$v];
01651             }
01652         } else {
01653             $recCopy_temp=$recCopy;
01654         }
01655         $encStr = implode('|',$recCopy_temp).'|'.$this->conf['authcodeFields.']['addKey'].'|'.$GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'];
01656         $hash = substr(md5($encStr),0,$this->codeLength);
01657         return $hash;
01658     }
01659 
01660 
01661     /**
01662      * Returns true if preview display is on.
01663      *
01664      * @return  boolean
01665      */
01666     function isPreview()    {
01667         return ($this->conf[$this->cmdKey.'.']['preview'] && $this->preview);
01668     }
01669 
01670     /**
01671      * Creates an instance of class "t3lib_basicFileFunctions" in $this->fileFunc (if not already done)
01672      *
01673      * @return  void
01674      */
01675     function createFileFuncObj()    {
01676         if (!$this->fileFunc)   {
01677             $this->fileFunc = t3lib_div::makeInstance('t3lib_basicFileFunctions');
01678         }
01679     }
01680 
01681     /**
01682      * If TypoScript property clearCacheOfPages is set then all page ids in this value will have their cache cleared
01683      *
01684      * @return  void
01685      */
01686     function clearCacheIfSet()  {
01687         if ($this->conf['clearCacheOfPages'])   {
01688             $cc_pidList = $GLOBALS['TYPO3_DB']->cleanIntList($this->conf['clearCacheOfPages']);
01689             $GLOBALS['TSFE']->clearPageCacheContent_pidList($cc_pidList);
01690         }
01691     }
01692 
01693     /**
01694      * 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
01695      *
01696      * @param   string      Field name
01697      * @param   string      Command identifier string
01698      * @param   string      Alternative label, shown if no other error string was found
01699      * @return  string      The error message string
01700      */
01701     function getFailure($theField, $theCmd, $label) {
01702         return isset($this->conf['evalErrors.'][$theField.'.'][$theCmd]) ? $this->conf['evalErrors.'][$theField.'.'][$theCmd] : $label;
01703     }
01704 
01705     /**
01706      * Will escape HTML-tags
01707      *
01708      * @param   mixed       The unescaped data
01709      * @return  mixed       The processed input data
01710      */
01711     function escapeHTML($var)   {
01712         if (is_array($var)) {
01713             foreach ($var as $k => $value) {
01714                 $var[$k] = $this->escapeHTML($var[$k]);
01715             }
01716         } else {
01717             $var = htmlspecialchars($var, ENT_NOQUOTES);
01718         }
01719         return $var;
01720     }
01721 }
01722 
01723 
01724 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['media/scripts/fe_adminLib.inc'])) {
01725     include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['media/scripts/fe_adminLib.inc']);
01726 }
01727 ?>