migrate up to the next version

@param   mixed	version to migrate up to
@param   string  name of the package, module or app
@param   string  type of migration (package, module or app)

@return	array
978603
public static function up($version = null, $name = 'default', $type = 'app')
	{
		// get the current version info from the config
		$current = \Config::get('migrations.version.'.$type.'.'.$name);

		// get the last migration installed
		$current = empty($current) ? null : end($current);

		// get the available migrations after the current one
		$migrations = static::find_migrations($name, $type, $current, $version);

		// found any?
		if ( ! empty($migrations))
		{
			// if no version was given, only install the next migration
			is_null($version) and $migrations = array(reset($migrations));

			// install migrations found
			return static::run($migrations, $name, $type, 'up');
		}

		// nothing to migrate
		return array();
	}
1082978
public function upgrade( $version ) {

		if ( $version < 1 ) {
			// Upgrade from version 0 (closed source service) to version 1 (initial open source offering)
			$this->upgradeEcommerce();
			$this->upgradeBookInformation();
			$this->upgradeBook();
		}
		if ( $version < 3 ) {
			\Pressbooks\CustomCss::upgradeCustomCss();
		}
		if ( $version < 4 ) {
			$this->fixDoubleSlashBug();
		}
		if ( $version < 5 ) {
			$this->changeDefaultBookCover();
		}
		if ( $version < 6 || $version < 7 ) {
			$this->makeThumbnailsForBookCover();
		}
		if ( $version < 8 ) {
			$this->resetLandingPage();
		}
		if ( $version < 10 ) {
			$taxonomy = Taxonomy::init();
			$taxonomy->insertTerms();
			flush_rewrite_rules( false );
		}
		if ( $version < 11 ) {
			$this->migratePartContentToEditor();
		}
		if ( $version < 12 ) {
			Container::get( 'Styles' )->initPosts();
		}
		if ( $version < 13 ) {
			$this->upgradeToPressbooksFive();
		}
	}
873827
public function getMigrations($environment)
    {
        if ($this->migrations === null) {
            $phpFiles = $this->getMigrationFiles();

            if ($this->getOutput()->getVerbosity() >= OutputInterface::VERBOSITY_DEBUG) {
                $this->getOutput()->writeln('Migration file');
                $this->getOutput()->writeln(
                    array_map(
                        function ($phpFile) {
                            return "    <info>{$phpFile}</info>";
                        },
                        $phpFiles
                    )
                );
            }

            // filter the files to only get the ones that match our naming scheme
            $fileNames = [];
            /** @var \Phinx\Migration\AbstractMigration[] $versions */
            $versions = [];

            foreach ($phpFiles as $filePath) {
                if (Util::isValidMigrationFileName(basename($filePath))) {
                    if ($this->getOutput()->getVerbosity() >= OutputInterface::VERBOSITY_DEBUG) {
                        $this->getOutput()->writeln("Valid migration file <info>{$filePath}</info>.");
                    }

                    $version = Util::getVersionFromFileName(basename($filePath));

                    if (isset($versions[$version])) {
                        throw new \InvalidArgumentException(sprintf('Duplicate migration - "%s" has the same version as "%s"', $filePath, $versions[$version]->getVersion()));
                    }

                    $config = $this->getConfig();
                    $namespace = $config instanceof NamespaceAwareInterface ? $config->getMigrationNamespaceByPath(dirname($filePath)) : null;

                    // convert the filename to a class name
                    $class = ($namespace === null ? '' : $namespace . '\\') . Util::mapFileNameToClassName(basename($filePath));

                    if (isset($fileNames[$class])) {
                        throw new \InvalidArgumentException(sprintf(
                            'Migration "%s" has the same name as "%s"',
                            basename($filePath),
                            $fileNames[$class]
                        ));
                    }

                    $fileNames[$class] = basename($filePath);

                    if ($this->getOutput()->getVerbosity() >= OutputInterface::VERBOSITY_DEBUG) {
                        $this->getOutput()->writeln("Loading class <info>$class</info> from <info>$filePath</info>.");
                    }

                    // load the migration file
                    $orig_display_errors_setting = ini_get('display_errors');
                    ini_set('display_errors', 'On');
                    /** @noinspection PhpIncludeInspection */
                    require_once $filePath;
                    ini_set('display_errors', $orig_display_errors_setting);
                    if (!class_exists($class)) {
                        throw new \InvalidArgumentException(sprintf(
                            'Could not find class "%s" in file "%s"',
                            $class,
                            $filePath
                        ));
                    }

                    if ($this->getOutput()->getVerbosity() >= OutputInterface::VERBOSITY_DEBUG) {
                        $this->getOutput()->writeln("Running <info>$class</info>.");
                    }

                    // instantiate it
                    $migration = new $class($environment, $version, $this->getInput(), $this->getOutput());

                    if (!($migration instanceof AbstractMigration)) {
                        throw new \InvalidArgumentException(sprintf(
                            'The class "%s" in file "%s" must extend \Phinx\Migration\AbstractMigration',
                            $class,
                            $filePath
                        ));
                    }

                    $versions[$version] = $migration;
                } else {
                    if ($this->getOutput()->getVerbosity() >= OutputInterface::VERBOSITY_DEBUG) {
                        $this->getOutput()->writeln("Invalid migration file <error>{$filePath}</error>.");
                    }
                }
            }

            ksort($versions);
            $this->setMigrations($versions);
        }

        return $this->migrations;
    }
