/**
  * Returns the target database structure from the database.sql files.
  *
  * @return array An array of tables and fields
  */
 private function getFromFile()
 {
     $return = [];
     /** @var SplFileInfo[] $files */
     $files = $this->finder->findIn('config')->depth(0)->files()->name('database.sql');
     foreach ($files as $file) {
         $return = array_merge_recursive($return, SqlFileParser::parse($file));
     }
     ksort($return);
     return $return;
 }
Example #2
0
 /**
  * Create the extract from the DCA or the database.sql files
  */
 protected function createExtract()
 {
     // Load the default language file (see #7202)
     if (empty($GLOBALS['TL_LANG']['MSC'])) {
         System::loadLanguageFile('default');
     }
     // Load the data container
     if (!isset($GLOBALS['loadDataContainer'][$this->strTable])) {
         $this->loadDataContainer($this->strTable);
     }
     // Return if the DC type is "File"
     if ($GLOBALS['TL_DCA'][$this->strTable]['config']['dataContainer'] == 'File') {
         return;
     }
     $blnFromFile = false;
     $arrRelations = array();
     // Check whether there are fields (see #4826)
     if (isset($GLOBALS['TL_DCA'][$this->strTable]['fields'])) {
         foreach ($GLOBALS['TL_DCA'][$this->strTable]['fields'] as $field => $config) {
             // Check whether all fields have an SQL definition
             if (!isset($config['sql']) && isset($config['inputType'])) {
                 $blnFromFile = true;
             }
             // Check whether there is a relation (see #6524)
             if (isset($config['relation'])) {
                 $table = substr($config['foreignKey'], 0, strrpos($config['foreignKey'], '.'));
                 $arrRelations[$field] = array_merge(array('table' => $table, 'field' => 'id'), $config['relation']);
                 // Table name and field name are mandatory
                 if (empty($arrRelations[$field]['table']) || empty($arrRelations[$field]['field'])) {
                     throw new \Exception('Incomplete relation defined for ' . $this->strTable . '.' . $field);
                 }
             }
         }
     }
     $sql = $GLOBALS['TL_DCA'][$this->strTable]['config']['sql'] ?: array();
     $fields = $GLOBALS['TL_DCA'][$this->strTable]['fields'] ?: array();
     // Deprecated since Contao 4.0, to be removed in Contao 5.0
     if ($blnFromFile) {
         trigger_error('Using database.sql files has been deprecated and will no longer work in Contao 5.0. Use a DCA file instead.', E_USER_DEPRECATED);
         if (!isset(static::$arrSql[$this->strTable])) {
             try {
                 /** @var SplFileInfo[] $files */
                 $files = \System::getContainer()->get('contao.resource_locator')->locate('config/database.sql', null, false);
             } catch (\InvalidArgumentException $e) {
                 return array();
             }
             $arrSql = array();
             foreach ($files as $file) {
                 $arrSql = array_merge_recursive($arrSql, \SqlFileParser::parse($file));
             }
             static::$arrSql = $arrSql;
         }
         $arrTable = static::$arrSql[$this->strTable];
         list($engine, , $charset) = explode(' ', trim($arrTable['TABLE_OPTIONS']));
         if ($engine != '') {
             $sql['engine'] = str_replace('ENGINE=', '', $engine);
         }
         if ($charset != '') {
             $sql['charset'] = str_replace('CHARSET=', '', $charset);
         }
         // Fields
         if (isset($arrTable['TABLE_FIELDS'])) {
             foreach ($arrTable['TABLE_FIELDS'] as $k => $v) {
                 $fields[$k]['sql'] = str_replace('`' . $k . '` ', '', $v);
             }
         }
         // Keys
         if (isset($arrTable['TABLE_CREATE_DEFINITIONS'])) {
             foreach ($arrTable['TABLE_CREATE_DEFINITIONS'] as $strKey) {
                 if (preg_match('/^([A-Z]+ )?KEY .+\\(([^)]+)\\)$/', $strKey, $arrMatches) && preg_match_all('/`([^`]+)`/', $arrMatches[2], $arrFields)) {
                     $type = trim($arrMatches[1]);
                     $field = implode(',', $arrFields[1]);
                     $sql['keys'][$field] = $type != '' ? strtolower($type) : 'index';
                 }
             }
         }
     }
     // Not a database table or no field information
     if (empty($sql) || empty($fields)) {
         return;
     }
     // Add the default engine and charset if none is given
     if (empty($sql['engine'])) {
         $sql['engine'] = 'MyISAM';
     }
     if (empty($sql['charset'])) {
         $sql['charset'] = \Config::get('dbCharset');
     }
     // Meta
     $this->arrMeta = array('engine' => $sql['engine'], 'charset' => $sql['charset']);
     // Fields
     if (!empty($fields)) {
         $this->arrFields = array();
         $this->arrOrderFields = array();
         foreach ($fields as $field => $config) {
             if (isset($config['sql'])) {
                 $this->arrFields[$field] = $config['sql'];
             }
             // Only add order fields of binary fields (see #7785)
             if (isset($config['inputType']) && $config['inputType'] == 'fileTree' && isset($config['eval']['orderField'])) {
                 $this->arrOrderFields[] = $config['eval']['orderField'];
             }
             if (isset($config['eval']['unique']) && $config['eval']['unique']) {
                 $this->arrUniqueFields[] = $field;
             }
         }
     }
     // Keys
     if (!empty($sql['keys']) && is_array($sql['keys'])) {
         $this->arrKeys = array();
         foreach ($sql['keys'] as $field => $type) {
             $this->arrKeys[$field] = $type;
             if ($type == 'unique') {
                 $this->arrUniqueFields[] = $field;
             }
         }
     }
     // Relations
     if (!empty($arrRelations)) {
         $this->arrRelations = array();
         foreach ($arrRelations as $field => $config) {
             $this->arrRelations[$field] = array();
             foreach ($config as $k => $v) {
                 $this->arrRelations[$field][$k] = $v;
             }
         }
     }
     $this->arrUniqueFields = array_unique($this->arrUniqueFields);
     $this->blnIsDbTable = true;
 }