The class parses the DCA files and stores various extracts like relations in the cache directory. This meta data can then be loaded and used in the application (e.g. the Model classes). Usage: $user = DcaExtractor::getInstance('tl_user'); if ($user->hasRelations()) { print_r($user->getRelations()); }
Наследование: extends Controller
Пример #1
0
    /**
     * Return all non-excluded fields of a record as HTML table
     *
     * @return string
     */
    public function show()
    {
        if (!strlen($this->intId)) {
            return '';
        }
        $objRow = $this->Database->prepare("SELECT * FROM " . $this->strTable . " WHERE id=?")->limit(1)->execute($this->intId);
        if ($objRow->numRows < 1) {
            return '';
        }
        $count = 1;
        $return = '';
        $row = $objRow->row();
        // Get the order fields
        $objDcaExtractor = \DcaExtractor::getInstance($this->strTable);
        $arrOrder = $objDcaExtractor->getOrderFields();
        // Get all fields
        $fields = array_keys($row);
        $allowedFields = array('id', 'pid', 'sorting', 'tstamp');
        if (is_array($GLOBALS['TL_DCA'][$this->strTable]['fields'])) {
            $allowedFields = array_unique(array_merge($allowedFields, array_keys($GLOBALS['TL_DCA'][$this->strTable]['fields'])));
        }
        // Use the field order of the DCA file
        $fields = array_intersect($allowedFields, $fields);
        // Show all allowed fields
        foreach ($fields as $i) {
            if (!in_array($i, $allowedFields) || $GLOBALS['TL_DCA'][$this->strTable]['fields'][$i]['inputType'] == 'password' || $GLOBALS['TL_DCA'][$this->strTable]['fields'][$i]['eval']['doNotShow'] || $GLOBALS['TL_DCA'][$this->strTable]['fields'][$i]['eval']['hideInput']) {
                continue;
            }
            // Special treatment for table tl_undo
            if ($this->strTable == 'tl_undo' && $i == 'data') {
                continue;
            }
            $value = deserialize($row[$i]);
            // Decrypt the value
            if ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$i]['eval']['encrypt']) {
                $value = \Encryption::decrypt($value);
            }
            $class = $count++ % 2 == 0 ? ' class="tl_bg"' : '';
            // Get the field value
            if (isset($GLOBALS['TL_DCA'][$this->strTable]['fields'][$i]['foreignKey'])) {
                $temp = array();
                $chunks = explode('.', $GLOBALS['TL_DCA'][$this->strTable]['fields'][$i]['foreignKey'], 2);
                foreach ((array) $value as $v) {
                    $objKey = $this->Database->prepare("SELECT " . $chunks[1] . " AS value FROM " . $chunks[0] . " WHERE id=?")->limit(1)->execute($v);
                    if ($objKey->numRows) {
                        $temp[] = $objKey->value;
                    }
                }
                $row[$i] = implode(', ', $temp);
            } elseif ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$i]['inputType'] == 'fileTree' || in_array($i, $arrOrder)) {
                if (is_array($value)) {
                    foreach ($value as $kk => $vv) {
                        $value[$kk] = $vv ? \StringUtil::binToUuid($vv) : '';
                    }
                    $row[$i] = implode(', ', $value);
                } else {
                    $row[$i] = $value ? \StringUtil::binToUuid($value) : '';
                }
            } elseif (is_array($value)) {
                foreach ($value as $kk => $vv) {
                    if (is_array($vv)) {
                        $vals = array_values($vv);
                        $value[$kk] = $vals[0] . ' (' . $vals[1] . ')';
                    }
                }
                $row[$i] = implode(', ', $value);
            } elseif ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$i]['eval']['rgxp'] == 'date') {
                $row[$i] = $value ? \Date::parse(\Config::get('dateFormat'), $value) : '-';
            } elseif ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$i]['eval']['rgxp'] == 'time') {
                $row[$i] = $value ? \Date::parse(\Config::get('timeFormat'), $value) : '-';
            } elseif ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$i]['eval']['rgxp'] == 'datim' || in_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$i]['flag'], array(5, 6, 7, 8, 9, 10)) || $i == 'tstamp') {
                $row[$i] = $value ? \Date::parse(\Config::get('datimFormat'), $value) : '-';
            } elseif ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$i]['inputType'] == 'checkbox' && !$GLOBALS['TL_DCA'][$this->strTable]['fields'][$i]['eval']['multiple']) {
                $row[$i] = $value != '' ? $GLOBALS['TL_LANG']['MSC']['yes'] : $GLOBALS['TL_LANG']['MSC']['no'];
            } elseif ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$i]['inputType'] == 'textarea' && ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$i]['eval']['allowHtml'] || $GLOBALS['TL_DCA'][$this->strTable]['fields'][$i]['eval']['preserveTags'])) {
                $row[$i] = specialchars($value);
            } elseif (is_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$i]['reference'])) {
                $row[$i] = isset($GLOBALS['TL_DCA'][$this->strTable]['fields'][$i]['reference'][$row[$i]]) ? is_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$i]['reference'][$row[$i]]) ? $GLOBALS['TL_DCA'][$this->strTable]['fields'][$i]['reference'][$row[$i]][0] : $GLOBALS['TL_DCA'][$this->strTable]['fields'][$i]['reference'][$row[$i]] : $row[$i];
            } elseif ($GLOBALS['TL_DCA'][$this->strTable]['fields'][$i]['eval']['isAssociative'] || array_is_assoc($GLOBALS['TL_DCA'][$this->strTable]['fields'][$i]['options'])) {
                $row[$i] = $GLOBALS['TL_DCA'][$this->strTable]['fields'][$i]['options'][$row[$i]];
            } else {
                $row[$i] = $value;
            }
            // Label
            if (isset($GLOBALS['TL_DCA'][$this->strTable]['fields'][$i]['label'])) {
                $label = is_array($GLOBALS['TL_DCA'][$this->strTable]['fields'][$i]['label']) ? $GLOBALS['TL_DCA'][$this->strTable]['fields'][$i]['label'][0] : $GLOBALS['TL_DCA'][$this->strTable]['fields'][$i]['label'];
            } else {
                $label = is_array($GLOBALS['TL_LANG']['MSC'][$i]) ? $GLOBALS['TL_LANG']['MSC'][$i][0] : $GLOBALS['TL_LANG']['MSC'][$i];
            }
            if ($label == '') {
                $label = $i;
            }
            $return .= '
  <tr>
    <td' . $class . '><span class="tl_label">' . $label . ': </span></td>
    <td' . $class . '>' . $row[$i] . '</td>
  </tr>';
        }
        // Special treatment for tl_undo
        if ($this->strTable == 'tl_undo') {
            $arrData = deserialize($objRow->data);
            foreach ($arrData as $strTable => $arrTableData) {
                \System::loadLanguageFile($strTable);
                $this->loadDataContainer($strTable);
                foreach ($arrTableData as $arrRow) {
                    $count = 0;
                    $return .= '
  <tr>
    <td colspan="2" style="padding:0"><div style="margin-bottom:26px;line-height:24px;border-bottom:1px dotted #ccc">&nbsp;</div></td>
  </tr>';
                    foreach ($arrRow as $i => $v) {
                        if (is_array(deserialize($v))) {
                            continue;
                        }
                        $class = $count++ % 2 == 0 ? ' class="tl_bg"' : '';
                        // Get the field label
                        if (isset($GLOBALS['TL_DCA'][$strTable]['fields'][$i]['label'])) {
                            $label = is_array($GLOBALS['TL_DCA'][$strTable]['fields'][$i]['label']) ? $GLOBALS['TL_DCA'][$strTable]['fields'][$i]['label'][0] : $GLOBALS['TL_DCA'][$strTable]['fields'][$i]['label'];
                        } else {
                            $label = is_array($GLOBALS['TL_LANG']['MSC'][$i]) ? $GLOBALS['TL_LANG']['MSC'][$i][0] : $GLOBALS['TL_LANG']['MSC'][$i];
                        }
                        if (!strlen($label)) {
                            $label = $i;
                        }
                        // Always encode special characters (thanks to Oliver Klee)
                        $return .= '
  <tr>
    <td' . $class . '><span class="tl_label">' . $label . ': </span></td>
    <td' . $class . '>' . specialchars($v) . '</td>
  </tr>';
                    }
                }
            }
        }
        // Return table
        return '
