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