Contao\Versions::compare PHP Метод

compare() публичный Метод

Compare versions
public compare ( )
    public function compare()
    {
        $strBuffer = '';
        $arrVersions = array();
        $intTo = 0;
        $intFrom = 0;
        $objVersions = $this->Database->prepare("SELECT * FROM tl_version WHERE pid=? AND fromTable=? ORDER BY version DESC")->execute($this->intPid, $this->strTable);
        if ($objVersions->numRows < 2) {
            $strBuffer = '<p>There are no versions of ' . $this->strTable . '.id=' . $this->intPid . '</p>';
        } else {
            $intIndex = 0;
            $from = array();
            // Store the versions and mark the active one
            while ($objVersions->next()) {
                if ($objVersions->active) {
                    $intIndex = $objVersions->version;
                }
                $arrVersions[$objVersions->version] = $objVersions->row();
                $arrVersions[$objVersions->version]['info'] = $GLOBALS['TL_LANG']['MSC']['version'] . ' ' . $objVersions->version . ' (' . \Date::parse(\Config::get('datimFormat'), $objVersions->tstamp) . ') ' . $objVersions->username;
            }
            // To
            if (\Input::post('to') && isset($arrVersions[\Input::post('to')])) {
                $intTo = \Input::post('to');
                $to = \StringUtil::deserialize($arrVersions[\Input::post('to')]['data']);
            } elseif (\Input::get('to') && isset($arrVersions[\Input::get('to')])) {
                $intTo = \Input::get('to');
                $to = \StringUtil::deserialize($arrVersions[\Input::get('to')]['data']);
            } else {
                $intTo = $intIndex;
                $to = \StringUtil::deserialize($arrVersions[$intTo]['data']);
            }
            // From
            if (\Input::post('from') && isset($arrVersions[\Input::post('from')])) {
                $intFrom = \Input::post('from');
                $from = \StringUtil::deserialize($arrVersions[\Input::post('from')]['data']);
            } elseif (\Input::get('from') && isset($arrVersions[\Input::get('from')])) {
                $intFrom = \Input::get('from');
                $from = \StringUtil::deserialize($arrVersions[\Input::get('from')]['data']);
            } elseif ($objVersions->numRows > $intIndex) {
                $intFrom = $objVersions->first()->version;
                $from = \StringUtil::deserialize($arrVersions[$intFrom]['data']);
            } elseif ($intIndex > 1) {
                $intFrom = $intIndex - 1;
                $from = \StringUtil::deserialize($arrVersions[$intFrom]['data']);
            }
            // Only continue if both version numbers are set
            if ($intTo > 0 && $intFrom > 0) {
                \System::loadLanguageFile($this->strTable);
                $this->loadDataContainer($this->strTable);
                // Get the order fields
                $objDcaExtractor = \DcaExtractor::getInstance($this->strTable);
                $arrOrder = $objDcaExtractor->getOrderFields();
                // Find the changed fields and highlight the changes
                foreach ($to as $k => $v) {
                    if ($from[$k] != $to[$k]) {
                        if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['eval']['doNotShow'] || $GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['eval']['hideInput']) {
                            continue;
                        }
                        $blnIsBinary = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['inputType'] == 'fileTree' || in_array($k, $arrOrder);
                        // Decrypt the values
                        if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['eval']['encrypt']) {
                            $to[$k] = \Encryption::decrypt($to[$k]);
                            $from[$k] = \Encryption::decrypt($from[$k]);
                        }
                        // Convert serialized arrays into strings
                        if (is_array($tmp = \StringUtil::deserialize($to[$k])) && !is_array($to[$k])) {
                            $to[$k] = $this->implodeRecursive($tmp, $blnIsBinary);
                        }
                        if (is_array($tmp = \StringUtil::deserialize($from[$k])) && !is_array($from[$k])) {
                            $from[$k] = $this->implodeRecursive($tmp, $blnIsBinary);
                        }
                        unset($tmp);
                        // Convert binary UUIDs to their hex equivalents (see #6365)
                        if ($blnIsBinary && \Validator::isBinaryUuid($to[$k])) {
                            $to[$k] = \StringUtil::binToUuid($to[$k]);
                        }
                        if ($blnIsBinary && \Validator::isBinaryUuid($from[$k])) {
                            $to[$k] = \StringUtil::binToUuid($from[$k]);
                        }
                        // Convert date fields
                        if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['eval']['rgxp'] == 'date') {
                            $to[$k] = \Date::parse(\Config::get('dateFormat'), $to[$k] ?: '');
                            $from[$k] = \Date::parse(\Config::get('dateFormat'), $from[$k] ?: '');
                        } elseif ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['eval']['rgxp'] == 'time') {
                            $to[$k] = \Date::parse(\Config::get('timeFormat'), $to[$k] ?: '');
                            $from[$k] = \Date::parse(\Config::get('timeFormat'), $from[$k] ?: '');
                        } elseif ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['eval']['rgxp'] == 'datim' || $k == 'tstamp') {
                            $to[$k] = \Date::parse(\Config::get('datimFormat'), $to[$k] ?: '');
                            $from[$k] = \Date::parse(\Config::get('datimFormat'), $from[$k] ?: '');
                        }
                        // Convert strings into arrays
                        if (!is_array($to[$k])) {
                            $to[$k] = explode("\n", $to[$k]);
                        }
                        if (!is_array($from[$k])) {
                            $from[$k] = explode("\n", $from[$k]);
                        }
                        $objDiff = new \Diff($from[$k], $to[$k]);
                        $strBuffer .= $objDiff->render(new DiffRenderer(array('field' => $GLOBALS['TL_DCA'][$this->strTable]['fields'][$k]['label'][0] ?: (isset($GLOBALS['TL_LANG']['MSC'][$k]) ? is_array($GLOBALS['TL_LANG']['MSC'][$k]) ? $GLOBALS['TL_LANG']['MSC'][$k][0] : $GLOBALS['TL_LANG']['MSC'][$k] : $k))));
                    }
                }
            }
        }
        // Identical versions
        if ($strBuffer == '') {
            $strBuffer = '<p>' . $GLOBALS['TL_LANG']['MSC']['identicalVersions'] . '</p>';
        }
        /** @var BackendTemplate|object $objTemplate */
        $objTemplate = new \BackendTemplate('be_diff');
        // Template variables
        $objTemplate->content = $strBuffer;
        $objTemplate->versions = $arrVersions;
        $objTemplate->to = $intTo;
        $objTemplate->from = $intFrom;
        $objTemplate->showLabel = \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['showDifferences']);
        $objTemplate->theme = \Backend::getTheme();
        $objTemplate->base = \Environment::get('base');
        $objTemplate->language = $GLOBALS['TL_LANGUAGE'];
        $objTemplate->title = \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['showDifferences']);
        $objTemplate->charset = \Config::get('characterSet');
        $objTemplate->action = ampersand(\Environment::get('request'));
        throw new ResponseException($objTemplate->getResponse());
    }

