shop.balmet.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

1000.php (10078B)


      1 <?php
      2 class ModelUpgrade1000 extends Model {
      3 	public function upgrade() {
      4 		// This is a generic upgrade script.
      5 		// It makes mass changes to the DB by creating tables that are not in the current db, changes the charset and DB engine to the SQL schema.
      6 		// The uprade script is not coherent because of the changes over time to the upgrades so im grouping the changes into different files
      7 		// Future version should have a upgrade file name that matches the version number being changed to
      8 
      9 		// Load the sql file
     10 		$file = DIR_APPLICATION . 'opencart.sql';
     11 
     12 		if (!file_exists($file)) {
     13 			exit('Could not load sql file: ' . $file);
     14 		}
     15 
     16 		$string = '';
     17 
     18 		$lines = file($file);
     19 
     20 		$status = false;
     21 
     22 		// Get only the create statements
     23 		foreach($lines as $line) {
     24 			// Set any prefix
     25 			$line = str_replace("DROP TABLE IF EXISTS `oc_", "DROP TABLE IF EXISTS `" . DB_PREFIX, $line);
     26 
     27 			$line = str_replace("CREATE TABLE IF NOT EXISTS `oc_", "CREATE TABLE `" . DB_PREFIX, $line);
     28 
     29 			$line = str_replace("CREATE TABLE `oc_", "CREATE TABLE `" . DB_PREFIX, $line);
     30 
     31 			// If line begins with create table we want to start recording
     32 			if (substr($line, 0, 12) == 'CREATE TABLE') {
     33 				$status = true;
     34 			}
     35 
     36 			if ($status) {
     37 				$string .= $line;
     38 			}
     39 
     40 			// If line contains with ; we want to stop recording
     41 			if (preg_match('/;/', $line)) {
     42 				$status = false;
     43 			}
     44 		}
     45 
     46 		$table_new_data = array();
     47 
     48 		// Trim any spaces
     49 		$string = trim($string);
     50 
     51 		// Trim any ;
     52 		$string = trim($string, ';');
     53 
     54 		// Start reading each create statement
     55 		$statements = explode(';', $string);
     56 
     57 		foreach ($statements as $sql) {
     58 			// Get all fields
     59 			$field_data = array();
     60 
     61 			preg_match_all('#`(\w[\w\d]*)`\s+((tinyint|smallint|mediumint|bigint|int|tinytext|text|mediumtext|longtext|tinyblob|blob|mediumblob|longblob|varchar|char|datetime|date|float|double|decimal|timestamp|time|year|enum|set|binary|varbinary)(\((.*)\))?){1}\s*(collate (\w+)\s*)?(unsigned\s*)?((NOT\s*NULL\s*)|(NULL\s*))?(auto_increment\s*)?(default \'([^\']*)\'\s*)?#i', $sql, $match);
     62 
     63 			foreach(array_keys($match[0]) as $key) {
     64 				$field_data[] = array(
     65 					'name'          => trim($match[1][$key]),
     66 					'type'          => strtoupper(trim($match[3][$key])),
     67 					'size'          => str_replace(array('(', ')'), '', trim($match[4][$key])),
     68 					'sizeext'       => trim($match[6][$key]),
     69 					'collation'     => trim($match[7][$key]),
     70 					'unsigned'      => trim($match[8][$key]),
     71 					'notnull'       => trim($match[9][$key]),
     72 					'autoincrement' => trim($match[12][$key]),
     73 					'default'       => trim($match[14][$key])
     74 				);
     75 			}
     76 
     77 			// Get primary keys
     78 			$primary_data = array();
     79 
     80 			preg_match('#primary\s*key\s*\([^)]+\)#i', $sql, $match);
     81 
     82 			if (isset($match[0])) {
     83 				preg_match_all('#`(\w[\w\d]*)`#', $match[0], $match);
     84 			} else{
     85 				$match = array();
     86 			}
     87 
     88 			if ($match) {
     89 				foreach($match[1] as $primary) {
     90 					$primary_data[] = $primary;
     91 				}
     92 			}
     93 
     94 			// Get indexes
     95 			$index_data = array();
     96 
     97 			$indexes = array();
     98 
     99 			preg_match_all('#key\s*`\w[\w\d]*`\s*\(.*\)#i', $sql, $match);
    100 
    101 			foreach($match[0] as $key) {
    102 				preg_match_all('#`(\w[\w\d]*)`#', $key, $match);
    103 
    104 				$indexes[] = $match;
    105 			}
    106 
    107 			foreach($indexes as $index) {
    108 				$key = '';
    109 
    110 				foreach($index[1] as $field) {
    111 					if ($key == '') {
    112 						$key = $field;
    113 					} else{
    114 						$index_data[$key][] = $field;
    115 					}
    116 				}
    117 			}
    118 
    119 			// Table options
    120 			$option_data = array();
    121 
    122 			preg_match_all('#(\w+)=\'?(\w+\~?\w+)\'?#', $sql, $option);
    123 
    124 			foreach(array_keys($option[0]) as $key) {
    125 				$option_data[$option[1][$key]] = $option[2][$key];
    126 			}
    127 
    128 			// Get Table Name
    129 			preg_match_all('#create\s*table\s*`(\w[\w\d]*)`#i', $sql, $table);
    130 
    131 			if (isset($table[1][0])) {
    132 				$table_new_data[] = array(
    133 					'sql'     => $sql,
    134 					'name'    => $table[1][0],
    135 					'field'   => $field_data,
    136 					'primary' => $primary_data,
    137 					'index'   => $index_data,
    138 					'option'  => $option_data
    139 				);
    140 			}
    141 		}
    142 
    143 		// Get all current tables, fields, type, size, etc..
    144 		$table_old_data = array();
    145 
    146 		$table_query = $this->db->query("SHOW TABLES FROM `" . DB_DATABASE . "`");
    147 
    148 		foreach ($table_query->rows as $table) {
    149 			if (utf8_substr($table['Tables_in_' . DB_DATABASE], 0, strlen(DB_PREFIX)) == DB_PREFIX) {
    150 				$field_data = array();
    151 				$extended_field_data = array();
    152 
    153 				$field_query = $this->db->query("SHOW COLUMNS FROM `" . $table['Tables_in_' . DB_DATABASE] . "`");
    154 
    155 				foreach ($field_query->rows as $field) {
    156 					$field_data[] = $field['Field'];
    157 					$extended_field_data[] = $field;
    158 				}
    159 
    160 				$table_old_data[$table['Tables_in_' . DB_DATABASE]]['field_list'] = $field_data;
    161 				$table_old_data[$table['Tables_in_' . DB_DATABASE]]['extended_field_data'] = $extended_field_data;
    162 			}
    163 		}
    164 
    165 		foreach ($table_new_data as $table) {
    166 			// If table is not found create it
    167 			if (!isset($table_old_data[$table['name']])) {
    168 				$this->db->query($table['sql']);
    169 			} else {
    170 				// DB Engine
    171 				if (isset($table['option']['ENGINE'])) {
    172 					$this->db->query("ALTER TABLE `" . $table['name'] . "` ENGINE = `" . $table['option']['ENGINE'] . "`");
    173 				}
    174 
    175 				// Charset
    176 				if (isset($table['option']['CHARSET']) && isset($table['option']['COLLATE'])) {
    177 					$this->db->query("ALTER TABLE `" . $table['name'] . "` DEFAULT CHARACTER SET `" . $table['option']['CHARSET'] . "` COLLATE `" . $table['option']['COLLATE'] . "`");
    178 				}
    179 
    180 				// Loop through all tables and adjust based on opencart.sql file
    181 				$i = 0;
    182 
    183 				foreach ($table['field'] as $field) {
    184 
    185 					// If field is not found create it
    186 					if (!in_array($field['name'], $table_old_data[$table['name']]['field_list'])) {
    187 
    188 						$status = true;
    189 						foreach ($table_old_data[$table['name']]['extended_field_data'] as $oldfield) {
    190 							if ($oldfield['Extra'] == 'auto_increment' && $field['autoincrement']) {
    191 								$sql = "ALTER TABLE `" . $table['name'] . "` CHANGE `" . $oldfield['Field'] . "` `" . $field['name'] . "` " . strtoupper($field['type']);
    192 								$status = false;
    193 								break;
    194 							}
    195 						}
    196 
    197 						if ($status) {
    198 							$sql = "ALTER TABLE `" . $table['name'] . "` ADD `" . $field['name'] . "` " . $field['type'];
    199 						}
    200 
    201 						if ($field['size']) {
    202 							$sql .= "(" . $field['size'] . ")";
    203 						}
    204 
    205 						if ($field['collation']) {
    206 							$sql .= " " . $field['collation'];
    207 						}
    208 
    209 						if ($field['unsigned']) {
    210 							$sql .= " " . $field['unsigned'];
    211 						}
    212 
    213 						if ($field['notnull']) {
    214 							$sql .= " " . $field['notnull'];
    215 						}
    216 
    217 						if ($field['default'] != '') {
    218 							$sql .= " DEFAULT '" . $field['default'] . "'";
    219 						}
    220 
    221 						if (isset($table['field'][$i - 1])) {
    222 							$sql .= " AFTER `" . $table['field'][$i - 1]['name'] . "`";
    223 						} else {
    224 							$sql .= " FIRST";
    225 						}
    226 
    227 						$this->db->query($sql);
    228 					} else {
    229 						// Remove auto increment from all fields
    230 						$sql = "ALTER TABLE `" . $table['name'] . "` CHANGE `" . $field['name'] . "` `" . $field['name'] . "` " . strtoupper($field['type']);
    231 
    232 						if ($field['size']) {
    233 							$sql .= "(" . $field['size'] . ")";
    234 						}
    235 
    236 						if ($field['collation']) {
    237 							$sql .= " " . $field['collation'];
    238 						}
    239 
    240 						if ($field['unsigned']) {
    241 							$sql .= " " . $field['unsigned'];
    242 						}
    243 
    244 						if ($field['notnull']) {
    245 							$sql .= " " . $field['notnull'];
    246 						}
    247 
    248 						if ($field['default'] != '') {
    249 							$sql .= " DEFAULT '" . $field['default'] . "'";
    250 						}
    251 
    252 						if (isset($table['field'][$i - 1])) {
    253 							$sql .= " AFTER `" . $table['field'][$i - 1]['name'] . "`";
    254 						} else {
    255 							$sql .= " FIRST";
    256 						}
    257 
    258 						$this->db->query($sql);
    259 					}
    260 
    261 					$i++;
    262 				}
    263 
    264 				$status = false;
    265 
    266 				// Drop primary keys and indexes.
    267 				$query = $this->db->query("SHOW INDEXES FROM `" . $table['name'] . "`");
    268 
    269 				$last_key_name = '';
    270 				if ($query->num_rows) {
    271 					foreach ($query->rows as $result) {
    272 						if ($result['Key_name'] != 'PRIMARY' && $result['Key_name'] != $last_key_name) {
    273 							$last_key_name = $result['Key_name'];
    274 							$this->db->query("ALTER TABLE `" . $table['name'] . "` DROP INDEX `" . $result['Key_name'] . "`");
    275 						} else {
    276 							$status = true;
    277 						}
    278 					}
    279 				}
    280 
    281 				if ($status) {
    282 					$this->db->query("ALTER TABLE `" . $table['name'] . "` DROP PRIMARY KEY");
    283 				}
    284 
    285 				// Add a new primary key.
    286 				$primary_data = array();
    287 
    288 				foreach ($table['primary'] as $primary) {
    289 					$primary_data[] = "`" . $primary . "`";
    290 				}
    291 
    292 				if ($primary_data) {
    293 					$this->db->query("ALTER TABLE `" . $table['name'] . "` ADD PRIMARY KEY(" . implode(',', $primary_data) . ")");
    294 				}
    295 
    296 				// Add the new indexes
    297 				foreach ($table['index'] as $name => $index) {
    298 					$index_data = array();
    299 
    300 					foreach ($index as $key) {
    301 						$index_data[] = '`' . $key . '`';
    302 					}
    303 
    304 					if ($index_data) {
    305 						$this->db->query("ALTER TABLE `" . $table['name'] . "` ADD INDEX `$name` (" . implode(',', $index_data) . ")");
    306 					}
    307 				}
    308 
    309 				// Add auto increment to primary keys again
    310 				foreach ($table['field'] as $field) {
    311 					if ($field['autoincrement']) {
    312 						$sql = "ALTER TABLE `" . $table['name'] . "` CHANGE `" . $field['name'] . "` `" . $field['name'] . "` " . strtoupper($field['type']);
    313 
    314 						if ($field['size']) {
    315 							$sql .= "(" . $field['size'] . ")";
    316 						}
    317 
    318 						if ($field['collation']) {
    319 							$sql .= " " . $field['collation'];
    320 						}
    321 
    322 						if ($field['unsigned']) {
    323 							$sql .= " " . $field['unsigned'];
    324 						}
    325 
    326 						if ($field['notnull']) {
    327 							$sql .= " " . $field['notnull'];
    328 						}
    329 
    330 						if ($field['default'] != '') {
    331 							$sql .= " DEFAULT '" . $field['default'] . "'";
    332 						}
    333 
    334 						if ($field['autoincrement']) {
    335 							$sql .= " AUTO_INCREMENT";
    336 						}
    337 
    338 						$this->db->query($sql);
    339 					}
    340 				}
    341 			}
    342 		}
    343 	}
    344 }