PageRenderTime 33ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/typo3/sysext/statictemplates/media/scripts/fe_adminLib.inc

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