[FEATURE] Add flexible preview link configuration 39/38639/2
authorMarkus Klein <klein.t3@reelworx.at>
Sat, 11 Apr 2015 18:41:29 +0000 (20:41 +0200)
committerAndreas Fernandez <andreas.fernandez@aspedia.de>
Wed, 15 Apr 2015 09:25:32 +0000 (11:25 +0200)
We add new page TSconfig to allow flexible configuration of preview
links for any record.

Releases: master
Resolves: #66370
Change-Id: I5beac52f9383d17aac424694dd9b3011a1e06776
Reviewed-on: http://review.typo3.org/38639
Reviewed-by: Frans Saris <franssaris@gmail.com>
Reviewed-by: Georg Ringer <georg.ringer@gmail.com>
Tested-by: Georg Ringer <georg.ringer@gmail.com>
Reviewed-by: Mathias Schreiber <mathias.schreiber@wmdb.de>
Tested-by: Mathias Schreiber <mathias.schreiber@wmdb.de>
Reviewed-by: Andreas Fernandez <andreas.fernandez@aspedia.de>
Tested-by: Andreas Fernandez <andreas.fernandez@aspedia.de>
typo3/sysext/backend/Classes/Controller/EditDocumentController.php
typo3/sysext/backend/Classes/Utility/BackendUtility.php
typo3/sysext/core/Documentation/Changelog/master/Feature-66370-AddFlexiblePreviewUrlConfiguration.rst [new file with mode: 0644]

index 11961e9..5410695 100644 (file)
@@ -23,6 +23,7 @@ use TYPO3\CMS\Core\Type\Bitmask\Permission;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Core\Utility\HttpUtility;
 use TYPO3\CMS\Core\Utility\MathUtility;
+use TYPO3\CMS\Frontend\Page\PageRepository;
 
 /**
  * Script Class: Drawing the editing form for editing records in TYPO3.
@@ -387,6 +388,13 @@ class EditDocumentController {
        protected $signalSlotDispatcher;
 
        /**
+        * Stores information needed to preview the currently saved record
+        *
+        * @var array
+        */
+       protected $previewData = [];
+
+       /**
         * Constructor
         */
        public function __construct() {
@@ -609,6 +617,18 @@ class EditDocumentController {
                                // Re-compile the store* values since editconf changed...
                                $this->compileStoreDat();
                        }
+                       // If a preview is requested
+                       if (isset($_POST['_savedokview_x'])) {
+                               // Get the first table and id of the data array from DataHandler
+                               $table = reset(array_keys($this->data));
+                               $id = reset(array_keys($this->data[$table]));
+                               if (!MathUtility::canBeInterpretedAsInteger($id)) {
+                                       $id = $tce->substNEWwithIDs[$id];
+                               }
+                               // Store this information for later use
+                               $this->previewData['table'] = $table;
+                               $this->previewData['id'] = $id;
+                       }
                        $tce->printLogErrorMessages(isset($_POST['_saveandclosedok_x']) || isset($_POST['_translation_savedok_x']) ? $this->retUrl : $this->R_URL_parts['path'] . '?' . GeneralUtility::implodeArrayForUrl('', $this->R_URL_getvars));
                }
                //  || count($tce->substNEWwithIDs)... If any new items has been save, the document is CLOSED
@@ -676,11 +696,11 @@ class EditDocumentController {
                                'height' => $popupWindowHeight
                        ),
                );