Usage Example

Пример #1
0
    /**
     * Auto-generate a form to edit the current database record
     *
     * @param integer $intId
     * @param integer $ajaxId
     *
     * @return string
     *
     * @throws AccessDeniedException
     * @throws InternalServerErrorException
     */
    public function edit($intId = null, $ajaxId = null)
    {
        if ($GLOBALS['TL_DCA'][$this->strTable]['config']['notEditable']) {
            throw new InternalServerErrorException('Table "' . $this->strTable . '" is not editable.');
        }
        if ($intId != '') {
            $this->intId = $intId;
        }
        // Get the current record
        $objRow = $this->Database->prepare("SELECT * FROM " . $this->strTable . " WHERE id=?")->limit(1)->execute($this->intId);
        // Redirect if there is no record with the given ID
        if ($objRow->numRows < 1) {
            throw new AccessDeniedException('Cannot load record "' . $this->strTable . '.id=' . $this->intId . '".');
        }
        $this->objActiveRecord = $objRow;
        $return = '';
        $this->values[] = $this->intId;
        $this->procedure[] = 'id=?';
        $this->blnCreateNewVersion = false;
        $objVersions = new \Versions($this->strTable, $this->intId);
        if (!$GLOBALS['TL_DCA'][$this->strTable]['config']['hideVersionMenu']) {
            // Compare versions
            if (\Input::get('versions')) {
                $objVersions->compare();
            }
            // Restore a version
            if (\Input::post('FORM_SUBMIT') == 'tl_version' && \Input::post('version') != '') {
                $objVersions->restore(\Input::post('version'));
                $this->reload();
            }
        }
        $objVersions->initialize();
        // Build an array from boxes and rows
        $this->strPalette = $this->getPalette();
        $boxes = trimsplit(';', $this->strPalette);
        $legends = array();
        if (!empty($boxes)) {
            foreach ($boxes as $k => $v) {
                $eCount = 1;
                $boxes[$k] = trimsplit(',', $v);
                foreach ($boxes[$k] as $kk => $vv) {
                    if (preg_match('/^\\[.*\\]$/', $vv)) {
                        ++$eCount;
                        continue;
                    }
                    if (preg_match('/^\\{.*\\}$/', $vv)) {
                        $legends[$k] = substr($vv, 1, -1);
                        unset($boxes[$k][$kk]);
                    } elseif ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$vv]['exclude'] || !is_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$vv])) {
                        unset($boxes[$k][$kk]);
                    }
                }
                // Unset a box if it does not contain any fields
                if (count($boxes[$k]) < $eCount) {
                    unset($boxes[$k]);
                }
            }
            /** @var SessionInterface $objSessionBag */
            $objSessionBag = \System::getContainer()->get('session')->getBag('contao_backend');
            $class = 'tl_tbox';
            $fs = $objSessionBag->get('fieldset_states');
            $blnIsFirst = true;
            // Render boxes
            foreach ($boxes as $k => $v) {
                $strAjax = '';
                $blnAjax = false;
                $key = '';
                $cls = '';
                $legend = '';
                if (isset($legends[$k])) {
                    list($key, $cls) = explode(':', $legends[$k]);
                    $legend = "\n" . '<legend onclick="AjaxRequest.toggleFieldset(this,\'' . $key . '\',\'' . $this->strTable . '\')">' . (isset($GLOBALS['TL_LANG'][$this->strTable][$key]) ? $GLOBALS['TL_LANG'][$this->strTable][$key] : $key) . '</legend>';
                }
                if (isset($fs[$this->strTable][$key])) {
                    $class .= $fs[$this->strTable][$key] ? '' : ' collapsed';
                } else {
                    $class .= $cls && $legend ? ' ' . $cls : '';
                }
                $return .= "\n\n" . '<fieldset' . ($key ? ' id="pal_' . $key . '"' : '') . ' class="' . $class . ($legend ? '' : ' nolegend') . '">' . $legend;
                // Build rows of the current box
                foreach ($v as $vv) {
                    if ($vv == '[EOF]') {
                        if ($blnAjax && \Environment::get('isAjaxRequest')) {
                            return $strAjax . '<input type="hidden" name="FORM_FIELDS[]" value="' . specialchars($this->strPalette) . '">';
                        }
                        $blnAjax = false;
                        $return .= "\n" . '</div>';
                        continue;
                    }
                    if (preg_match('/^\\[.*\\]$/', $vv)) {
                        $thisId = 'sub_' . substr($vv, 1, -1);
                        $blnAjax = $ajaxId == $thisId && \Environment::get('isAjaxRequest') ? true : false;
                        $return .= "\n" . '<div id="' . $thisId . '">';
                        continue;
                    }
                    $this->strField = $vv;
                    $this->strInputName = $vv;
                    $this->varValue = $objRow->{$vv};
                    // Autofocus the first field
                    if ($blnIsFirst && $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['inputType'] == 'text') {
                        $GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['autofocus'] = 'autofocus';
                        $blnIsFirst = false;
                    }
                    // Convert CSV fields (see #2890)
                    if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['multiple'] && isset($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['csv'])) {
                        $this->varValue = trimsplit($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['eval']['csv'], $this->varValue);
                    }
                    // Call load_callback
                    if (is_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['load_callback'])) {
                        foreach ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$this->strField]['load_callback'] as $callback) {
                            if (is_array($callback)) {
                                $this->import($callback[0]);
                                $this->varValue = $this->{$callback[0]}->{$callback[1]}($this->varValue, $this);
                            } elseif (is_callable($callback)) {
                                $this->varValue = $callback($this->varValue, $this);
                            }
                        }
                    }
                    // Re-set the current value
                    $this->objActiveRecord->{$this->strField} = $this->varValue;
                    // Build the row and pass the current palette string (thanks to Tristan Lins)
                    $blnAjax ? $strAjax .= $this->row($this->strPalette) : ($return .= $this->row($this->strPalette));
                }
                $class = 'tl_box';
                $return .= "\n" . '</fieldset>';
            }
        }
        // Versions overview
        if ($GLOBALS['TL_DCA'][$this->strTable]['config']['enableVersioning'] && !$GLOBALS['TL_DCA'][$this->strTable]['config']['hideVersionMenu']) {
            $version = $objVersions->renderDropdown();
        } else {
            $version = '';
        }
        // Submit buttons
        $arrButtons = array();
        $arrButtons['save'] = '<button type="submit" name="save" id="save" class="tl_submit" accesskey="s">' . $GLOBALS['TL_LANG']['MSC']['save'] . '</button>';
        if (!\Input::get('nb')) {
            $arrButtons['saveNclose'] = '<button type="submit" name="saveNclose" id="saveNclose" class="tl_submit" accesskey="c">' . $GLOBALS['TL_LANG']['MSC']['saveNclose'] . '</button>';
        }
        if (!\Input::get('popup') && !$GLOBALS['TL_DCA'][$this->strTable]['config']['closed'] && !$GLOBALS['TL_DCA'][$this->strTable]['config']['notCreatable']) {
            $arrButtons['saveNcreate'] = '<button type="submit" name="saveNcreate" id="saveNcreate" class="tl_submit" accesskey="n">' . $GLOBALS['TL_LANG']['MSC']['saveNcreate'] . '</button>';
        }
        if ($GLOBALS['TL_DCA'][$this->strTable]['config']['switchToEdit']) {
            $arrButtons['saveNedit'] = '<button type="submit" name="saveNedit" id="saveNedit" class="tl_submit" accesskey="e">' . $GLOBALS['TL_LANG']['MSC']['saveNedit'] . '</button>';
        }
        if (!\Input::get('popup') && ($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['mode'] == 4 || strlen($this->ptable) || $GLOBALS['TL_DCA'][$this->strTable]['config']['switchToEdit'])) {
            $arrButtons['saveNback'] = '<button type="submit" name="saveNback" id="saveNback" class="tl_submit" accesskey="g">' . $GLOBALS['TL_LANG']['MSC']['saveNback'] . '</button>';
        }
        // Call the buttons_callback (see #4691)
        if (is_array($GLOBALS['TL_DCA'][$this->strTable]['edit']['buttons_callback'])) {
            foreach ($GLOBALS['TL_DCA'][$this->strTable]['edit']['buttons_callback'] as $callback) {
                if (is_array($callback)) {
                    $this->import($callback[0]);
                    $arrButtons = $this->{$callback[0]}->{$callback[1]}($arrButtons, $this);
                } elseif (is_callable($callback)) {
                    $arrButtons = $callback($arrButtons, $this);
                }
            }
        }
        // Add the buttons and end the form
        $return .= '