1301005
public static function getByVersionNumber($version)
    {
        $updates = id(new Update())->getLocalAvailableUpdates();
        foreach ($updates as $up) {
            if ($up->getUpdateVersion() == $version) {
                return $up;
            }
        }
    }
687833
public static function get_by_package($package_name = 'project') {
		if (!file_exists(Config::$migration_directory)) {
			throw new \Exception('Config::$migration_directory is not set to a valid directory');
		}

		/**
		 * Array with results
		 */
		$migrations = [];

		if ($package_name == 'project') {
			$files = scandir(Config::$migration_directory, SCANDIR_SORT_ASCENDING);

			foreach ($files as $key => $file) {
				if ($file[0] == '.') {
					unset($files[$key]);
					continue;
				}

				if ($file == 'db_version') {
					unset($files[$key]);
					continue;
				}

				if (!preg_match("/^\d{8}_\d{6}_.*$/", $file)) {
					unset($files[$key]);
					continue;
				}


				$parts = explode('_', $file);
				foreach ($parts as $key => $part) {
					$parts[$key] = ucfirst($part);
				}

				$classname = 'Migration_' . str_replace('.php', '', implode('_', $parts));
				include_once Config::$migration_directory . '/' . $file;
				$migrations[] = new $classname();
			}
		} else {

			/**
			 * Make a list of all migrations to be execute
			 */
			$packages = \Skeleton\Core\Skeleton::get_all();

			foreach ($packages as $package) {
				if ($package->name != $package_name) {
					continue;
				}
				if (!file_exists($package->migration_path)) {
					continue;
				}
				$files = scandir($package->migration_path, SCANDIR_SORT_ASCENDING);

				foreach ($files as $key => $file) {
					if ($file[0] == '.') {
						unset($files[$key]);
						continue;
					}

					if ($file == 'db_version') {
						unset($files[$key]);
						continue;
					}

					if (!preg_match("/^\d{8}_\d{6}_.*$/", $file)) {
						unset($files[$key]);
						continue;
					}


					$parts = explode('_', $file);
					foreach ($parts as $key => $part) {
						$parts[$key] = ucfirst($part);
					}

					$namespace_parts = explode('-', $package->name);
					foreach ($namespace_parts as $key => $namespace_part) {
						$namespace_parts[$key] = ucfirst($namespace_part);
					}
					$namespace = implode('\\', $namespace_parts);

					$classname = $namespace . '\Migration_' . str_replace('.php', '', implode('_', $parts));
					include_once $package->migration_path . '/' . $file;
					$migrations[] = new $classname();
				}
			}
		}


		return $migrations;
	}
322571
public function migrate(
        ?string $to = null,
        ?MigratorConfiguration $migratorConfiguration = null
    ) : array {
        $migratorConfiguration = $migratorConfiguration ?? new MigratorConfiguration();
        $dryRun                = $migratorConfiguration->isDryRun();

        if ($to === null) {
            $to = $this->migrationRepository->getLatestVersion();
        }

        $versions = $this->migrationRepository->getMigrations();

        if (! isset($versions[$to]) && $to > 0) {
            throw UnknownMigrationVersion::new($to);
        }

        $from = $this->migrationRepository->getCurrentVersion();

        $direction = $this->calculateDirection($from, $to);

        $migrationsToExecute = $this->configuration
            ->getMigrationsToExecute($direction, $to);

        /**
         * If
         *  there are no migrations to execute
         *  and there are migrations,
         *  and the migration from and to are the same
         * means we are already at the destination return an empty array()
         * to signify that there is nothing left to do.
         */
        if ($from === $to && count($migrationsToExecute) === 0 && count($versions) !== 0) {
            return $this->noMigrations();
        }

        $output  = $dryRun ? 'Executing dry run of migration' : 'Migrating';
        $output .= ' <info>%s</info> to <comment>%s</comment> from <comment>%s</comment>';

        $this->outputWriter->write(sprintf($output, $direction, $to, $from));

        /**
         * If there are no migrations to execute throw an exception.
         */
        if (count($migrationsToExecute) === 0 && ! $migratorConfiguration->getNoMigrationException()) {
            throw NoMigrationsToExecute::new();
        }

        if (count($migrationsToExecute) === 0) {
            return $this->noMigrations();
        }

        $stopwatchEvent = $this->stopwatch->start('migrate');

        $sql = $this->executeMigration($migrationsToExecute, $direction, $migratorConfiguration);

        $this->endMigration($stopwatchEvent, $migrationsToExecute, $sql);

        return $sql;
    }
