mirror of
https://github.com/Icinga/icinga-php-thirdparty.git
synced 2025-08-23 10:38:18 +02:00
473 lines
16 KiB
PHP
473 lines
16 KiB
PHP
<?php
|
|
class Zend_Tool_DatabaseSchemaProvider extends Zend_Tool_Project_Provider_Abstract
|
|
{
|
|
/**
|
|
* @var Zend_Db_Adapter_Interface
|
|
*/
|
|
protected $_db;
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
protected $_tablePrefix;
|
|
|
|
/**
|
|
* @var Zend_Config
|
|
*/
|
|
protected $_config;
|
|
|
|
/**
|
|
* Section name to load from config
|
|
* @var string
|
|
*/
|
|
protected $_appConfigSectionName;
|
|
|
|
public function update($env='development', $dir='./scripts/migrations')
|
|
{
|
|
return $this->updateTo(null, $env, $dir);
|
|
}
|
|
|
|
/**
|
|
* Allows you to change the database schema version by specifying the desired version. If you are
|
|
* upgrading (choosing a higher version), it will update to the highest version that is available.
|
|
* If you are downgrading, it will go to the highest version that is equal to or lower than the
|
|
* version you specified.
|
|
*
|
|
* @param string $version Version to change to
|
|
* @param string $env Environment to retrieve database credentials from, default is development
|
|
* @param string $dir Directory containing migration files, default is ./scripts/migrations
|
|
*
|
|
* @return boolean
|
|
*/
|
|
public function updateTo($version, $env='development', $dir='./scripts/migrations')
|
|
{
|
|
$this->_init($env);
|
|
$response = $this->_registry->getResponse();
|
|
try {
|
|
$db = $this->_getDbAdapter();
|
|
$manager = new Zend_Db_Schema_Manager($dir, $db, $this->getTablePrefix());
|
|
|
|
$result = $manager->updateTo($version);
|
|
|
|
switch ($result) {
|
|
case Zend_Db_Schema_Manager::RESULT_AT_CURRENT_VERSION:
|
|
if (!$version) {
|
|
$version = $manager->getCurrentSchemaVersion();
|
|
}
|
|
$response->appendContent("Already at version $version");
|
|
break;
|
|
|
|
case Zend_Db_Schema_Manager::RESULT_NO_MIGRATIONS_FOUND :
|
|
$response->appendContent("No migration files found to migrate from {$manager->getCurrentSchemaVersion()} to $version");
|
|
break;
|
|
|
|
default:
|
|
$response->appendContent('Schema updated to version ' . $manager->getCurrentSchemaVersion());
|
|
}
|
|
|
|
return true;
|
|
} catch (Exception $e) {
|
|
$response->appendContent('AN ERROR HAS OCCURED:');
|
|
$response->appendContent($e->getMessage());
|
|
$response->appendContent($e->getTraceAsString());
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Decrements the database schema version to the next version or if specified
|
|
* down a specified number of versions.
|
|
*
|
|
* @param int $versions Number of versions to decrement. Default is 1
|
|
* @param string $env Environment to read database credentials from
|
|
* @param string $dir Directory containing migration files
|
|
*
|
|
* @return boolean
|
|
*/
|
|
public function decrement($versions=1, $env='development', $dir='./scripts/migrations')
|
|
{
|
|
$this->_init($env);
|
|
$response = $this->_registry->getResponse();
|
|
try {
|
|
$db = $this->_getDbAdapter();
|
|
$manager = new Zend_Db_Schema_Manager($dir, $db, $this->getTablePrefix());
|
|
|
|
$result = $manager->decrementVersion($versions);
|
|
|
|
switch ($result) {
|
|
case Zend_Db_Schema_Manager::RESULT_AT_MINIMUM_VERSION:
|
|
$response->appendContent("Already at minimum version " . $manager->getCurrentSchemaVersion());
|
|
break;
|
|
|
|
default:
|
|
$response->appendContent('Schema updated to version ' . $manager->getCurrentSchemaVersion());
|
|
}
|
|
|
|
return true;
|
|
} catch (Exception $e) {
|
|
$response->appendContent('AN ERROR HAS OCCURRED: ');
|
|
$response->appendContent($e->getMessage());
|
|
$response->appendContent($e->getTraceAsString());
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Increments the datbase schema version to the next version or up a specified
|
|
* number of versions
|
|
*
|
|
* @param int $versions Number of versions to increment. Default is 1
|
|
* @param string $env Environment to read database conguration from
|
|
* @param string $dir Directory containing migration scripts
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function increment($versions=1,$env='development', $dir='./scripts/migrations')
|
|
{
|
|
$this->_init($env);
|
|
$response = $this->_registry->getResponse();
|
|
try {
|
|
$db = $this->_getDbAdapter();
|
|
$manager = new Zend_Db_Schema_Manager($dir, $db, $this->getTablePrefix());
|
|
|
|
$result = $manager->incrementVersion($versions);
|
|
|
|
switch ($result) {
|
|
case Zend_Db_Schema_Manager::RESULT_AT_MAXIMUM_VERSION:
|
|
$response->appendContent("Already at maximum version " . $manager->getCurrentSchemaVersion());
|
|
break;
|
|
|
|
default:
|
|
$response->appendContent('Schema updated to version ' . $manager->getCurrentSchemaVersion());
|
|
}
|
|
|
|
return true;
|
|
} catch (Exception $e) {
|
|
$response->appendContent('AN ERROR HAS OCCURED:');
|
|
$response->appendContent($e->getMessage());
|
|
$response->appendContent($e->getTraceAsString());
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Provide the current schema version number
|
|
*
|
|
* @return boolean
|
|
*/
|
|
#[\ReturnTypeWillChange]
|
|
public function current($env='development', $dir='./migrations')
|
|
{
|
|
$this->_init($env);
|
|
try {
|
|
|
|
// Initialize and retrieve DB resource
|
|
$db = $this->_getDbAdapter();
|
|
$manager = new Zend_Db_Schema_Manager($dir, $db, $this->getTablePrefix());
|
|
echo 'Current schema version is ' . $manager->getCurrentSchemaVersion() . PHP_EOL;
|
|
|
|
return true;
|
|
} catch (Exception $e) {
|
|
echo 'AN ERROR HAS OCCURED:' . PHP_EOL;
|
|
echo $e->getMessage() . PHP_EOL;
|
|
echo $e->getTraceAsString() . PHP_EOL;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Retrieves the realpath for ./scripts/migrations. Does not appear to be
|
|
* used anywhere. Possible candidate for removal.
|
|
*
|
|
* @return string
|
|
* @deprecated
|
|
*/
|
|
protected function _getDirectory()
|
|
{
|
|
$dir = './scripts/migrations';
|
|
return realpath($dir);
|
|
}
|
|
|
|
/**
|
|
* Initializes the Akrabat functionality and adds it to Zend_Tool (zf)
|
|
*
|
|
* @param string $env Environment to initialize for
|
|
*
|
|
* @return null
|
|
*
|
|
* @throws Zend_Tool_Project_Exception
|
|
*/
|
|
protected function _init($env)
|
|
{
|
|
$profile = $this->_loadProfile(self::NO_PROFILE_THROW_EXCEPTION);
|
|
$appConfigFileResource = $profile->search('applicationConfigFile');
|
|
|
|
if ($appConfigFileResource == false) {
|
|
throw new Zend_Tool_Project_Exception('A project with an application config file is required to use this provider.');
|
|
}
|
|
$appConfigFilePath = $appConfigFileResource->getPath();
|
|
|
|
// Base config, normally the application.ini in the configs dir of your app
|
|
$this->_config = $this->_createConfig($appConfigFilePath, $env, true);
|
|
|
|
// Are there any override config files?
|
|
foreach($this->_getAppConfigOverridePathList($appConfigFilePath) as $path) {
|
|
$overrideConfig = $this->_createConfig($path);
|
|
if (isset($overrideConfig->$env)) {
|
|
$this->_config->merge($overrideConfig->$env);
|
|
}
|
|
}
|
|
|
|
require_once 'Zend/Loader/Autoloader.php';
|
|
$autoloader = Zend_Loader_Autoloader::getInstance();
|
|
$autoloader->registerNamespace('Zend_');
|
|
}
|
|
|
|
/**
|
|
* Pull the akrabat section of the zf.ini
|
|
*
|
|
* @return Zend_Config_Ini|false Fasle if not set
|
|
*/
|
|
protected function _getUserConfig()
|
|
{
|
|
$userConfig = false;
|
|
if (isset($this->_registry->getConfig()->akrabat)) {
|
|
$userConfig = $this->_registry->getConfig()->akrabat;
|
|
}
|
|
return $userConfig;
|
|
}
|
|
|
|
/**
|
|
* Create new Zend_Config object based on a filename
|
|
*
|
|
* Mostly a copy and paste from Zend_Application::_loadConfig
|
|
*
|
|
* @param string $filename File to create the object from
|
|
* @param string $section If not null, pull this sestion of the config
|
|
* file only. Doesn't apply to .php and .inc file
|
|
* @param string $allowModifications Should the object be mutable or not
|
|
*
|
|
* @throws Zend_Db_Schema_Exception
|
|
*
|
|
* @return Zend_Config
|
|
*/
|
|
protected function _createConfig($filename, $section = null, $allowModifications = false) {
|
|
|
|
$options = false;
|
|
if ($allowModifications) {
|
|
$options = ['allowModifications' => true];
|
|
}
|
|
|
|
$suffix = pathinfo($filename, PATHINFO_EXTENSION);
|
|
$suffix = ($suffix === 'dist')
|
|
? pathinfo(basename($filename, ".$suffix"), PATHINFO_EXTENSION)
|
|
: $suffix;
|
|
|
|
switch (strtolower($suffix)) {
|
|
case 'ini':
|
|
$config = new Zend_Config_Ini($filename, $section, $options);
|
|
break;
|
|
|
|
case 'xml':
|
|
$config = new Zend_Config_Xml($filename, $section, $options);
|
|
break;
|
|
|
|
case 'json':
|
|
$config = new Zend_Config_Json($filename, $section, $options);
|
|
break;
|
|
|
|
case 'yaml':
|
|
case 'yml':
|
|
$config = new Zend_Config_Yaml($filename, $section, $options);
|
|
break;
|
|
|
|
case 'php':
|
|
case 'inc':
|
|
$config = include $filename;
|
|
if (!is_array($config)) {
|
|
throw new Zend_Db_Schema_Exception(
|
|
'Invalid configuration file provided; PHP file does not return array value'
|
|
);
|
|
}
|
|
$config = new Zend_Config($config, $allowModifications);
|
|
break;
|
|
|
|
default:
|
|
throw new Zend_Db_Schema_Exception(
|
|
'Invalid configuration file provided; unknown config type'
|
|
);
|
|
}
|
|
return $config;
|
|
}
|
|
|
|
/**
|
|
* Will pull a list of file paths to application config overrides
|
|
*
|
|
* There is a deliberate attempt to be very forgiving. If a file doesn't exist,
|
|
* it won't be included in the list. If a the file doesn't have a section that
|
|
* corresponds the current target environment it don't be merged.
|
|
*
|
|
* The config files should be standalone, they will not be able to extend
|
|
* sections from the base config file.
|
|
*
|
|
* The ini, xml, json, yaml and php config file types are supported
|
|
*
|
|
* By default we will look for a "local.ini" in the applications configs
|
|
* directory.
|
|
*
|
|
* Config files are added with an order, the order run from lowest to highest.
|
|
* The "local.ini" file in this case will be given the order of 100
|
|
*
|
|
* This can be disabled with the following in your .zf.ini:
|
|
*
|
|
* akrabat.appConfigOverride.skipLocal = true
|
|
*
|
|
* You can have add to the list of file names to look for in the configs
|
|
* directory by adding the following to the .zf.ini:
|
|
*
|
|
* akrabat.appConfigOverride.name = 'override.ini'
|
|
*
|
|
* You can only add one name with this approach and it will be added with the
|
|
* order of 200
|
|
*
|
|
* To add mutiple names to be checked use the following in the .zf.ini:
|
|
*
|
|
* akrabat.appConfigOverride.name.60 = 'dev.ini'
|
|
* akrabat.appConfigOverride.name.50 = 'override.ini.ini'
|
|
*
|
|
* Where the last part of the config key is the order to merge the files.
|
|
*
|
|
* To add a path to be include, do the following in your .zf.ini:
|
|
*
|
|
* akrabat.appConfigOverride.path = '/home/user/projects/account/configs/local.ini'
|
|
*
|
|
* You can only add one path with this approach and it will be added with the
|
|
* order of 300
|
|
*
|
|
* To add mutiple path use the following in the .zf.ini:
|
|
*
|
|
* akrabat.appConfigOverride.path.1 = './application/configs/dev.ini'
|
|
* akrabat.appConfigOverride.path.4 = '/home/user/projects/account/configs/local.ini'
|
|
*
|
|
* Where the last part of the config key is the order to merge the files.
|
|
*
|
|
* If a path is added with an order that clashes with another file then the
|
|
* path will be added the end of the queue
|
|
*
|
|
* @param string $appConfigFilePath
|
|
*
|
|
* @return array
|
|
*/
|
|
protected function _getAppConfigOverridePathList($appConfigFilePath)
|
|
{
|
|
$pathList = [];
|
|
$appConfigDir = dirname($appConfigFilePath);
|
|
$userConfig = false;
|
|
|
|
if ($this->_getUserConfig() !== false
|
|
&& isset($this->_getUserConfig()->appConfigOverride)
|
|
) {
|
|
$userConfig = $this->_getUserConfig()->appConfigOverride;
|
|
}
|
|
|
|
$skipLocal = false;
|
|
if ($userConfig !== false && isset($userConfig->skipLocal)) {
|
|
$skipLocal = (bool)$userConfig->skipLocal;
|
|
}
|
|
|
|
// The convention over configuration option
|
|
if ($skipLocal === false) {
|
|
$appConfigFilePathLocal = realpath($appConfigDir.'/local.ini');
|
|
if ($appConfigFilePathLocal) {
|
|
$pathList[100] = $appConfigFilePathLocal;
|
|
}
|
|
}
|
|
|
|
if ($userConfig === false) {
|
|
return $pathList;
|
|
}
|
|
|
|
// Look for file names in the app configs dir
|
|
if (isset($userConfig->name)) {
|
|
if ($userConfig->name instanceof Zend_Config) {
|
|
$fileNameList = $userConfig->name->toArray();
|
|
} else {
|
|
$fileNameList = [200 => $userConfig->name];
|
|
}
|
|
|
|
foreach($fileNameList as $order => $fileName) {
|
|
$path = realpath($appConfigDir.'/'.$fileName);
|
|
if ($path) {
|
|
$pathList[$order] = $appConfigDir.'/'.$fileName;
|
|
}
|
|
}
|
|
}
|
|
|
|
// A full or relative path, app dir will not be prefixed
|
|
if (isset($userConfig->path)) {
|
|
if ($userConfig->path instanceof Zend_Config) {
|
|
$filePathList = $userConfig->path->toArray();
|
|
} else {
|
|
$filePathList = [300 => $userConfig->path];
|
|
}
|
|
|
|
foreach($filePathList as $order => $filePath) {
|
|
if (file_exists($filePath) === false) {
|
|
continue;
|
|
}
|
|
if (isset($pathList[$order])) {
|
|
$pathList[] = $filePath;
|
|
} else {
|
|
$pathList[$order] = $filePath;
|
|
}
|
|
}
|
|
}
|
|
|
|
ksort($pathList);
|
|
return $pathList;
|
|
}
|
|
|
|
/**
|
|
* Retrieve initialized DB connection
|
|
*
|
|
* @return Zend_Db_Adapter_Interface
|
|
*/
|
|
protected function _getDbAdapter()
|
|
{
|
|
if ((null === $this->_db)) {
|
|
if($this->_config->resources->db){
|
|
$dbConfig = $this->_config->resources->db;
|
|
$this->_db = Zend_Db::factory($dbConfig->adapter, $dbConfig->params);
|
|
} elseif($this->_config->resources->multidb){
|
|
foreach ($this->_config->resources->multidb as $db) {
|
|
if($db->default){
|
|
$this->_db = Zend_Db::factory($db->adapter, $db);
|
|
}
|
|
}
|
|
}
|
|
if($this->_db instanceof Zend_Db_Adapter_Interface) {
|
|
throw new Zend_Db_Schema_Exception('Database was not initialized');
|
|
}
|
|
}
|
|
return $this->_db;
|
|
}
|
|
|
|
/**
|
|
* Retrieve table prefix
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getTablePrefix()
|
|
{
|
|
if ((null === $this->_tablePrefix)) {
|
|
$prefix = '';
|
|
if (isset($this->_config->resources->db->table_prefix)) {
|
|
$prefix = $this->_config->resources->db->table_prefix . '_';
|
|
}
|
|
$this->_tablePrefix = $prefix;
|
|
}
|
|
return $this->_tablePrefix;
|
|
}
|
|
|
|
}
|