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