971129
protected function _generateMigrationFile($version, $contentUp = "", $contentDown = "")
    {
        $classVersion = preg_replace('/[^0-9A-Za-z]/', '', $version);
        $className = 'Migration_' . $classVersion;
        $classData = "<?php

use Phalcon\Migrations\MigrationScript as Migration;

class " . $className . " extends Migration\n" .
            "{\n\n" .
            "\tpublic function up()\n" .
            "\t{\n" . $contentUp .
            "\n\t}" .
            "\n\n" .
            "\tpublic function down()\n" .
            "\t{\n" . $contentDown .
            "\n\t}" .
            "\n}\n";
        $classData = str_replace("\t", "    ", $classData);

        file_put_contents($this->migrationsDir . '/' . $version . '.php', $classData);

        return $classData;
    }
1080929
public static function convertVersionMetadata($version)
    {
        $version = str_replace(self::$cleanPatterns, '', $version);

        if (preg_match_all(
            self::createPattern('([a-zA-Z]+|(\-|\+)[a-zA-Z]+|(\-|\+)[0-9]+)'),
            $version,
            $matches,
            PREG_OFFSET_CAPTURE
        )) {
            list($type, $version, $end) = self::cleanVersion(strtolower($version), $matches);
            list($version, $patchVersion) = self::matchVersion($version, $type);

            $matches = array();
            $hasPatchNumber = preg_match('/[0-9]+\.[0-9]+|[0-9]+|\.[0-9]+$/', $end, $matches);
            $end = $hasPatchNumber ? $matches[0] : '1';

            if ($patchVersion) {
                $version .= $end;
            }
        }

        return static::cleanWildcard($version);
    }
999070
protected static function matchVersion($version, $type)
    {
        $patchVersion = true;

        if (\in_array($type, array('dev', 'snapshot'), true)) {
            $type = 'dev';
            $patchVersion = false;
        } elseif ('a' === $type) {
            $type = 'alpha';
        } elseif (\in_array($type, array('b', 'pre'), true)) {
            $type = 'beta';
        } elseif (!\in_array($type, array('alpha', 'beta', 'RC'), true)) {
            $type = 'patch';
        }

        $version .= $type;

        return array($version, $patchVersion);
    }
1135763
protected static function run($migrations, $name, $type, $method = 'up')
	{
		// storage for installed migrations
		$done = array();

		static::$connection === null or \DBUtil::set_connection(static::$connection);

		// Loop through the runnable migrations and run them
		foreach ($migrations as $ver => $migration)
		{
			logger(Fuel::L_INFO, 'Migrating to version: '.$ver);
			$result = call_user_func(array(new $migration['class'], $method));
			if ($result === false)
			{
				logger(Fuel::L_INFO, 'Skipped migration to '.$ver.'.');
				return false;
			}

			$file = basename($migration['path'], '.php');
			$method == 'up' ? static::write_install($name, $type, $file) : static::write_revert($name, $type, $file);
			$done[] = $file;
		}

		static::$connection === null or \DBUtil::set_connection(null);

		empty($done) or logger(Fuel::L_INFO, 'Migrated to '.$ver.' successfully.');

		return $done;
	}
269194
protected function generateMigration(Configuration $configuration, InputInterface $input, $version, $up = null, $down = null)
    {
        $placeHolders = [
            '<namespace>',
            '<version>',
            '<up>',
            '<down>',
        ];
        $replacements = [
            $configuration->getMigrationsNamespace(),
            $version,
            $up ? '        ' . implode("\n        ", explode("\n", $up)) : null,
            $down ? '        ' . implode("\n        ", explode("\n", $down)) : null,
        ];
        $code = str_replace($placeHolders, $replacements, self::$_template);

        $dir = $this->getDirectory($configuration);

        // Verify Migrations directory exists
        if (!file_exists($dir)) {
            throw new \InvalidArgumentException(
                sprintf(
                    'Migrations directory "%s" does not exist.',
                    $dir
                )
            );
        }

        $path = $this->buildVersionPath($dir, $version);

        // Output Version
        file_put_contents($path, $code);

        if ($editorCmd = $input->getOption('editor-cmd')) {
            shell_exec(
                sprintf(
                    '%s %s',
                    $editorCmd,
                    escapeshellarg($path)
                )
            );
        }

        return $path;
    }
