Follow-up for feature #10374: Add helper function for additional frontend editing...
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_frontendedit.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2008 Jeff Segars <jeff@webempoweredchurch.org>
6 * (c) 2008 David Slayback <dave@webempoweredchurch.org>
7 * All rights reserved
8 *
9 * This script is part of the TYPO3 project. The TYPO3 project is
10 * free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * The GNU General Public License can be found at
16 * http://www.gnu.org/copyleft/gpl.html.
17 * A copy is found in the textfile GPL.txt and important notices to the license
18 * from the author is found in LICENSE.txt distributed with these scripts.
19 *
20 *
21 * This script is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * This copyright notice MUST APPEAR in all copies of the script!
27 ***************************************************************/
28 /**
29 * Controller class for frontend editing.
30 *
31 * $Id$
32 *
33 * @author Jeff Segars <jeff@webempoweredchurch.org>
34 * @author David Slayback <dave@webempoweredchurch.org>
35 * @package TYPO3
36 * @subpackage t3lib
37 */
38 class t3lib_frontendedit {
39
40 /**
41 * TCEmain object.
42 *
43 * @var t3lib_tcemain
44 */
45 protected $tce;
46
47
48 /**
49 * Force preview?
50 *
51 * @var boolean
52 */
53 protected $ext_forcePreview = false;
54
55 /**
56 * Comma separated list of page UIDs to be published.
57 *
58 * @var string
59 */
60 protected $extPublishList = '';
61
62 /**
63 * Creates and initializes the TCEmain object.
64 *
65 * @return void
66 */
67 public function __construct() {
68 $this->tce = t3lib_div::makeInstance('t3lib_TCEmain');
69 $this->tce->stripslashes_values=0;
70 }
71
72 /**
73 * Initializes configuration options.
74 *
75 * @return void
76 */
77 public function initConfigOptions() {
78 $this->saveConfigOptions();
79 $this->TSFE_EDIT = t3lib_div::_POST('TSFE_EDIT');
80
81 // Setting some values based on the admin panel
82 $GLOBALS['TSFE']->forceTemplateParsing = $this->extGetFeAdminValue('tsdebug', 'forceTemplateParsing');
83 $GLOBALS['TSFE']->displayEditIcons = $this->extGetFeAdminValue('edit', 'displayIcons');
84 $GLOBALS['TSFE']->displayFieldEditIcons = $this->extGetFeAdminValue('edit', 'displayFieldIcons');
85
86 if ($this->extGetFeAdminValue('tsdebug', 'displayQueries')) {
87 if ($GLOBALS['TYPO3_DB']->explainOutput == 0) { // do not override if the value is already set in t3lib_db
88 // Enable execution of EXPLAIN SELECT queries
89 $GLOBALS['TYPO3_DB']->explainOutput = 3;
90 }
91 }
92
93 if (t3lib_div::_GP('ADMCMD_editIcons')) {
94 $GLOBALS['TSFE']->displayFieldEditIcons=1;
95 $GLOBALS['BE_USER']->uc['TSFE_adminConfig']['edit_editNoPopup']=1;
96 }
97
98 if (t3lib_div::_GP('ADMCMD_simUser')) {
99 $GLOBALS['BE_USER']->uc['TSFE_adminConfig']['preview_simulateUserGroup']=intval(t3lib_div::_GP('ADMCMD_simUser'));
100 $this->ext_forcePreview = true;
101 }
102
103 if (t3lib_div::_GP('ADMCMD_simTime')) {
104 $GLOBALS['BE_USER']->uc['TSFE_adminConfig']['preview_simulateDate']=intval(t3lib_div::_GP('ADMCMD_simTime'));
105 $this->ext_forcePreview = true;
106 }
107
108 // Include classes for editing IF editing module in Admin Panel is open
109 if (($this->isAdminModuleEnabled('edit') && $this->isAdminModuleOpen('edit')) || $GLOBALS['TSFE']->displayEditIcons == 1) {
110 $GLOBALS['TSFE']->includeTCA();
111 if ($this->isEditAction()) {
112 require_once (PATH_t3lib . 'class.t3lib_tcemain.php');
113 $this->editAction();
114 }
115
116 if ($this->isEditFormShown()) {
117 require_once(PATH_t3lib . 'class.t3lib_tceforms.php');
118 require_once(PATH_t3lib . 'class.t3lib_iconworks.php');
119 require_once(PATH_t3lib . 'class.t3lib_loaddbgroup.php');
120 require_once(PATH_t3lib . 'class.t3lib_transferdata.php');
121 }
122 }
123
124 if ($GLOBALS['TSFE']->forceTemplateParsing || $GLOBALS['TSFE']->displayEditIcons || $GLOBALS['TSFE']->displayFieldEditIcons) {
125 $GLOBALS['TSFE']->set_no_cache();
126 }
127 }
128
129
130 /**
131 * Delegates to the appropriate view and renders the admin panel content.
132 *
133 * @return string.
134 */
135 public function displayAdmin() {
136 $content = '';
137 $adminClass = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/classes/class.frontendedit.php']['admin'];
138 if ($adminClass && !$GLOBALS['BE_USER']->extAdminConfig['hide'] && $GLOBALS['TSFE']->config['config']['admPanel']) {
139 $admin = &t3lib_div::getUserObj($adminClass);
140 if (is_object($admin)) {
141 $content = $admin->display();
142 }
143 }
144
145 return $content;
146 }
147
148 /**
149 * Generates the "edit panels" which can be shown for a page or records on a page when the Admin Panel is enabled for a backend users surfing the frontend.
150 * With the "edit panel" the user will see buttons with links to editing, moving, hiding, deleting the element
151 * This function is used for the cObject EDITPANEL and the stdWrap property ".editPanel"
152 *
153 * @param string A content string containing the content related to the edit panel. For cObject "EDITPANEL" this is empty but not so for the stdWrap property. The edit panel is appended to this string and returned.
154 * @param array TypoScript configuration properties for the editPanel
155 * @param string The "table:uid" of the record being shown. If empty string then $this->currentRecord is used. For new records (set by $conf['newRecordFromTable']) it's auto-generated to "[tablename]:NEW"
156 * @param array Alternative data array to use. Default is $this->data
157 * @return string The input content string with the editPanel appended. This function returns only an edit panel appended to the content string if a backend user is logged in (and has the correct permissions). Otherwise the content string is directly returned.
158 * @link http://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=270&tx_extrepmgm_pi1[tocEl]=375&cHash=7d8915d508
159 */
160 public function displayEditPanel($content, array $conf, $currentRecord, array $dataArray) {
161 if ($conf['newRecordFromTable']) {
162 $currentRecord = $conf['newRecordFromTable'] . ':NEW';
163 $conf['allow'] = 'new';
164 }
165
166 list($table, $uid) = explode(':', $currentRecord);
167
168 // Page ID for new records, 0 if not specified
169 $newRecordPid = intval($conf['newRecordInPid']);
170 if (!$conf['onlyCurrentPid'] || $dataArray['pid'] == $GLOBALS['TSFE']->id) {
171 if ($table=='pages') {
172 $newUid = $uid;
173 } else {
174 if ($conf['newRecordFromTable']) {
175 $newUid = $GLOBALS['TSFE']->id;
176 if ($newRecordPid) {
177 $newUid = $newRecordPid;
178 }
179 } else {
180 $newUid = -1 * $uid;
181 }
182 }
183 }
184
185 if ($GLOBALS['TSFE']->displayEditIcons && $table && $this->allowedToEdit($table, $dataArray, $conf) && $this->allowedToEditLanguage($table, $dataArray)) {
186 $editClass = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/classes/class.frontendedit.php']['edit'];
187 if ($editClass) {
188 $edit = &t3lib_div::getUserObj($editClass, false);
189 if (is_object($edit)) {
190 $allowedActions = $this->getAllowedEditActions($table, $conf, $dataArray['pid']);
191 $content = $edit->editPanel($content, $conf, $currentRecord, $dataArray, $table, $allowedActions, $newUid, $this->getHiddenFields($dataArray));
192 }
193 }
194 }
195
196 return $content;
197 }
198
199 /**
200 * Adds an edit icon to the content string. The edit icon links to alt_doc.php with proper parameters for editing the table/fields of the context.
201 * This implements TYPO3 context sensitive editing facilities. Only backend users will have access (if properly configured as well).
202 *
203 * @param string The content to which the edit icons should be appended
204 * @param string The parameters defining which table and fields to edit. Syntax is [tablename]:[fieldname],[fieldname],[fieldname],... OR [fieldname],[fieldname],[fieldname],... (basically "[tablename]:" is optional, default table is the one of the "current record" used in the function). The fieldlist is sent as "&columnsOnly=" parameter to alt_doc.php
205 * @param array TypoScript properties for configuring the edit icons.
206 * @param string The "table:uid" of the record being shown. If empty string then $this->currentRecord is used. For new records (set by $conf['newRecordFromTable']) it's auto-generated to "[tablename]:NEW"
207 * @param array Alternative data array to use. Default is $this->data
208 * @param string Additional URL parameters for the link pointing to alt_doc.php
209 * @return string The input content string, possibly with edit icons added (not necessarily in the end but just after the last string of normal content.
210 */
211
212 public function displayEditIcons($content, $params, array $conf=array(), $currentRecord = '', array $dataArray = array(), $addUrlParamStr = '') {
213 // Check incoming params:
214 list($currentRecordTable, $currentRecordUID) = explode(':', $currentRecord);
215 list($fieldList, $table) = array_reverse(t3lib_div::trimExplode(':', $params, 1)); // Reverse the array because table is optional
216 if (!$table) {
217 $table = $currentRecordTable;
218 } elseif ($table != $currentRecordTable) {
219 return $content; // If the table is set as the first parameter, and does not match the table of the current record, then just return.
220 }
221
222 $editUid = $dataArray['_LOCALIZED_UID'] ? $dataArray['_LOCALIZED_UID'] : $currentRecordUID;
223
224 // Edit icons imply that the editing action is generally allowed, assuming page and content element permissions permit it.
225 if (!array_key_exists('allow', $conf)) {
226 $conf['allow'] = 'edit';
227 }
228
229 if ($GLOBALS['TSFE']->displayFieldEditIcons && $table && $this->allowedToEdit($table, $dataArray, $conf) && $fieldList && $this->allowedToEditLanguage($table, $dataArray)) {
230 $editClass = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/classes/class.frontendedit.php']['edit'];
231 if ($editClass) {
232 $edit = &t3lib_div::getUserObj($editClass);
233 if (is_object($edit)) {
234 $content = $edit->editIcons($content, $params, $conf, $currentRecord, $dataArray, $addURLParamStr, $table, $editUid, $fieldList);
235 }
236 }
237 }
238
239 return $content;
240 }
241
242 /**
243 * Checks if a Admin Panel section ("module") is available for the user. If so, true is returned.
244 *
245 * @param string The module key, eg. "edit", "preview", "info" etc.
246 * @return boolean
247 */
248 public function isAdminModuleEnabled($key) {
249 // Returns true if the module checked is "preview" and the forcePreview flag is set.
250 if ($key=='preview' && $this->ext_forcePreview) {
251 return true;
252 }
253
254 // If key is not set, only "all" is checked
255 if ($GLOBALS['BE_USER']->extAdminConfig['enable.']['all']) {
256 return true;
257 }
258
259 if ($GLOBALS['BE_USER']->extAdminConfig['enable.'][$key]) {
260 return true;
261 }
262 }
263
264 /**
265 * Saves any change in settings made in the Admin Panel.
266 * Called from index_ts.php right after access check for the Admin Panel
267 *
268 * @return void
269 */
270 public function saveConfigOptions() {
271 $input = t3lib_div::_GP('TSFE_ADMIN_PANEL');
272 if (is_array($input)) {
273 // Setting
274 $GLOBALS['BE_USER']->uc['TSFE_adminConfig'] = array_merge(!is_array($GLOBALS['BE_USER']->uc['TSFE_adminConfig']) ? array() : $GLOBALS['BE_USER']->uc['TSFE_adminConfig'], $input); // Candidate for t3lib_div::array_merge() if integer-keys will some day make trouble...
275 unset($GLOBALS['BE_USER']->uc['TSFE_adminConfig']['action']);
276
277 // Actions:
278 if ($input['action']['clearCache'] && $this->isAdminModuleEnabled('cache')) {
279 $GLOBALS['BE_USER']->extPageInTreeInfo=array();
280 $theStartId = intval($input['cache_clearCacheId']);
281 $GLOBALS['TSFE']->clearPageCacheContent_pidList($GLOBALS['BE_USER']->extGetTreeList($theStartId, $this->extGetFeAdminValue('cache', 'clearCacheLevels'), 0, $GLOBALS['BE_USER']->getPagePermsClause(1)) . $theStartId);
282 }
283 if ($input['action']['publish'] && $this->isAdminModuleEnabled('publish')) {
284 $theStartId = intval($input['publish_id']);
285 $this->extPublishList = $GLOBALS['BE_USER']->extGetTreeList($theStartId, $this->extGetFeAdminValue('publish', 'levels'), 0, $GLOBALS['BE_USER']->getPagePermsClause(1)) . $theStartId;
286 }
287
288 // Saving
289 $GLOBALS['BE_USER']->writeUC();
290 }
291 $GLOBALS['TT']->LR = $this->extGetFeAdminValue('tsdebug', 'LR');
292
293 if ($this->extGetFeAdminValue('cache', 'noCache')) {
294 $GLOBALS['TSFE']->set_no_cache();
295 }
296
297 // Hook for post processing the frontend admin configuration. Added with TYPO3 4.2, so naming is now incorrect but preserves compatibility.
298 // @deprecated since TYPO3 4.3
299 if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['extSaveFeAdminConfig-postProc'])) {
300 $_params = array('input' => &$input, 'pObj' => &$this);
301 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['extSaveFeAdminConfig-postProc'] as $_funcRef) {
302 t3lib_div::callUserFunction($_funcRef, $_params, $this);
303 }
304 }
305 }
306
307 /**
308 * Returns the value for a Admin Panel setting. You must specify both the module-key and the internal setting key.
309 *
310 * @param string Module key
311 * @param string Setting key
312 * @return string The setting value
313 */
314 public function extGetFeAdminValue($pre, $val='') {
315 // Check if module is enabled.
316 if ($this->isAdminModuleEnabled($pre)) {
317 // Exceptions where the values can be overridden from backend:
318 // deprecated
319 if ($pre . '_' . $val == 'edit_displayIcons' && $GLOBALS['BE_USER']->extAdminConfig['module.']['edit.']['forceDisplayIcons']) {
320 return true;
321 }
322 if ($pre . '_' . $val == 'edit_displayFieldIcons' && $GLOBALS['BE_USER']->extAdminConfig['module.']['edit.']['forceDisplayFieldIcons']) {
323 return true;
324 }
325
326 // override all settings with user TSconfig
327 if ($GLOBALS['BE_USER']->extAdminConfig['override.'][$pre . '.'][$val] && $val) {
328 return $GLOBALS['BE_USER']->extAdminConfig['override.'][$pre . '.'][$val];
329 }
330 if ($GLOBALS['BE_USER']->extAdminConfig['override.'][$pre]) {
331 return $GLOBALS['BE_USER']->extAdminConfig['override.'][$pre];
332 }
333
334 $retVal = $val ? $GLOBALS['BE_USER']->uc['TSFE_adminConfig'][$pre . '_' . $val] : 1;
335
336 if ($pre=='preview' && $this->ext_forcePreview) {
337 if (!$val) {
338 return true;
339 } else {
340 return $retVal;
341 }
342 }
343 // regular check:
344 if ($this->isAdminModuleOpen($pre)) { // See if the menu is expanded!
345 return $retVal;
346 }
347
348 // Hook for post processing the frontend admin configuration. Added with TYPO3 4.2, so naming is now incorrect but preserves compatibility.
349 // @deprecated since TYPO3 4.3
350 if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['extEditAction-postProc'])) {
351 $_params = array('cmd' => &$cmd, 'tce' => &$this->tce, 'pObj' => &$this);
352 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['extEditAction-postProc'] as $_funcRef) {
353 t3lib_div::callUserFunction($_funcRef, $_params, $this);
354 }
355 }
356 }
357 }
358
359 /**
360 * Enables the force preview option.
361 *
362 * @return void
363 */
364 public function forcePreview() {
365 $this->ext_forcePreview = true;
366 }
367
368 /**
369 * Returns the comma-separated list of page UIDs to be published.
370 *
371 * @return string
372 */
373 public function getExtPublishList() {
374 return $this->extPublishList;
375 }
376
377 /**
378 * Returns true if admin panel module is open
379 *
380 * @param string Module key
381 * @return boolean True, if the admin panel is open for the specified admin panel module key.
382 */
383 public function isAdminModuleOpen($pre) {
384 return $GLOBALS['BE_USER']->uc['TSFE_adminConfig']['display_top'] && $GLOBALS['BE_USER']->uc['TSFE_adminConfig']['display_' . $pre];
385 }
386
387 /*****************************************************
388 *
389 * Frontend Editing
390 *
391 ****************************************************/
392
393 /**
394 * Returns true if an edit-action is sent from the Admin Panel
395 *
396 * @return boolean
397 * @see index_ts.php
398 */
399 public function isEditAction() {
400 if (is_array($this->TSFE_EDIT)) {
401 if ($this->TSFE_EDIT['cancel']) {
402 unset($this->TSFE_EDIT['cmd']);
403 } else {
404 $cmd = (string) $this->TSFE_EDIT['cmd'];
405 if (($cmd != 'edit' || (is_array($this->TSFE_EDIT['data']) && ($this->TSFE_EDIT['update'] || $this->TSFE_EDIT['update_close']))) && $cmd != 'new') {
406 // $cmd can be a command like "hide" or "move". If $cmd is "edit" or "new" it's an indication to show the formfields. But if data is sent with update-flag then $cmd = edit is accepted because edit may be sendt because of .keepGoing flag.
407 return true;
408 }
409 }
410 }
411 return false;
412 }
413
414 /**
415 * Returns true if an edit form is shown on the page.
416 * Used from index_ts.php where a true return-value will result in classes etc. being included.
417 *
418 * @return boolean
419 * @see index_ts.php
420 */
421 public function isEditFormShown() {
422 if (is_array($this->TSFE_EDIT)) {
423 $cmd = (string) $this->TSFE_EDIT['cmd'];
424 if ($cmd == 'edit' || $cmd == 'new') {
425 return true;
426 }
427 }
428 }
429
430 /**
431 * Management of the on-page frontend editing forms and edit panels.
432 * Basically taking in the data and commands and passes them on to the proper classes as they should be.
433 *
434 * @return void
435 * @throws UnexpectedValueException if TSFE_EDIT[cmd] is not a valid command
436 * @see index_ts.php
437 */
438 public function editAction() {
439 // Commands:
440 list($table, $uid) = explode(':', $this->TSFE_EDIT['record']);
441 $cmd = $this->TSFE_EDIT['cmd'];
442
443 if ($cmd && $table && $uid && isset($GLOBALS['TCA'][$table])) {
444 // Hook for defining custom editing actions. Naming is incorrect, but preserves compatibility.
445 if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['extEditAction'])) {
446 $_params = array();
447 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['extEditAction'] as $_funcRef) {
448 t3lib_div::callUserFunction($_funcRef, $_params, $this);
449 }
450 }
451 // Perform the requested editing command.
452 if (is_callable(array($this, $cmd))) {
453 $this->$cmd($table, $uid);
454 } else {
455 throw new UnexpectedValueException(
456 'The specified frontend edit command (' . $cmd . ') is not valid.',
457 1225818120
458 );
459 }
460 }
461 // Data:
462 if (($this->TSFE_EDIT['doSave'] || $this->TSFE_EDIT['update'] || $this->TSFE_EDIT['update_close']) && is_array($this->TSFE_EDIT['data'])) {
463 $this->save($this->TSFE_EDIT['data']);
464 // pass this on if needed
465 if ($newuid = $this->tce->substNEWwithIDs['NEW']) {
466 $this->TSFE_EDIT['newUID'] = $newuid;
467 }
468 }
469 }
470
471 /**
472 * Hides a specific record.
473 *
474 * @param string The table name for the record to hide.
475 * @param integer The UID for the record to hide.
476 * @return void
477 */
478 public function hide($table, $uid) {
479 $hideField = $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled'];
480 if ($hideField) {
481 $recData = array();
482 $recData[$table][$uid][$hideField] = 1;
483 $this->tce->start($recData, array());
484 $this->tce->process_datamap();
485 }
486 }
487
488 /**
489 * Unhides (shows) a specific record.
490 *
491 * @param string The table name for the record to unhide.
492 * @param integer The UID for the record to unhide.
493 * @return void
494 */
495 public function unhide($table, $uid) {
496 $hideField = $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled'];
497 if ($hideField) {
498 $recData = array();
499 $recData[$table][$uid][$hideField] = 0;
500 $this->tce->start($recData, array());
501 $this->tce->process_datamap();
502 }
503 }
504
505 /**
506 * Moves a record up.
507 *
508 * @param string The table name for the record to move.
509 * @param integer The UID for the record to hide.
510 * @return void
511 */
512 public function up($table, $uid) {
513 $this->move($table, $uid, 'up');
514 }
515
516 /**
517 * Moves a record down.
518 *
519 * @param string The table name for the record to move.
520 * @param integer The UID for the record to move.
521 * @return void
522 */
523 public function down($table, $uid) {
524 $this->move($table, $uid, 'down');
525 }
526
527 /**
528 * Moves a record in the specified direction.
529 *
530 * @param string The table name for the record to move.
531 * @param integer The UID for the record to move.
532 * @param string The direction to move, either 'up' or 'down'.
533 * @return void
534 */
535 protected function move($table, $uid, $direction) {
536 $cmdData = array();
537 if ($direction == 'up') {
538 $operator = '<';
539 $order = 'DESC';
540 } else {
541 $operator = '>';
542 $order = 'ASC';
543 }
544
545 $sortField = $GLOBALS['TCA'][$table]['ctrl']['sortby'];
546 if ($sortField) {
547 // Get self:
548 $fields = array_unique(t3lib_div::trimExplode(',', $GLOBALS['TCA'][$table]['ctrl']['copyAfterDuplFields'] . ',uid,pid,' . $sortField, true));
549 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(implode(',', $fields), $table, 'uid=' . $uid);
550 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
551 // record before or after
552 $preview = $this->extGetFeAdminValue('preview');
553 $copyAfterFieldsQuery = '';
554 if ($preview) {
555 $ignore = array('starttime'=>1, 'endtime'=>1, 'disabled'=>1, 'fe_group'=>1);
556 }
557 if ($GLOBALS['TCA'][$table]['ctrl']['copyAfterDuplFields']) {
558 $cAFields = t3lib_div::trimExplode(',', $GLOBALS['TCA'][$table]['ctrl']['copyAfterDuplFields'], false);
559 foreach($cAFields as $fieldName) {
560 $copyAfterFieldsQuery .= ' AND ' . $fieldName . '="' . $row[$fieldName] . '"';
561 }
562 }
563
564 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
565 'uid,pid',
566 $table,
567 'pid=' . intval($row['pid']) .
568 ' AND ' . $sortField . $operator . intval($row[$sortField]) .
569 $copyAfterFieldsQuery .
570 $GLOBALS['TSFE']->sys_page->enableFields($table, '', $ignore),
571 '',
572 $sortField . ' ' . $order,
573 '2'
574 );
575 if ($row2 = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
576 if ($direction == 'down') {
577 $cmdData[$table][$uid]['move'] = -$row2['uid'];
578 } elseif ($row3 = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { // Must take the second record above...
579 $cmdData[$table][$uid]['move'] = -$row3['uid'];
580 } else { // ... and if that does not exist, use pid
581 $cmdData[$table][$uid]['move'] = $row['pid'];
582 }
583 } elseif ($direction == 'up') {
584 $cmdData[$table][$uid]['move'] = $row['pid'];
585 }
586 }
587 if (count($cmdData)) {
588 $this->tce->start(array(), $cmdData);
589 $this->tce->process_cmdmap();
590 }
591 }
592 }
593
594 /**
595 * Deletes a specific record.
596 *
597 * @param string The table name for the record to delete.
598 * @param integer The UID for the record to delete.
599 * @return void
600 */
601 public function delete($table, $uid) {
602 $cmdData[$table][$uid]['delete'] = 1;
603 if (count($cmdData)) {
604 $this->tce->start(array(), $cmdData);
605 $this->tce->process_cmdmap();
606 }
607 }
608
609 /**
610 * Saves a record based on its data array.
611 *
612 * @param array Array of record data to be saved.
613 * @return void
614 */
615 public function save(array $data) {
616 $this->tce->start($data, array());
617 $this->tce->process_uploads($_FILES);
618 $this->tce->process_datamap();
619 }
620
621 /**
622 * Checks whether the user has access to edit the language for the
623 * requested record.
624 *
625 * @param string The name of the table.
626 * @param array The record.
627 * @return boolean
628 */
629 protected function allowedToEditLanguage($table, array $currentRecord) {
630 // If no access right to record languages, return immediately
631 if ($table === 'pages') {
632 $lang = $GLOBALS['TSFE']->sys_language_uid;
633 } elseif ($table === 'tt_content') {
634 $lang = $GLOBALS['TSFE']->sys_language_content;
635 } elseif ($GLOBALS['TCA'][$table]['ctrl']['languageField']) {
636 $lang = $currentRecord[$GLOBALS['TCA'][$table]['ctrl']['languageField']];
637 } else {
638 $lang = -1;
639 }
640
641 if ($GLOBALS['BE_USER']->checkLanguageAccess($lang)) {
642 $languageAccess = true;
643 } else {
644 $languageAccess = false;
645 }
646
647 return $languageAccess;
648 }
649
650 /**
651 * Checks whether the user is allowed to edit the requested table.
652 *
653 * @param string The name of the table.
654 * @param array The data array.
655 * @param array The configuration array for the edit panel.
656 * @return boolean
657 */
658 protected function allowedToEdit($table, array $dataArray, array $conf) {
659
660 // Unless permissions specifically allow it, editing is not allowed.
661 $mayEdit = false;
662
663 if ($table=='pages') {
664 // 2 = permission to edit the page
665 if ($GLOBALS['BE_USER']->isAdmin() || $GLOBALS['BE_USER']->doesUserHaveAccess($dataArray, 2)) {
666 $mayEdit = true;
667 }
668 } else {
669 // 16 = permission to edit content on the page
670 if ($GLOBALS['BE_USER']->isAdmin() || $GLOBALS['BE_USER']->doesUserHaveAccess(t3lib_BEfunc::getRecord('pages', $dataArray['pid']), 16)) {
671 $mayEdit = true;
672 }
673 }
674
675 if (!$conf['onlyCurrentPid'] || ($dataArray['pid'] == $GLOBALS['TSFE']->id)) {
676 // Permissions:
677 $types = t3lib_div::trimExplode(',', t3lib_div::strtolower($conf['allow']),1);
678 $allow = array_flip($types);
679
680 $perms = $GLOBALS['BE_USER']->calcPerms($GLOBALS['TSFE']->page);
681 if ($table == 'pages') {
682 $allow = $this->getAllowedEditActions($table, $conf, $dataArray['pid'], $allow);
683
684 // Can only display editbox if there are options in the menu
685 if (count($allow)) {
686 $mayEdit = true;
687 }
688 } else {
689 $mayEdit = count($allow) && ($perms & 16);
690 }
691 }
692
693 return $mayEdit;
694 }
695
696 /**
697 * Takes an array of generally allowed actions and filters that list based on page and content permissions.
698 *
699 * @param string The name of the table.
700 * @param array The configuration array.
701 * @param integer The PID where editing will occur.
702 * @param string Comma-separated list of actions that are allowed in general.
703 * @return array
704 */
705 protected function getAllowedEditActions($table, array $conf, $pid, $allow = '') {
706
707 if (!$allow) {
708 $types = t3lib_div::trimExplode(',', t3lib_div::strtolower($conf['allow']), true);
709 $allow = array_flip($types);
710 }
711
712 if (!$conf['onlyCurrentPid'] || $pid == $GLOBALS['TSFE']->id) {
713 // Permissions:
714 $types = t3lib_div::trimExplode(',', t3lib_div::strtolower($conf['allow']), true);
715 $allow = array_flip($types);
716
717 $perms = $GLOBALS['BE_USER']->calcPerms($GLOBALS['TSFE']->page);
718 if ($table=='pages') {
719 // rootpage!
720 if (count($GLOBALS['TSFE']->config['rootLine']) == 1) {
721 unset($allow['move']);
722 unset($allow['hide']);
723 unset($allow['delete']);
724 }
725 if (!($perms & 2)){
726 unset($allow['edit']);
727 unset($allow['move']);
728 unset($allow['hide']);
729 }
730 if (!($perms & 4)) {
731 unset($allow['delete']);
732 }
733 if (!($perms&8)) {
734 unset($allow['new']);
735 }
736 }
737 }
738
739 return $allow;
740 }
741
742 /**
743 * Adds any extra Javascript includes needed for Front-end editing
744 *
745 * @param none
746 * @return string
747 */
748 public function getJavascriptIncludes() {
749 // No extra JS includes needed
750 return '';
751 }
752
753 /**
754 * Gets the hidden fields (array key=field name, value=field value) to be used in the edit panel for a particular content element.
755 * In the normal case, no hidden fields are needed but special controllers such as TemplaVoila need to track flexform pointers, etc.
756 *
757 * @param array The data array for a specific content element.
758 * @return array
759 */
760 public function getHiddenFields(array $dataArray) {
761 // No special hidden fields needed.
762 return array();
763 }
764 }
765
766 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_frontendedit.php']) {
767 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_frontendedit.php']);
768 }
769
770 ?>