[BUGFIX] Remove early return in PageTreeDataProvider
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_frontendedit.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2008-2011 Jeff Segars <jeff@webempoweredchurch.org>
6 * (c) 2008-2011 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 * @author Jeff Segars <jeff@webempoweredchurch.org>
32 * @author David Slayback <dave@webempoweredchurch.org>
33 * @package TYPO3
34 * @subpackage t3lib
35 */
36 class t3lib_frontendedit {
37 /**
38 * GET/POST parameters for the FE editing.
39 * Accessed as $GLOBALS['BE_USER']->frontendEdit->TSFE_EDIT, thus public
40 *
41 * @var array
42 */
43 public $TSFE_EDIT;
44
45 /**
46 * TCEmain object.
47 *
48 * @var t3lib_tcemain
49 */
50 protected $tce;
51
52 /**
53 * Initializes configuration options.
54 *
55 * @return void
56 */
57 public function initConfigOptions() {
58 $this->TSFE_EDIT = t3lib_div::_GP('TSFE_EDIT');
59
60 // Include classes for editing IF editing module in Admin Panel is open
61 if ($GLOBALS['BE_USER']->isFrontendEditingActive()) {
62 $GLOBALS['TSFE']->includeTCA();
63 if ($this->isEditAction()) {
64 $this->editAction();
65 }
66 }
67 }
68
69 /**
70 * 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.
71 * With the "edit panel" the user will see buttons with links to editing, moving, hiding, deleting the element
72 * This function is used for the cObject EDITPANEL and the stdWrap property ".editPanel"
73 *
74 * @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.
75 * @param array TypoScript configuration properties for the editPanel
76 * @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"
77 * @param array Alternative data array to use. Default is $this->data
78 * @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.
79 */
80 public function displayEditPanel($content, array $conf, $currentRecord, array $dataArray) {
81 if ($conf['newRecordFromTable']) {
82 $currentRecord = $conf['newRecordFromTable'] . ':NEW';
83 $conf['allow'] = 'new';
84 $checkEditAccessInternals = FALSE;
85 } else {
86 $checkEditAccessInternals = TRUE;
87 }
88
89 list($table, $uid) = explode(':', $currentRecord);
90
91 // Page ID for new records, 0 if not specified
92 $newRecordPid = intval($conf['newRecordInPid']);
93 if (!$conf['onlyCurrentPid'] || $dataArray['pid'] == $GLOBALS['TSFE']->id) {
94 if ($table == 'pages') {
95 $newUid = $uid;
96 } else {
97 if ($conf['newRecordFromTable']) {
98 $newUid = $GLOBALS['TSFE']->id;
99 if ($newRecordPid) {
100 $newUid = $newRecordPid;
101 }
102 } else {
103 $newUid = -1 * $uid;
104 }
105 }
106 }
107
108 if ($GLOBALS['TSFE']->displayEditIcons && $table && $this->allowedToEdit($table, $dataArray, $conf, $checkEditAccessInternals) && $this->allowedToEditLanguage($table, $dataArray)) {
109 $editClass = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/classes/class.frontendedit.php']['edit'];
110 if ($editClass) {
111 $edit = t3lib_div::getUserObj($editClass, FALSE);
112 if (is_object($edit)) {
113 $allowedActions = $this->getAllowedEditActions($table, $conf, $dataArray['pid']);
114 $content = $edit->editPanel($content, $conf, $currentRecord, $dataArray, $table, $allowedActions, $newUid, $this->getHiddenFields($dataArray));
115 }
116 }
117 }
118
119 return $content;
120 }
121
122 /**
123 * 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.
124 * This implements TYPO3 context sensitive editing facilities. Only backend users will have access (if properly configured as well).
125 *
126 * @param string The content to which the edit icons should be appended
127 * @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
128 * @param array TypoScript properties for configuring the edit icons.
129 * @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"
130 * @param array Alternative data array to use. Default is $this->data
131 * @param string Additional URL parameters for the link pointing to alt_doc.php
132 * @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.
133 */
134
135 public function displayEditIcons($content, $params, array $conf = array(), $currentRecord = '', array $dataArray = array(), $addUrlParamStr = '') {
136 // Check incoming params:
137 list($currentRecordTable, $currentRecordUID) = explode(':', $currentRecord);
138 list($fieldList, $table) = array_reverse(t3lib_div::trimExplode(':', $params, 1)); // Reverse the array because table is optional
139 if (!$table) {
140 $table = $currentRecordTable;
141 } elseif ($table != $currentRecordTable) {
142 return $content; // If the table is set as the first parameter, and does not match the table of the current record, then just return.
143 }
144
145 $editUid = $dataArray['_LOCALIZED_UID'] ? $dataArray['_LOCALIZED_UID'] : $currentRecordUID;
146
147 // Edit icons imply that the editing action is generally allowed, assuming page and content element permissions permit it.
148 if (!array_key_exists('allow', $conf)) {
149 $conf['allow'] = 'edit';
150 }
151
152 if ($GLOBALS['TSFE']->displayFieldEditIcons && $table && $this->allowedToEdit($table, $dataArray, $conf) && $fieldList && $this->allowedToEditLanguage($table, $dataArray)) {
153 $editClass = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/classes/class.frontendedit.php']['edit'];
154 if ($editClass) {
155 $edit = t3lib_div::getUserObj($editClass);
156 if (is_object($edit)) {
157 $content = $edit->editIcons($content, $params, $conf, $currentRecord, $dataArray, $addUrlParamStr, $table, $editUid, $fieldList);
158 }
159 }
160 }
161
162 return $content;
163 }
164
165 /*****************************************************
166 *
167 * Frontend Editing
168 *
169 ****************************************************/
170
171 /**
172 * Returns TRUE if an edit-action is sent from the Admin Panel
173 *
174 * @return boolean
175 * @see index_ts.php
176 */
177 public function isEditAction() {
178 if (is_array($this->TSFE_EDIT)) {
179 if ($this->TSFE_EDIT['cancel']) {
180 unset($this->TSFE_EDIT['cmd']);
181 } else {
182 $cmd = (string) $this->TSFE_EDIT['cmd'];
183 if (($cmd != 'edit' || (is_array($this->TSFE_EDIT['data']) && ($this->TSFE_EDIT['doSave'] || $this->TSFE_EDIT['update'] || $this->TSFE_EDIT['update_close']))) && $cmd != 'new') {
184 // $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 sent because of .keepGoing flag.
185 return TRUE;
186 }
187 }
188 }
189 return FALSE;
190 }
191
192 /**
193 * Returns TRUE if an edit form is shown on the page.
194 * Used from index_ts.php where a TRUE return-value will result in classes etc. being included.
195 *
196 * @return boolean
197 * @see index_ts.php
198 */
199 public function isEditFormShown() {
200 if (is_array($this->TSFE_EDIT)) {
201 $cmd = (string) $this->TSFE_EDIT['cmd'];
202 if ($cmd == 'edit' || $cmd == 'new') {
203 return TRUE;
204 }
205 }
206 }
207
208 /**
209 * Management of the on-page frontend editing forms and edit panels.
210 * Basically taking in the data and commands and passes them on to the proper classes as they should be.
211 *
212 * @return void
213 * @throws UnexpectedValueException if TSFE_EDIT[cmd] is not a valid command
214 * @see index_ts.php
215 */
216 public function editAction() {
217 // Commands:
218 list($table, $uid) = explode(':', $this->TSFE_EDIT['record']);
219 $uid = intval($uid);
220 $cmd = $this->TSFE_EDIT['cmd'];
221
222 // Look for some TSFE_EDIT data that indicates we should save.
223 if (($this->TSFE_EDIT['doSave'] || $this->TSFE_EDIT['update'] || $this->TSFE_EDIT['update_close']) && is_array($this->TSFE_EDIT['data'])) {
224 $cmd = 'save';
225 }
226
227 if (($cmd == 'save') || ($cmd && $table && $uid && isset($GLOBALS['TCA'][$table]))) {
228 // Hook for defining custom editing actions. Naming is incorrect, but preserves compatibility.
229 if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['extEditAction'])) {
230 $_params = array();
231 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['extEditAction'] as $_funcRef) {
232 t3lib_div::callUserFunction($_funcRef, $_params, $this);
233 }
234 }
235
236 // Perform the requested editing command.
237 $cmdAction = 'do' . ucwords($cmd);
238 if (is_callable(array($this, $cmdAction))) {
239 $this->$cmdAction($table, $uid);
240 } else {
241 throw new UnexpectedValueException(
242 'The specified frontend edit command (' . $cmd . ') is not valid.',
243 1225818120
244 );
245 }
246 }
247 }
248
249 /**
250 * Hides a specific record.
251 *
252 * @param string The table name for the record to hide.
253 * @param integer The UID for the record to hide.
254 * @return void
255 */
256 public function doHide($table, $uid) {
257 $hideField = $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled'];
258 if ($hideField) {
259 $recData = array();
260 $recData[$table][$uid][$hideField] = 1;
261
262 $this->initializeTceMain();
263 $this->tce->start($recData, array());
264 $this->tce->process_datamap();
265 }
266 }
267
268 /**
269 * Unhides (shows) a specific record.
270 *
271 * @param string The table name for the record to unhide.
272 * @param integer The UID for the record to unhide.
273 * @return void
274 */
275 public function doUnhide($table, $uid) {
276 $hideField = $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled'];
277 if ($hideField) {
278 $recData = array();
279 $recData[$table][$uid][$hideField] = 0;
280
281 $this->initializeTceMain();
282 $this->tce->start($recData, array());
283 $this->tce->process_datamap();
284 }
285 }
286
287 /**
288 * Moves a record up.
289 *
290 * @param string The table name for the record to move.
291 * @param integer The UID for the record to hide.
292 * @return void
293 */
294 public function doUp($table, $uid) {
295 $this->move($table, $uid, 'up');
296 }
297
298 /**
299 * Moves a record down.
300 *
301 * @param string The table name for the record to move.
302 * @param integer The UID for the record to move.
303 * @return void
304 */
305 public function doDown($table, $uid) {
306 $this->move($table, $uid, 'down');
307 }
308
309 /**
310 * Moves a record after a given element. Used for drag.
311 *
312 * @param string The table name for the record to move.
313 * @param integer The UID for the record to move.
314 * @return void
315 */
316 public function doMoveAfter($table, $uid) {
317 $afterUID = $GLOBALS['BE_USER']->frontendEdit->TSFE_EDIT['moveAfter'];
318 $this->move($table, $uid, '', $afterUID);
319 }
320
321 /**
322 * Moves a record
323 *
324 * @param string The table name for the record to move.
325 * @param integer The UID for the record to move.
326 * @param string The direction to move, either 'up' or 'down'.
327 * @param integer The UID of record to move after. This is specified for dragging only.
328 * @return void
329 */
330 protected function move($table, $uid, $direction = '', $afterUID = 0) {
331 $cmdData = array();
332 $sortField = $GLOBALS['TCA'][$table]['ctrl']['sortby'];
333 if ($sortField) {
334 // Get self:
335 $fields = array_unique(t3lib_div::trimExplode(',', $GLOBALS['TCA'][$table]['ctrl']['copyAfterDuplFields'] . ',uid,pid,' . $sortField, TRUE));
336 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(implode(',', $fields), $table, 'uid=' . $uid);
337 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
338 // record before or after
339 if (($GLOBALS['BE_USER']->adminPanel instanceOf tslib_AdminPanel) && ($GLOBALS['BE_USER']->adminPanel->extGetFeAdminValue('preview'))) {
340 $ignore = array('starttime' => 1, 'endtime' => 1, 'disabled' => 1, 'fe_group' => 1);
341 }
342 $copyAfterFieldsQuery = '';
343 if ($GLOBALS['TCA'][$table]['ctrl']['copyAfterDuplFields']) {
344 $cAFields = t3lib_div::trimExplode(',', $GLOBALS['TCA'][$table]['ctrl']['copyAfterDuplFields'], TRUE);
345 foreach ($cAFields as $fieldName) {
346 $copyAfterFieldsQuery .= ' AND ' . $fieldName . '="' . $row[$fieldName] . '"';
347 }
348 }
349 if (!empty($direction)) {
350 if ($direction == 'up') {
351 $operator = '<';
352 $order = 'DESC';
353 } else {
354 $operator = '>';
355 $order = 'ASC';
356 }
357 $sortCheck = ' AND ' . $sortField . $operator . intval($row[$sortField]);
358 }
359 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
360 'uid,pid',
361 $table,
362 'pid=' . intval($row['pid']) .
363 $sortCheck .
364 $copyAfterFieldsQuery .
365 $GLOBALS['TSFE']->sys_page->enableFields($table, '', $ignore),
366 '',
367 $sortField . ' ' . $order,
368 '2'
369 );
370 if ($row2 = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
371 if ($afterUID) {
372 $cmdData[$table][$uid]['move'] = -$afterUID;
373 }
374 elseif ($direction == 'down') {
375 $cmdData[$table][$uid]['move'] = -$row2['uid'];
376 }
377 elseif ($row3 = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { // Must take the second record above...
378 $cmdData[$table][$uid]['move'] = -$row3['uid'];
379 }
380 else { // ... and if that does not exist, use pid
381 $cmdData[$table][$uid]['move'] = $row['pid'];
382 }
383 } elseif ($direction == 'up') {
384 $cmdData[$table][$uid]['move'] = $row['pid'];
385 }
386 }
387 if (!empty($cmdData)) {
388 $this->initializeTceMain();
389 $this->tce->start(array(), $cmdData);
390 $this->tce->process_cmdmap();
391 }
392 }
393 }
394
395 /**
396 * Deletes a specific record.
397 *
398 * @param string The table name for the record to delete.
399 * @param integer The UID for the record to delete.
400 * @return void
401 */
402 public function doDelete($table, $uid) {
403 $cmdData[$table][$uid]['delete'] = 1;
404 if (count($cmdData)) {
405 $this->initializeTceMain();
406 $this->tce->start(array(), $cmdData);
407 $this->tce->process_cmdmap();
408 }
409 }
410
411 /**
412 * Saves a record based on its data array.
413 *
414 * @param string The table name for the record to save.
415 * @param integer The UID for the record to save.
416 * @return void
417 */
418 public function doSave($table, $uid) {
419 $data = $this->TSFE_EDIT['data'];
420
421 if (!empty($data)) {
422 $this->initializeTceMain();
423 $this->tce->start($data, array());
424 $this->tce->process_uploads($_FILES);
425 $this->tce->process_datamap();
426
427 // Save the new UID back into TSFE_EDIT
428 $newUID = $this->tce->substNEWwithIDs['NEW'];
429 if ($newUID) {
430 $GLOBALS['BE_USER']->frontendEdit->TSFE_EDIT['newUID'] = $newUID;
431 }
432 }
433 }
434
435 /**
436 * Saves a record based on its data array and closes it.
437 *
438 * @param string The table name for the record to save.
439 * @param integer The UID for the record to save.
440 * @return void
441 * @note This method is only a wrapper for doSave() but is needed so
442 * that frontend editing views can handle "save" differently from
443 * "save and close".
444 * Example: When editing a page record, "save" reloads the same
445 * editing form. "Save and close" reloads the entire page at
446 * the appropriate URL.
447 */
448 public function doSaveAndClose($table, $uid) {
449 $this->doSave($table, $uid);
450 }
451
452
453 /**
454 * Stub for closing a record. No real functionality needed since content
455 * element rendering will take care of everything.
456 *
457 * @param string The table name for the record to close.
458 * @param integer The UID for the record to close.
459 * @return void
460 */
461 public function doClose($table, $uid) {
462 // Do nothing.
463 }
464
465 /**
466 * Checks whether the user has access to edit the language for the
467 * requested record.
468 *
469 * @param string The name of the table.
470 * @param array The record.
471 * @return boolean
472 */
473 protected function allowedToEditLanguage($table, array $currentRecord) {
474 // If no access right to record languages, return immediately
475 if ($table === 'pages') {
476 $lang = $GLOBALS['TSFE']->sys_language_uid;
477 } elseif ($table === 'tt_content') {
478 $lang = $GLOBALS['TSFE']->sys_language_content;
479 } elseif ($GLOBALS['TCA'][$table]['ctrl']['languageField']) {
480 $lang = $currentRecord[$GLOBALS['TCA'][$table]['ctrl']['languageField']];
481 } else {
482 $lang = -1;
483 }
484
485 if ($GLOBALS['BE_USER']->checkLanguageAccess($lang)) {
486 $languageAccess = TRUE;
487 } else {
488 $languageAccess = FALSE;
489 }
490
491 return $languageAccess;
492 }
493
494 /**
495 * Checks whether the user is allowed to edit the requested table.
496 *
497 * @param string The name of the table.
498 * @param array The data array.
499 * @param array The configuration array for the edit panel.
500 * @param boolean Boolean indicating whether recordEditAccessInternals should not be checked. Defaults
501 * to TRUE but doesn't makes sense when creating new records on a page.
502 * @return boolean
503 */
504 protected function allowedToEdit($table, array $dataArray, array $conf, $checkEditAccessInternals = TRUE) {
505
506 // Unless permissions specifically allow it, editing is not allowed.
507 $mayEdit = FALSE;
508
509 if ($checkEditAccessInternals) {
510 $editAccessInternals = $GLOBALS['BE_USER']->recordEditAccessInternals($table, $dataArray, FALSE, FALSE);
511 } else {
512 $editAccessInternals = TRUE;
513 }
514
515 if ($editAccessInternals) {
516 if ($table == 'pages') {
517 // 2 = permission to edit the page
518 if ($GLOBALS['BE_USER']->isAdmin() || $GLOBALS['BE_USER']->doesUserHaveAccess($dataArray, 2)) {
519 $mayEdit = TRUE;
520 }
521 } else {
522 // 16 = permission to edit content on the page
523 if ($GLOBALS['BE_USER']->isAdmin() || $GLOBALS['BE_USER']->doesUserHaveAccess(t3lib_BEfunc::getRecord('pages', $dataArray['pid']), 16)) {
524 $mayEdit = TRUE;
525 }
526 }
527
528 if (!$conf['onlyCurrentPid'] || ($dataArray['pid'] == $GLOBALS['TSFE']->id)) {
529 // Permissions:
530 $types = t3lib_div::trimExplode(',', t3lib_div::strtolower($conf['allow']), 1);
531 $allow = array_flip($types);
532
533 $perms = $GLOBALS['BE_USER']->calcPerms($GLOBALS['TSFE']->page);
534 if ($table == 'pages') {
535 $allow = $this->getAllowedEditActions($table, $conf, $dataArray['pid'], $allow);
536
537 // Can only display editbox if there are options in the menu
538 if (count($allow)) {
539 $mayEdit = TRUE;
540 }
541 } else {
542 $mayEdit = count($allow) && ($perms & 16);
543 }
544 }
545 }
546
547 return $mayEdit;
548 }
549
550 /**
551 * Takes an array of generally allowed actions and filters that list based on page and content permissions.
552 *
553 * @param string The name of the table.
554 * @param array The configuration array.
555 * @param integer The PID where editing will occur.
556 * @param string Comma-separated list of actions that are allowed in general.
557 * @return array
558 */
559 protected function getAllowedEditActions($table, array $conf, $pid, $allow = '') {
560
561 if (!$allow) {
562 $types = t3lib_div::trimExplode(',', t3lib_div::strtolower($conf['allow']), TRUE);
563 $allow = array_flip($types);
564 }
565
566 if (!$conf['onlyCurrentPid'] || $pid == $GLOBALS['TSFE']->id) {
567 // Permissions:
568 $types = t3lib_div::trimExplode(',', t3lib_div::strtolower($conf['allow']), TRUE);
569 $allow = array_flip($types);
570
571 $perms = $GLOBALS['BE_USER']->calcPerms($GLOBALS['TSFE']->page);
572 if ($table == 'pages') {
573 // rootpage!
574 if (count($GLOBALS['TSFE']->config['rootLine']) == 1) {
575 unset($allow['move']);
576 unset($allow['hide']);
577 unset($allow['delete']);
578 }
579 if (!($perms & 2)) {
580 unset($allow['edit']);
581 unset($allow['move']);
582 unset($allow['hide']);
583 }
584 if (!($perms & 4)) {
585 unset($allow['delete']);
586 }
587 if (!($perms & 8)) {
588 unset($allow['new']);
589 }
590 }
591 }
592
593 return $allow;
594 }
595
596 /**
597 * Adds any extra Javascript includes needed for Front-end editing
598 *
599 * @param none
600 * @return string
601 */
602 public function getJavascriptIncludes() {
603 // No extra JS includes needed
604 return '';
605 }
606
607 /**
608 * Gets the hidden fields (array key=field name, value=field value) to be used in the edit panel for a particular content element.
609 * In the normal case, no hidden fields are needed but special controllers such as TemplaVoila need to track flexform pointers, etc.
610 *
611 * @param array The data array for a specific content element.
612 * @return array
613 */
614 public function getHiddenFields(array $dataArray) {
615 // No special hidden fields needed.
616 return array();
617 }
618
619 /**
620 * Initializes t3lib_TCEmain since it is used on modification actions.
621 *
622 * @return void
623 */
624 protected function initializeTceMain() {
625 if (!isset($this->tce)) {
626 $this->tce = t3lib_div::makeInstance('t3lib_TCEmain');
627 $this->tce->stripslashes_values = 0;
628 }
629 }
630 }
631
632 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_frontendedit.php'])) {
633 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_frontendedit.php']);
634 }
635
636 ?>