181228
protected static function _down($name, $type)
	{
		// -v or --version
		$version = \Cli::option('v', \Cli::option('version', null));

		// if version has a value, make sure only 1 item was passed
		if ($version and (static::$default + static::$module_count + static::$package_count > 1))
		{
			\Cli::write('Migration: version only accepts 1 item.');
			return;
		}

		$migrations = \Migrate::down($version, $name, $type);

		if ($migrations)
		{
			\Cli::write('Reverted migrations for '.$type.':'.$name.':', 'green');
			foreach ($migrations as $migration)
			{
				\Cli::write('- '.$migration);
			}
		}
		else
		{
			// there is no 'down'...
			\Cli::write('There are no migrations installed to revert for '.$type.':'.$name.'.');
		}
	}
192754
private static function file_get_version($package) {
		if (file_exists(Config::$migration_directory . '/db_version')) {
			$version_file = trim(file_get_contents(Config::$migration_directory . '/db_version'));
			$version = json_decode($version_file, true);
		} else {
			$version = null;
		}

		if ($version === null and file_exists(Config::$migration_directory . '/db_version')) {
			// This is an old db_version file, let's update it
			$version = [
				'project' => $version_file
			];
			file_put_contents(Config::$migration_directory . '/db_version', json_encode($version));
		}

		if (empty($version[$package])) {
			return null;
		}

		return \DateTime::createFromFormat('Ymd His', $version[$package]);
	}
734821
protected function getMigrations($version_tag = false, $flatList = false, $configuration = [])
    {
        //Get migration definitions by tag
        $migrations = array_filter(
            $this->pluginManagerMigration->getDefinitions(), function ($migration) use ($version_tag) {
                return !empty($migration['migration_tags']) && in_array($version_tag, $migration['migration_tags']);
            }
        );

        // Create an array to configure all migration plugins with same configuration
        $keys = array_keys($migrations);
        $migration_plugin_configuration = array_fill_keys($keys, $configuration);

        //Create all migration instances
        $all_migrations = $this->pluginManagerMigration->createInstances(array_keys($migrations), $migration_plugin_configuration);

        $migrations = [];
        foreach ($all_migrations as $migration) {
            if ($flatList) {
                $migrations[$migration->id()] = ucwords($migration->label());
            } else {
                $migrations[$migration->id()]['tags'] = implode(', ', $migration->getMigrationTags());
                $migrations[$migration->id()]['description'] = ucwords($migration->label());
            }
        }
        return  $migrations;
    }
950431
protected function convertLegacySchemaVersion($version) {
    // Check to see if version is Semver (legacy format). Convert to expected
    // syntax. Luckily, there are a finite number of known legacy versions.
    // We check specifically for those.
    // E.g., 8.6.6 => 8006006.
    if (strpos($version, '.') !== FALSE) {
      str_replace('-beta1', '', $version);
      $semver_array = explode('.', $version);
      $semver_array[1] = str_pad($semver_array[1], 3, "0", STR_PAD_LEFT);
      $semver_array[2] = str_pad($semver_array[2], 3, "0", STR_PAD_LEFT);
      $version = implode('', $semver_array);
    }
    if (strpos($version, 'dev') !== FALSE) {
      $version = '0';
    }
    return $version;
  }
1235761
public function to($version) {
        $this->out(sprintf('<success>Upgrading to %s...</success>', $version));

        $schema = sprintf('%s/Config/Schema/Upgrade/%s.sql', CakePlugin::path($this->plugin), $version);

        if (!file_exists($schema)) {
            $this->err(sprintf('<error>Upgrade schema %s does not exist</error>', basename($schema)));
            return false;
        }

        // Trigger any migration changes
        $method = 'to_' . preg_replace('/[^0-9]+/', '', $version);

        if (method_exists($this, $method)) {
            call_user_func(array($this, $method));
        }

        // Execute the schema
        if ($this->executeSchema($schema, false)) {
            $this->complete[] = $version;

            $this->out(sprintf('<success>Upgrade to %s complete</success>', $version));
            $this->versions();
        }

        return true;
    }
1304343
public function getMigrationSql($version, $increment)
    {
        // I could use the GLOB_BRACE but it is not supported on ALPINE distros.
        // So, I have to call multiple times to simulate the braces.

        if (intval($version) != $version) {
            throw new \InvalidArgumentException("Version '$version' should be a integer number");
        }
        $version = intval($version);

        $filePattern = $this->folder
            . "/migrations"
            . "/" . ($increment < 0 ? "down" : "up")
            . "/*.sql";

        $result = array_filter(glob($filePattern), function ($file) use ($version) {
            return preg_match("/^0*$version(-dev)?\.sql$/", basename($file));
        });

        // Valid values are 0 or 1
        if (count($result) > 1) {
            throw new InvalidMigrationFile("You have two files with the same version number '$version'");
        }

        foreach ($result as $file) {
            if (intval(basename($file)) === $version) {
                return $file;
            }
        }
        return null;
    }