</div>

<div class="tl_formbody_submit">

<div class="tl_submit_container">
  ' . implode(' ', $arrButtons) . '
</div>

</div>
</form>

<script>
  window.addEvent(\'domready\', function() {
    Theme.focusInput("' . $this->strTable . '");
  });
</script>';
        // Begin the form (-> DO NOT CHANGE THIS ORDER -> this way the onsubmit attribute of the form can be changed by a field)
        $return = $version . '
<div id="tl_buttons">' . (\Input::get('nb') ? '&nbsp;' : '
<a href="' . $this->getReferer(true) . '" class="header_back" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['backBTTitle']) . '" accesskey="b" onclick="Backend.getScrollOffset()">' . $GLOBALS['TL_LANG']['MSC']['backBT'] . '</a>') . '
</div>
' . \Message::generate() . '
<form action="' . ampersand(\Environment::get('request'), true) . '" id="' . $this->strTable . '" class="tl_form" method="post" enctype="' . ($this->blnUploadable ? 'multipart/form-data' : 'application/x-www-form-urlencoded') . '"' . (!empty($this->onsubmit) ? ' onsubmit="' . implode(' ', $this->onsubmit) . '"' : '') . '>
<div class="tl_formbody_edit">
<input type="hidden" name="FORM_SUBMIT" value="' . $this->strTable . '">
<input type="hidden" name="REQUEST_TOKEN" value="' . REQUEST_TOKEN . '">
<input type="hidden" name="FORM_FIELDS[]" value="' . specialchars($this->strPalette) . '">' . ($this->noReload ? '

