public function version($version = 0)
{
$output = '';
if ($version == 0) {
$files = glob($this->migrations_path . "*" . EXT);
$version = count($files);
}
$schema_version = $this->_get_db_schema_version();
$start = $schema_version;
$stop = $version;
if ($version > $schema_version) {
// Moving Up to the east side
$start++;
$stop++;
$step = 1;
} else {
// Moving Down
$step = -1;
}
$method = $step == 1 ? 'up' : 'down';
$migrations = array();
// We now prepare to actually DO the migrations
// But first let's make sure that everything is the way it should be
for ($i = $start; $i != $stop; $i += $step) {
$f = glob(sprintf($this->migrations_path . '%03d_*.php', $i));
// Only one migration per step is permitted
if (count($f) > 1) {
$this->error = sprintf($this->_ci->lang->line("multiple_migrations_version"), $i);
return 0;
}
// Migration step not found
if (count($f) == 0) {
// If trying to migrate up to a version greater than the last
// existing one, migrate to the last one.
if ($step == 1) {
break;
}
// If trying to migrate down but we're missing a step,
// something must definitely be wrong.
$this->error = sprintf($this->_ci->lang->line("migration_not_found"), $i);
return 0;
}
$file = basename($f[0]);
$name = basename($f[0], EXT);
// Filename validations
if (preg_match('/^\\d{3}_(\\w+)$/', $name, $match)) {
$match[1] = strtolower($match[1]);
// Cannot repeat a migration at different steps
if (in_array($match[1], $migrations)) {
$this->error = sprintf($this->_ci->lang->line("multiple_migrations_name"), $match[1]);
return 0;
}
include $f[0];
$class = ucfirst($match[1]);
if (!class_exists($class)) {
$this->error = sprintf($this->_ci->lang->line("migration_class_doesnt_exist"), $class);
return 0;
}
if (!is_callable(array($class, "up")) or !is_callable(array($class, "down"))) {
$this->error = sprintf($this->_ci->lang->line('wrong_migration_interface'), $class);
return 0;
}
$migrations[] = $match[1];
} else {
$this->error = sprintf($this->_ci->lang->line("invalid_migration_filename"), $file);
return 0;
}
}
$version = $i + ($step == 1 ? -1 : 0);
// If there is any migration to proccess
if (count($migrations)) {
if ($this->verbose) {
$output .= "<p>Current db schema version: " . $schema_version . "<br/>";
$output .= "Moving " . $method . " to version " . $version . "</p>";
$output .= "<hr/>";
}
// Loop Through the migrations
foreach ($migrations as $m) {
if ($this->verbose) {
$output .= "{$m}:<br />";
$output .= "<blockquote>";
}
$class = ucfirst($m);
// As of 5.2.3
$myobject = new $class();
$output .= call_user_func(array($myobject, $method));
if ($this->verbose) {
$output .= "</blockquote>";
$output .= "<hr/>";
}
$schema_version += $step;
$this->_update_schema_version($schema_version);
}
if ($this->verbose) {
$output .= sprintf(lang('all_done'), $schema_version);
}
} else {
if ($this->verbose) {
$output .= lang('nothing_to_do');
}
}
return $output;
}