<div id="tl_buttons">' . (!\Input::get('popup') ? '
<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>

<table class="tl_show">' . $return . '
</table>';
    }
Пример #2
0
 /**
  * Compare versions
  */
 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 ($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());
 }
Пример #3
0
 /**
  * Generates the DCA extracts.
  *
  * @param string $cacheDir
  */
 private function generateDcaExtracts($cacheDir)
 {
     $processed = [];
     /** @var SplFileInfo[] $files */
     $files = $this->finder->findIn('dca')->files()->name('*.php');
     foreach ($files as $file) {
         if (in_array($file->getBasename(), $processed)) {
             continue;
         }
         $processed[] = $file->getBasename();
         $table = $file->getBasename('.php');
         $extract = DcaExtractor::getInstance($table);
         if (!$extract->isDbTable()) {
             continue;
         }
         $this->filesystem->dumpFile(sprintf('%s/contao/sql/%s.php', $cacheDir, $table), sprintf("<?php\n\n%s\n\n%s\n\n%s\n\n%s\n\n%s\n\n\$this->blnIsDbTable = true;\n", sprintf('$this->arrMeta = %s;', var_export($extract->getMeta(), true)), sprintf('$this->arrFields = %s;', var_export($extract->getFields(), true)), sprintf('$this->arrOrderFields = %s;', var_export($extract->getOrderFields(), true)), sprintf('$this->arrKeys = %s;', var_export($extract->getKeys(), true)), sprintf('$this->arrRelations = %s;', var_export($extract->getRelations(), true))));
     }
 }
 /**
  * Returns the target database structure from the DCA.
  *
  * @return array An array of tables and fields
  */
 private function getFromDca()
 {
     $return = [];
     $processed = [];
     /** @var SplFileInfo[] $files */
     $files = $this->finder->findIn('dca')->depth(0)->files()->name('*.php');
     foreach ($files as $file) {
         if (in_array($file->getBasename(), $processed)) {
             continue;
         }
         $processed[] = $file->getBasename();
         $table = $file->getBasename('.php');
         $extract = DcaExtractor::getInstance($table);
         if ($extract->isDbTable()) {
             $return[$table] = $extract->getDbInstallerArray();
         }
     }
     ksort($return);
     return $return;
 }