<p class="tl_error">' . $GLOBALS['TL_LANG']['ERR']['general'] . '</p>' : '') . $return;
        // Reload the page to prevent _POST variables from being sent twice
        if (\Input::post('FORM_SUBMIT') == $this->strTable && !$this->noReload) {
            $arrValues = $this->values;
            array_unshift($arrValues, time());
            // Trigger the onsubmit_callback
            if (is_array($GLOBALS['TL_DCA'][$this->strTable]['config']['onsubmit_callback'])) {
                foreach ($GLOBALS['TL_DCA'][$this->strTable]['config']['onsubmit_callback'] as $callback) {
                    if (is_array($callback)) {
                        $this->import($callback[0]);
                        $this->{$callback[0]}->{$callback[1]}($this);
                    } elseif (is_callable($callback)) {
                        $callback($this);
                    }
                }
            }
            // Save the current version
            if ($this->blnCreateNewVersion) {
                $objVersions->create();
                // Call the onversion_callback
                if (is_array($GLOBALS['TL_DCA'][$this->strTable]['config']['onversion_callback'])) {
                    foreach ($GLOBALS['TL_DCA'][$this->strTable]['config']['onversion_callback'] as $callback) {
                        if (is_array($callback)) {
                            $this->import($callback[0]);
                            $this->{$callback[0]}->{$callback[1]}($this->strTable, $this->intId, $this);
                        } elseif (is_callable($callback)) {
                            $callback($this->strTable, $this->intId, $this);
                        }
                    }
                }
                $this->log('A new version of record "' . $this->strTable . '.id=' . $this->intId . '" has been created' . $this->getParentEntries($this->strTable, $this->intId), __METHOD__, TL_GENERAL);
            }
            // Set the current timestamp (-> DO NOT CHANGE THE ORDER version - timestamp)
            if ($GLOBALS['TL_DCA'][$this->strTable]['config']['dynamicPtable']) {
                $this->Database->prepare("UPDATE " . $this->strTable . " SET ptable=?, tstamp=? WHERE id=?")->execute($this->ptable, time(), $this->intId);
            } else {
                $this->Database->prepare("UPDATE " . $this->strTable . " SET tstamp=? WHERE id=?")->execute(time(), $this->intId);
            }
            // Redirect
            if (isset($_POST['saveNclose'])) {
                \Message::reset();
                \System::setCookie('BE_PAGE_OFFSET', 0, 0);
                $this->redirect($this->getReferer());
            } elseif (isset($_POST['saveNedit'])) {
                \Message::reset();
                \System::setCookie('BE_PAGE_OFFSET', 0, 0);
                $this->redirect($this->addToUrl($GLOBALS['TL_DCA'][$this->strTable]['list']['operations']['edit']['href'], false, array('s2e', 'act')));
            } elseif (isset($_POST['saveNback'])) {
                \Message::reset();
                \System::setCookie('BE_PAGE_OFFSET', 0, 0);
                if ($this->ptable == '') {
                    $this->redirect(TL_SCRIPT . '?do=' . \Input::get('do'));
                } elseif ($this->ptable == 'tl_theme' && $this->strTable == 'tl_style_sheet' || $this->ptable == 'tl_page' && $this->strTable == 'tl_article') {
                    $this->redirect($this->getReferer(false, $this->strTable));
                } else {
                    $this->redirect($this->getReferer(false, $this->ptable));
                }
            } elseif (isset($_POST['saveNcreate'])) {
                \Message::reset();
                \System::setCookie('BE_PAGE_OFFSET', 0, 0);
                $strUrl = TL_SCRIPT . '?do=' . \Input::get('do');
                if (isset($_GET['table'])) {
                    $strUrl .= '&amp;table=' . \Input::get('table');
                }
                // Tree view
                if ($this->treeView) {
                    $strUrl .= '&amp;act=create&amp;mode=1&amp;pid=' . $this->intId;
                } elseif ($GLOBALS['TL_DCA'][$this->strTable]['list']['sorting']['mode'] == 4) {
                    $strUrl .= $this->Database->fieldExists('sorting', $this->strTable) ? '&amp;act=create&amp;mode=1&amp;pid=' . $this->intId . '&amp;id=' . $this->activeRecord->pid : '&amp;act=create&amp;mode=2&amp;pid=' . $this->activeRecord->pid;
                } else {
                    $strUrl .= $this->ptable != '' ? '&amp;act=create&amp;mode=2&amp;pid=' . CURRENT_ID : '&amp;act=create';
                }
                $this->redirect($strUrl . '&amp;rt=' . REQUEST_TOKEN);
            }
            $this->reload();
        }
        // Set the focus if there is an error
        if ($this->noReload) {
            $return .= '

<script>
  window.addEvent(\'domready\', function() {
    Backend.vScrollTo(($(\'' . $this->strTable . '\').getElement(\'label.error\').getPosition().y - 20));
  });
</script>';
        }
        return $return;
    }
All Usage Examples Of Contao\Versions::compare