-               $this->doc->JScode = $this->doc->wrapScriptTags('
-                               TYPO3.configuration = ' . json_encode($t3Configuration) . ';
-                               // Object: TS:
-                               // passwordDummy and decimalSign are used by tbe_editor.js and have to be declared here as
-                               // TS object overwrites the object declared in tbe_editor.js
+               $javascript = '
+                       TYPO3.configuration = ' . json_encode($t3Configuration) . ';
+                       // Object: TS:
+                       // passwordDummy and decimalSign are used by tbe_editor.js and have to be declared here as
+                       // TS object overwrites the object declared in tbe_editor.js
                        function typoSetup() {  //
                                this.uniqueID = "";
                                this.passwordDummy = "********";
@@ -706,7 +726,11 @@ class EditDocumentController {
                                }
                                return false;
                        }
-               ' . (isset($_POST['_savedokview_x']) && $this->popViewId ? 'if (window.opener) { ' . BackendUtility::viewOnClick($this->popViewId, '', BackendUtility::BEgetRootLine($this->popViewId), '', $this->viewUrl, $this->popViewId_addParams, FALSE) . ' } else { ' . BackendUtility::viewOnClick($this->popViewId, '', BackendUtility::BEgetRootLine($this->popViewId), '', $this->viewUrl, $this->popViewId_addParams) . ' } ' : ''));
+               ';
+
+               $previewCode = isset($_POST['_savedokview_x']) && $this->popViewId ? $this->generatePreviewCode() : '';
+
+               $this->doc->JScode = $this->doc->wrapScriptTags($javascript . $previewCode);
                // Setting up the context sensitive menu:
                $this->doc->getContextMenuCode();
                $this->doc->bodyTagAdditions = 'onload="window.scrollTo(0,' . MathUtility::forceIntegerInRange(GeneralUtility::_GP('_scrollPosition'), 0, 10000) . ');"';
@@ -715,6 +739,103 @@ class EditDocumentController {
        }
 
        /**
+        * @return string
+        */
+       protected function generatePreviewCode() {
+               $currentPageId = MathUtility::convertToPositiveInteger($this->popViewId);
+               $table = $this->previewData['table'];
+               $recordId = $this->previewData['id'];
+
+               $pageTsConfig = BackendUtility::getPagesTSconfig($currentPageId);
+               $previewConfiguration = isset($pageTsConfig['TCEMAIN.']['preview.'][$table . '.'])
+                       ? $pageTsConfig['TCEMAIN.']['preview.'][$table . '.']
+                       : array();
+
+               $recordArray = BackendUtility::getRecord($table, $recordId);
+
+               // find the right preview page id
+               $previewPageId = 0;
+               if (isset($previewConfiguration['previewPageId'])) {
+                       $previewPageId = $previewConfiguration['previewPageId'];
+               }
+               // if no preview page was configured
+               if (!$previewPageId) {
+                       $rootPageData = NULL;
+                       $rootLine = BackendUtility::BEgetRootLine($currentPageId);
+                       $currentPage = reset($rootLine);
+                       if ((int)$currentPage['doktype'] === PageRepository::DOKTYPE_DEFAULT) {
+                               // try the current page
+                               $previewPageId = $currentPageId;
+                       } else {
+                               // or search for the root page
+                               foreach ($rootLine as $page) {
+                                       if ($page['is_siteroot']) {
+                                               $rootPageData = $page;
+                                               break;
+                                       }
+                               }
+                               $previewPageId = isset($rootPageData)
+                                       ? (int)$rootPageData['uid']
+                                       : $currentPageId;
+                       }
+               }
+
+               $linkParameters = [
+                       'no_cache' => 1,
+               ];
+
+               // language handling
+               $languageField = isset($GLOBALS['TCA'][$table]['ctrl']['languageField'])
+                       ? $GLOBALS['TCA'][$table]['ctrl']['languageField']
+                       : '';
+               if ($languageField && !empty($recordArray[$languageField])) {
+                       $l18nPointer = isset($GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'])
+                               ? $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']
+                               : '';
+                       if (
+                               $l18nPointer && !empty($recordArray[$l18nPointer])
+                               && isset($previewConfiguration['useDefaultLanguageRecord'])
+                               && !$previewConfiguration['useDefaultLanguageRecord']
+                       ) {
+                               // use parent record
+                               $recordId = $recordArray[$l18nPointer];
+                       }
+                       $linkParameters['L'] = $recordArray[$languageField];
+               }
+
+               // map record data to GET parameters
+               if (isset($previewConfiguration['fieldToParameterMap.'])) {
+                       foreach ($previewConfiguration['fieldToParameterMap.'] as $field => $parameterName) {
+                               $value = $recordArray[$field];
+                               if ($field === 'uid') {
+                                       $value = $recordId;
+                               }
+                               $linkParameters[$parameterName] = $value;
+                       }
+               }
+
+               // add/override parameters by configuration
+               if (isset($previewConfiguration['additionalGetParameters.'])) {
+                       $linkParameters = array_replace($linkParameters, $previewConfiguration['additionalGetParameters.']);
+               }
+
+               $this->popViewId = $previewPageId;
+               $this->popViewId_addParams = GeneralUtility::implodeArrayForUrl('', $linkParameters, '', FALSE, TRUE);
+
+               $previewPageRootline = BackendUtility::BEgetRootLine($this->popViewId);
+               return '
+                               if (window.opener) {
+                               '
+                       . BackendUtility::viewOnClick($this->popViewId, '', $previewPageRootline, '', $this->viewUrl, $this->popViewId_addParams, FALSE)
+                       . '
+                               } else {
+                               '
+                       . BackendUtility::viewOnClick($this->popViewId, '', $previewPageRootline, '', $this->viewUrl, $this->popViewId_addParams)
+                       . '
+                               }';
+       }
+
+       /**
         * Main module operation
         *
         * @return void
index 64fff1e..1f54f2f 100644 (file)
@@ -349,6 +349,7 @@ class BackendUtility {
                                        'uid' => $val['uid'],
                                        'pid' => $val['pid'],
                                        'title' => $val['title'],
+                                       'doktype' => $val['doktype'],
                                        'TSconfig' => $val['TSconfig'],
                                        'is_siteroot' => $val['is_siteroot'],
                                        'storage_pid' => $val['storage_pid'],
@@ -383,7 +384,7 @@ class BackendUtility {
                        $row = $getPageForRootline_cache[$ident];
                } else {
                        $db = static::getDatabaseConnection();
-                       $res = $db->exec_SELECTquery('pid,uid,title,TSconfig,is_siteroot,storage_pid,t3ver_oid,t3ver_wsid,t3ver_state,t3ver_stage,backend_layout_next_level', 'pages', 'uid=' . (int)$uid . ' ' . self::deleteClause('pages') . ' ' . $clause);
+                       $res = $db->exec_SELECTquery('pid,uid,title,doktype,TSconfig,is_siteroot,storage_pid,t3ver_oid,t3ver_wsid,t3ver_state,t3ver_stage,backend_layout_next_level', 'pages', 'uid=' . (int)$uid . ' ' . self::deleteClause('pages') . ' ' . $clause);
                        $row = $db->sql_fetch_assoc($res);
                        if ($row) {
                                $newLocation = FALSE;
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-66370-AddFlexiblePreviewUrlConfiguration.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-66370-AddFlexiblePreviewUrlConfiguration.rst
new file mode 100644 (file)
index 0000000..438a9cf
--- /dev/null
@@ -0,0 +1,51 @@
+========================================================
+Feature: #66370 - Add flexible Preview URL configuration
+========================================================
+
+Description
+===========
+
+It is now possible to configure the preview link generated for the save+view button in Backend.
+
+This allows to have different preview URLs depending on the record type.
+
+Common usecase is to have previews for blog or news records, but this feature now allows you to
+define a different preview page for content elements as well, which might be handy if those are stored
+in a sysfolder.
+
+Impact
+======
+
+New page TSconfig is introduced. The options are:
+
+.. code-block:: typoscript
+
+       TCEMAIN.preview {
+               <table name> {
+                       previewPageId = 123
+                       useDefaultLanguageRecord = 0
+                       fieldToParameterMap {
+                               uid = tx_myext_pi1[showUid]
+                       }
+                       additionalGetParameters {
+                               tx_myext_pi1[special] = HELLO
+                       }
+               }
+       }
+
+The ``previewPageId`` is the uid of the page to use for preview. If this setting is omitted the current page will be used.
+If the current page is not a normal page, the root page will be chosen.
+
+The ``useDefaultLanguageRecord`` defaults to ``1`` and ensures that translated records will use the uid of the default record
+for the preview link. You may disabled this, if your extension can deal with the uid of translated records.
+
+The ``fieldToParameterMap`` is a mapping which allows you to select fields of the record to be included as GET-parameters in
+the preview link. The key specifies the field name and the value specifies the GET-parameter name.
+
+Finally ``additionalGetParameters`` allow you to add arbitrary GET-parameters and even to override others.
+
+Predefined GET-parameters
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The Core automatically sets the ``no_cache`` and the ``L`` parameter. The language matches the language of the current record.
+You may override each parameter by using the ``additionalGetParameters`` configuration option.