PageRenderTime 64ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/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

Large files files are truncated, but you can click here to view the full file

  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. }

Large files files are truncated, but you can click here to view the full file