Пример #5
0
 /**
  * Add the table tl_files to the XML and the files to the archive
  * @param \DOMDocument           $xml
  * @param \DOMNode|\DOMElement   $tables
  * @param Database\Result|object $objTheme
  * @param ZipWriter              $objArchive
  */
 protected function addTableTlFiles(\DOMDocument $xml, \DOMElement $tables, Database\Result $objTheme, ZipWriter $objArchive)
 {
     // Add the table
     $table = $xml->createElement('table');
     $table->setAttribute('name', 'tl_files');
     $table = $tables->appendChild($table);
     // Load the DCA
     $this->loadDataContainer('tl_files');
     // Get the order fields
     $objDcaExtractor = \DcaExtractor::getInstance('tl_files');
     $arrOrder = $objDcaExtractor->getOrderFields();
     // Add the folders
     $arrFolders = \StringUtil::deserialize($objTheme->folders);
     if (!empty($arrFolders) && is_array($arrFolders)) {
         $objFolders = \FilesModel::findMultipleByUuids($arrFolders);
         if ($objFolders !== null) {
             foreach ($this->eliminateNestedPaths($objFolders->fetchEach('path')) as $strFolder) {
                 $this->addFolderToArchive($objArchive, $strFolder, $xml, $table, $arrOrder);
             }
         }
     }
 }