getNewVersion() == $toVersion) { break; // We've reached the version we wanted to downgrade to, so break } $downgradePerformed = self::_runDowngrade($downgrader) ? true : $downgradePerformed; } return $downgradePerformed; } /** * Run the given upgrade. * * @param $upgrader AirtimeUpgrader the upgrader class to be executed * * @return bool true if the upgrade was successful, otherwise false */ private static function _runUpgrade(AirtimeUpgrader $upgrader) { return $upgrader->checkIfUpgradeSupported() && $upgrader->upgrade(); } /** * Run the given downgrade. * * @param $downgrader AirtimeUpgrader the upgrader class to be executed * @param $supportedVersions array array of supported versions * * @return bool true if the downgrade was successful, otherwise false */ private static function _runDowngrade(AirtimeUpgrader $downgrader) { return $downgrader->checkIfDowngradeSupported() && $downgrader->downgrade(); } } abstract class AirtimeUpgrader { protected $_dir; protected $host; protected $port; protected $database; protected $username; protected $password; /** * @param $dir string directory housing upgrade files */ public function __construct($dir) { $this->_dir = $dir; } /** Schema versions that this upgrader class can upgrade from (an array of version strings). */ abstract protected function getSupportedSchemaVersions(); /** The schema version that this upgrader class will upgrade to. (returns a version string) */ abstract public function getNewVersion(); public static function getCurrentSchemaVersion() { return Application_Model_Preference::GetSchemaVersion(); } /** * This function checks to see if this class can perform an upgrade of your version of Airtime. * * @return bool true if we can upgrade your version of Airtime */ public function checkIfUpgradeSupported() { return in_array(static::getCurrentSchemaVersion(), $this->getSupportedSchemaVersions()); } /** * This function checks to see if this class can perform a downgrade of your version of Airtime. * * @return bool true if we can downgrade your version of Airtime */ public function checkIfDowngradeSupported() { return static::getCurrentSchemaVersion() == $this->getNewVersion(); } protected function toggleMaintenanceScreen($toggle) { if ($toggle) { // Disable Airtime UI // create a temporary maintenance notification file // when this file is on the server, zend framework redirects all // requests to the maintenance page and sets a 503 response code /* DISABLED because this does not work correctly $this->maintenanceFile = isset($_SERVER['AIRTIME_BASE']) ? $_SERVER['AIRTIME_BASE']."maintenance.txt" : "/tmp/maintenance.txt"; $file = fopen($this->maintenanceFile, 'w'); fclose($file); */ } // delete maintenance.txt to give users access back to Airtime /* DISABLED because this does not work correctly if ($this->maintenanceFile) { unlink($this->maintenanceFile); }*/ } /** * Implement this for each new version of Airtime * This function abstracts out the core upgrade functionality, * allowing child classes to overwrite _runUpgrade to reduce duplication. */ public function upgrade() { try { // $this->toggleMaintenanceScreen(true); $this->_getDbValues(); $this->_runUpgrade(); Application_Model_Preference::SetSchemaVersion($this->getNewVersion()); // $this->toggleMaintenanceScreen(false); } catch (Exception $e) { // $this->toggleMaintenanceScreen(false); Logging::error('Error in upgrade: ' . $e->getMessage()); return false; } return true; } /** * Implement this for each new version of Airtime * This function abstracts out the core downgrade functionality, * allowing child classes to overwrite _runDowngrade to reduce duplication. */ public function downgrade() { try { $this->_getDbValues(); $this->_runDowngrade(); $highestSupportedVersion = null; foreach ($this->getSupportedSchemaVersions() as $v) { // version_compare returns 1 (true) if the second parameter is lower if (!$highestSupportedVersion || version_compare($v, $highestSupportedVersion)) { $highestSupportedVersion = $v; } } // Set the schema version to the highest supported version so we don't skip versions when downgrading Application_Model_Preference::SetSchemaVersion($highestSupportedVersion); } catch (Exception $e) { return false; } return true; } protected function _getDbValues() { $config = Config::getConfig(); $this->host = $config['dsn']['host']; $this->port = $config['dsn']['port']; $this->username = $config['dsn']['username']; $this->password = $config['dsn']['password']; $this->database = $config['dsn']['database']; } protected function _runPsql($args) { $command = <<<"END" PGPASSWORD={$this->password} \\ /usr/bin/psql --quiet \\ --host={$this->host} \\ --port={$this->port} \\ --dbname={$this->database} \\ --username={$this->username} \\ {$args} END; passthru($command); } protected function _runUpgrade() { $sqlFile = "{$this->_dir}/upgrade_sql/airtime_{$this->getNewVersion()}/upgrade.sql"; $args = <<<"END" --file={$sqlFile} 2>&1 \\ | grep -v -E "will create implicit sequence|will create implicit index" END; $this->_runPsql($args); } protected function _runDowngrade() { $sqlFile = "{$this->_dir}/downgrade_sql/airtime_{$this->getNewVersion()}/downgrade.sql"; $args = <<<"END" --file={$sqlFile} 2>&1 \\ | grep -v -E "will create implicit sequence|will create implicit index" END; $this->_runPsql($args); } } class AirtimeUpgrader253 extends AirtimeUpgrader { protected function getSupportedSchemaVersions() { return ['2.5.1', '2.5.2']; } public function getNewVersion() { return '2.5.3'; } protected function _runUpgrade() { // Update disk_usage value in cc_pref $storDir = isset($_SERVER['AIRTIME_BASE']) ? $_SERVER['AIRTIME_BASE'] . 'srv/airtime/stor' : '/srv/airtime/stor'; $diskUsage = shell_exec("du -sb {$storDir} | awk '{print $1}'"); Application_Model_Preference::setDiskUsage($diskUsage); parent::_runUpgrade(); } } class AirtimeUpgrader254 extends AirtimeUpgrader { protected function getSupportedSchemaVersions() { return ['2.5.3']; } public function getNewVersion() { return '2.5.4'; } protected function _runUpgrade() { // First, ensure there are no superadmins already. $numberOfSuperAdmins = CcSubjsQuery::create() ->filterByDbType(UTYPE_SUPERADMIN) ->filterByDbLogin('sourcefabric_admin', Criteria::NOT_EQUAL) // Ignore sourcefabric_admin users ->count(); // Only create a super admin if there isn't one already. if ($numberOfSuperAdmins == 0) { // Find the "admin" user and promote them to superadmin. $adminUser = CcSubjsQuery::create() ->filterByDbLogin('admin') ->findOne(); if (!$adminUser) { // Otherwise get the user with the lowest ID that is of type administrator: $adminUser = CcSubjsQuery::create() ->filterByDbType(UTYPE_ADMIN) ->orderByDbId(Criteria::ASC) ->findOne(); if (!$adminUser) { throw new Exception("Failed to find any users of type 'admin' ('A')."); } } $adminUser = new Application_Model_User($adminUser->getDbId()); $adminUser->setType(UTYPE_SUPERADMIN); $adminUser->save(); Logging::info($_SERVER['HTTP_HOST'] . ': ' . $this->getNewVersion() . ' Upgrade: Promoted user ' . $adminUser->getLogin() . ' to be a Super Admin.'); // Also try to promote the sourcefabric_admin user $sofabAdminUser = CcSubjsQuery::create() ->filterByDbLogin('sourcefabric_admin') ->findOne(); if ($sofabAdminUser) { $sofabAdminUser = new Application_Model_User($sofabAdminUser->getDbId()); $sofabAdminUser->setType(UTYPE_SUPERADMIN); $sofabAdminUser->save(); Logging::info($_SERVER['HTTP_HOST'] . ': ' . $this->getNewVersion() . ' Upgrade: Promoted user ' . $sofabAdminUser->getLogin() . ' to be a Super Admin.'); } } } } class AirtimeUpgrader255 extends AirtimeUpgrader { protected function getSupportedSchemaVersions() { return [ '2.5.4', ]; } public function getNewVersion() { return '2.5.5'; } } class AirtimeUpgrader259 extends AirtimeUpgrader { protected function getSupportedSchemaVersions() { return [ '2.5.5', ]; } public function getNewVersion() { return '2.5.9'; } } class AirtimeUpgrader2510 extends AirtimeUpgrader { protected function getSupportedSchemaVersions() { return [ '2.5.9', ]; } public function getNewVersion() { return '2.5.10'; } } class AirtimeUpgrader2511 extends AirtimeUpgrader { protected function getSupportedSchemaVersions() { return [ '2.5.10', ]; } public function getNewVersion() { return '2.5.11'; } protected function _runUpgrade() { $queryResult = CcFilesQuery::create() ->select(['disk_usage']) ->withColumn('SUM(CcFiles.filesize)', 'disk_usage') ->find(); $disk_usage = $queryResult[0]; Application_Model_Preference::setDiskUsage($disk_usage); } } class AirtimeUpgrader2512 extends AirtimeUpgrader { protected function getSupportedSchemaVersions() { return [ '2.5.10', '2.5.11', ]; } public function getNewVersion() { return '2.5.12'; } } /** * Class AirtimeUpgrader2513 - Celery and SoundCloud upgrade. * * Adds third_party_track_references and celery_tasks tables for third party service * authentication and task architecture. * *
third_party_track_references schema: * * id -> int PK * service -> string internal service name * foreign_id -> int external unique service id * file_id -> int internal FK->cc_files track id * upload_time -> timestamp internal upload timestamp * status -> string external service status * *
celery_tasks schema: * * id -> int PK * task_id -> string external unique amqp results identifier * track_reference -> int internal FK->third_party_track_references id * name -> string external Celery task name * dispatch_time -> timestamp internal message dispatch time * status -> string external Celery task status */ class AirtimeUpgrader2513 extends AirtimeUpgrader { protected function getSupportedSchemaVersions() { return [ '2.5.12', ]; } public function getNewVersion() { return '2.5.13'; } } /** * Class AirtimeUpgrader2514. * * SAAS-923 - Add a partial constraint to cc_pref so that keystrings must be unique */ class AirtimeUpgrader2514 extends AirtimeUpgrader { protected function getSupportedSchemaVersions() { return [ '2.5.13', ]; } public function getNewVersion() { return '2.5.14'; } } /** * Class AirtimeUpgrader2515. * * SAAS-1071 - Remove not null constraint from file_id fk in third_party_track_references * so that we can create track references for downloads (which won't have a file * ID until the task is run and the file is POSTed back to Airtime) */ class AirtimeUpgrader2515 extends AirtimeUpgrader { protected function getSupportedSchemaVersions() { return [ '2.5.14', ]; } public function getNewVersion() { return '2.5.15'; } } class AirtimeUpgrader2516 extends AirtimeUpgrader { protected function getSupportedSchemaVersions() { return [ '2.5.15', ]; } public function getNewVersion() { return '2.5.16'; } } class AirtimeUpgrader300alpha extends AirtimeUpgrader { protected function getSupportedSchemaVersions() { return [ '2.5.16', ]; } public function getNewVersion() { return '3.0.0-alpha'; } } class AirtimeUpgrader300alpha1 extends AirtimeUpgrader { protected function getSupportedSchemaVersions() { return [ '3.0.0-alpha', ]; } public function getNewVersion() { return '3.0.0-alpha.1'; } } class AirtimeUpgrader300alpha6 extends AirtimeUpgrader { protected function getSupportedSchemaVersions() { return [ '3.0.0-alpha.1', ]; } public function getNewVersion() { return '3.0.0-alpha.6'; } } /** * Class AirtimeUpgrader300alpha7. * * GH-#636 - https://github.com/libretime/libretime/pull/636 - Change dynamic smartblock to be default smartblock type */ class AirtimeUpgrader300alpha7 extends AirtimeUpgrader { protected function getSupportedSchemaVersions() { return [ '3.0.0-alpha.6', ]; } public function getNewVersion() { return '3.0.0-alpha.7'; } } /** * Class AirtimeUpgrader300alpha7-1. * * GH-#659 - https://github.com/libretime/libretime/pull/659/ - Add description and title to podcast episodes database table */ class AirtimeUpgrader300alpha7_1 extends AirtimeUpgrader { protected function getSupportedSchemaVersions() { return [ '3.0.0-alpha.7', ]; } public function getNewVersion() { return '3.0.0-alpha.7.1'; } } /** * Class AirtimeUpgrader300alpha7-2. * * GH-#704 - https://github.com/libretime/libretime/pull/704/ - Add criteria group to smartblock table to enable database to store separately */ class AirtimeUpgrader300alpha7_2 extends AirtimeUpgrader { protected function getSupportedSchemaVersions() { return [ '3.0.0-alpha.7.1', ]; } public function getNewVersion() { return '3.0.0-alpha.7.2'; } } class AirtimeUpgrader300alpha7_3 extends AirtimeUpgrader { protected function getSupportedSchemaVersions() { return [ '3.0.0-alpha.7.2', ]; } public function getNewVersion() { return '3.0.0-alpha.7.3'; } } class AirtimeUpgrader300alpha9_1 extends AirtimeUpgrader { protected function getSupportedSchemaVersions() { return [ '3.0.0-alpha.7.3', ]; } public function getNewVersion() { return '3.0.0-alpha.9.1'; } } class AirtimeUpgrader300alpha9_2 extends AirtimeUpgrader { protected function getSupportedSchemaVersions() { return [ '3.0.0-alpha.9.1', ]; } public function getNewVersion() { return '3.0.0-alpha.9.2'; } } class AirtimeUpgrader200alpha9_3 extends AirtimeUpgrader { protected function getSupportedSchemaVersions() { return [ '3.0.0-alpha.9.2', ]; } public function getNewVersion() { return '3.0.0-alpha.9.3'; } } class AirtimeUpgrader200alpha9_4 extends AirtimeUpgrader { protected function getSupportedSchemaVersions() { return [ '3.0.0-alpha.9.3', ]; } public function getNewVersion() { return '3.0.0-alpha.9.4'; } }