* @deprecated use migrations instead. See https://github.com/oat-sa/generis/wiki/Tao-Update-Process */ class Updater extends common_ext_ExtensionUpdater { /** * @param string $initialVersion * * @return string $versionUpdatedTo * @throws common_Exception * @throws EasyRdf_Exception */ public function update($initialVersion) { if ($this->isBetween('0.0.0', '2.11.0')) { throw new common_exception_NotImplemented( 'Updates from versions prior to Tao 3.1 are not longer supported, please update to Tao 3.1 first' ); } // in order to prevent update scripts to fail we run some early fixes $this->runPreChecks(); $this->skip('2.12.0', '2.18.0'); if ($this->isVersion('2.18.0')) { $this->getServiceManager()->register(ActionService::SERVICE_ID, new ActionService()); $this->setVersion('2.19.0'); } if ($this->isVersion('2.19.0')) { try { $this->getServiceManager()->get(Queue::CONFIG_ID); } catch (ServiceNotFoundException $e) { $service = new SyncQueue([]); $service->setServiceManager($this->getServiceManager()); $this->getServiceManager()->register(Queue::CONFIG_ID, $service); } $this->setVersion('2.20.0'); } $this->skip('2.20.0', '2.29.1'); if ($this->isVersion('2.29.1')) { $this->getServiceManager()->register(FileReferenceSerializer::SERVICE_ID, new ResourceFileSerializer()); $this->setVersion('2.30.0'); } $this->skip('2.30.0', '2.31.6'); if ($this->isVersion('2.31.6')) { $complexSearch = new ComplexSearchService( [ 'shared' => [ 'search.query.query' => false, 'search.query.builder' => false, 'search.query.criterion' => false, 'search.tao.serialyser' => false, 'search.tao.result' => false, ], 'invokables' => [ 'search.query.query' => '\\oat\\search\\Query', 'search.query.builder' => '\\oat\\search\\QueryBuilder', 'search.query.criterion' => '\\oat\\search\\QueryCriterion', 'search.driver.postgres' => '\\oat\\search\\DbSql\\Driver\\PostgreSQL', 'search.driver.mysql' => '\\oat\\search\\DbSql\\Driver\\MySQL', 'search.driver.tao' => '\\oat\\generis\\model\\kernel\\persistence\\smoothsql\\search\\driver\\TaoSearchDriver', 'search.tao.serialyser' => '\\oat\\search\\DbSql\\TaoRdf\\UnionQuerySerialyser', 'search.factory.query' => '\\oat\\search\\factory\\QueryFactory', 'search.factory.builder' => '\\oat\\search\\factory\\QueryBuilderFactory', 'search.factory.criterion' => '\\oat\\search\\factory\\QueryCriterionFactory', 'search.tao.gateway' => '\\oat\\generis\\model\\kernel\\persistence\\smoothsql\\search\\GateWay', 'search.tao.result' => '\\oat\\generis\\model\\kernel\\persistence\\smoothsql\\search\\TaoResultSet', ], 'abstract_factories' => [ '\\oat\\search\\Command\\OperatorAbstractfactory', ], 'services' => [ 'search.options' => [ 'table' => 'statements', 'driver' => 'taoRdf', ], ], ] ); $this->getServiceManager()->register(ComplexSearchService::SERVICE_ID, $complexSearch); $this->setVersion('3.0.0'); } $this->skip('3.0.0', '3.6.1'); if ($this->isVersion('3.6.1')) { $model = ModelManager::getModel(); if ($model instanceof core_kernel_persistence_smoothsql_SmoothModel) { $model->setOption( core_kernel_persistence_smoothsql_SmoothModel::OPTION_SEARCH_SERVICE, ComplexSearchService::SERVICE_ID ); ModelManager::setModel($model); } $this->setVersion('3.7.0'); } if ($this->isBetween('3.7.0', '3.8.3')) { /* @var $modelWrapper WrapperModel */ $modelWrapper = ModelManager::getModel(); if ($modelWrapper instanceof WrapperModel) { $inner = $modelWrapper->getInnerModel(); $inner->setOption( core_kernel_persistence_smoothsql_SmoothModel::OPTION_SEARCH_SERVICE, ComplexSearchService::SERVICE_ID ); $workspace = $modelWrapper->getWorkspaceModel(); $workspace->setOption( core_kernel_persistence_smoothsql_SmoothModel::OPTION_SEARCH_SERVICE, ComplexSearchService::SERVICE_ID ); $wrappedModel = WrapperModel::wrap($inner, $workspace); $wrappedModel->setServiceLocator($this->getServiceManager()); ModelManager::setModel($wrappedModel); } $this->setVersion('3.8.4'); } $this->skip('3.8.4', '3.9.0'); if ($this->isVersion('3.9.0')) { $fsm = $this->getServiceManager()->get(FileSystemService::SERVICE_ID); $fsm->createFileSystem(Queue::FILE_SYSTEM_ID, Queue::FILE_SYSTEM_ID); $this->getServiceManager()->register(FileSystemService::SERVICE_ID, $fsm); $this->setVersion('3.10.0'); } $this->skip('3.10.0', '3.27.0'); if ($this->isVersion('3.27.0')) { if (!$this->getServiceManager()->has(common_ext_ExtensionsManager::SERVICE_ID)) { $this->getServiceManager()->register( common_ext_ExtensionsManager::SERVICE_ID, new common_ext_ExtensionsManager() ); } $this->setVersion('3.28.0'); } $this->skip('3.28.0', '3.29.1'); if ($this->isVersion('3.29.1')) { $this->getServiceManager()->register(LoggerService::SERVICE_ID, new LoggerService()); $this->setVersion('3.30.0'); } $this->skip('3.30.0', '3.34.0'); /** * replaced update script 3.34.0 because of potential config loss */ if ($this->isVersion('3.34.0')) { $queue = $this->getServiceManager()->get(Queue::SERVICE_ID); if (get_class($queue) === 'oat\Taskqueue\Persistence\RdsQueue') { $persistence = $queue->getOption('persistence'); $queue->setOptions( [ 'payload' => '\oat\oatbox\task\implementation\TaskQueuePayload', 'runner' => '\oat\oatbox\task\TaskRunner', 'persistence' => '\oat\Taskqueue\Persistence\TaskSqlPersistence', 'config' => ['persistence' => $persistence], ] ); } else { $queue->setOptions( [ 'payload' => TaskQueuePayload::class, 'runner' => TaskRunner::class, 'persistence' => InMemoryQueuePersistence::class, 'config' => [], ] ); } $this->getServiceManager()->register(Queue::SERVICE_ID, $queue); /** * skip because you don't need to fix config */ $this->setVersion('3.35.2'); } /** * you are on a bad version needs to be fixed */ $this->skip('3.35.0', '3.35.1'); /** * fix for bad config */ if ($this->isVersion('3.35.1')) { $queue = $this->getServiceManager()->get(Queue::SERVICE_ID); if (get_class($queue) === 'oat\Taskqueue\Persistence\RdsQueue') { $queue->setOptions( [ 'payload' => '\oat\oatbox\task\implementation\TaskQueuePayload', 'runner' => '\oat\oatbox\task\TaskRunner', 'persistence' => '\oat\Taskqueue\Persistence\TaskSqlPersistence', 'config' => ['persistence' => 'default'], ] ); } $this->getServiceManager()->register(Queue::SERVICE_ID, $queue); $this->setVersion('3.35.2'); } $this->skip('3.35.2', '4.1.4'); if ($this->isVersion('4.1.4')) { /** Rdf synchronization was moved to version 4.4.1 (see below) because OntologyUpdater is in tao extension */ // OntologyUpdater::syncModels(); $this->setVersion('4.2.0'); } $this->skip('4.2.0', '4.4.0'); if ($this->isVersion('4.4.0')) { $file = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'core' . DIRECTORY_SEPARATOR . 'ontology' . DIRECTORY_SEPARATOR . 'taskqueue.rdf'; $api = core_kernel_impl_ApiModelOO::singleton(); $api->importXmlRdf('http://www.tao.lu/Ontologies/taskqueue.rdf', $file); $this->setVersion('4.4.1'); } $this->skip('4.4.1', '6.7.0'); if ($this->isVersion('6.7.0')) { $file = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'core' . DIRECTORY_SEPARATOR . 'ontology' . DIRECTORY_SEPARATOR . 'generis.rdf'; $api = core_kernel_impl_ApiModelOO::singleton(); $api->importXmlRdf('http://www.tao.lu/Ontologies/generis.rdf', $file); $this->setVersion('6.8.0'); } $this->skip('6.8.0', '6.8.1'); if ($this->isVersion('6.8.1')) { if ($this->getExtension()->hasConfig('logger')) { $this->getExtension()->unsetConfig('logger'); } $conf = $this->getExtension()->getConfig('log'); if (!$conf instanceof LoggerInterface) { $logger = new LoggerService([ LoggerService::LOGGER_OPTION => new TaoLog([ TaoLog::OPTION_APPENDERS => $conf, ]), ]); $header = $this->getExtension()->getConfigHeader('log'); $logger->setHeader($header); $this->getServiceManager()->register(LoggerService::SERVICE_ID, $logger); } $this->setVersion('6.9.0'); } $this->skip('6.9.0', '6.16.0'); if ($this->isVersion('6.16.0')) { $userFactory = new UserFactoryService([]); $this->getServiceManager()->register(UserFactoryService::SERVICE_ID, $userFactory); /** @var common_ext_ExtensionsManager $extensionManager */ $extensionManager = $this->getServiceManager()->get(common_ext_ExtensionsManager::SERVICE_ID); $config = $extensionManager->getExtensionById('generis')->getConfig('auth'); foreach ($config as $index => $adapter) { if ($adapter['driver'] === AuthAdapter::class) { $adapter['user_factory'] = UserFactoryService::SERVICE_ID; } $config[$index] = $adapter; } $extensionManager->getExtensionById('generis')->setConfig('auth', array_values($config)); $this->setVersion('6.17.0'); } $this->skip('6.17.0', '7.1.1'); if ($this->isVersion('7.1.1')) { $this->getServiceManager()->register(UserLanguageService::SERVICE_ID, new UserLanguageService()); $this->setVersion('7.2.0'); } $this->skip('7.2.0', '7.14.2'); if ($this->isVersion('7.14.2')) { $this->getServiceManager()->register(SessionService::SERVICE_ID, new SessionService()); $modelConfig = $this->getServiceManager()->get(Ontology::SERVICE_ID)->getConfig(); $className = $modelConfig['class']; $ontologyModel = new $className($modelConfig['config']); if ($ontologyModel instanceof core_kernel_persistence_smoothsql_SmoothModel) { $ontologyModel->setOption( \core_kernel_persistence_smoothsql_SmoothModel::OPTION_CACHE_SERVICE, \common_cache_Cache::SERVICE_ID ); } $this->getServiceManager()->register(Ontology::SERVICE_ID, $ontologyModel); $this->setVersion('8.0.0'); } $this->skip('8.0.0', '9.1.3'); if ($this->isVersion('9.1.3')) { $this->getServiceManager()->unregister('generis/profiler'); $this->setVersion('10.0.0'); } $this->skip('10.0.0', '10.1.0'); if ($this->isBetween('10.1.0', '11.0.0')) { /** @var \common_persistence_Manager $persistenceManager */ $persistenceManager = $this->getServiceManager()->get(\common_persistence_Manager::SERVICE_ID); $persistenceManagerConfig = $persistenceManager->getOption('persistences'); foreach ($persistenceManagerConfig as $persistenceId => $persistenceParams) { // wrap pdo drivers in dbal if (strpos($persistenceParams['driver'], 'pdo_') === 0) { $persistenceManagerConfig[$persistenceId] = [ 'driver' => 'dbal', 'connection' => $persistenceParams, ]; } } $persistenceManager->setOption('persistences', $persistenceManagerConfig); $this->getServiceManager()->register(\common_persistence_Manager::SERVICE_ID, $persistenceManager); $this->setVersion('11.0.0'); } $this->skip('11.0.0', '11.1.1'); if ($this->isVersion('11.1.1')) { // $service = new LockService([ // LockService::OPTION_PERSISTENCE_CLASS => PdoStore::class, // LockService::OPTION_PERSISTENCE_OPTIONS => 'default', // ]); // $this->getServiceManager()->register(LockService::SERVICE_ID, $service); // $service->install(); $this->setVersion('11.2.0'); } $this->skip('11.2.0', '11.2.1'); if ($this->isVersion('11.2.1')) { $service = new LockService([ LockService::OPTION_PERSISTENCE_CLASS => NoLockStorage::class ]); $this->getServiceManager()->register(LockService::SERVICE_ID, $service); $this->setVersion('11.2.2'); } $this->skip('11.2.2', '11.3.1'); if ($this->isVersion('11.3.1')) { /** @var \common_persistence_Manager $persistenceManager */ $persistenceManager = $this->getServiceManager()->get(\common_persistence_Manager::SERVICE_ID); $persistenceManagerConfig = $persistenceManager->getOption('persistences'); foreach ($persistenceManagerConfig as $persistenceId => $persistenceParams) { $persistenceManager->registerPersistence($persistenceId, $persistenceParams); } $this->getServiceManager()->register(\common_persistence_Manager::SERVICE_ID, $persistenceManager); $this->setVersion('11.3.2'); } $this->skip('11.3.2', '11.5.2'); if ($this->isVersion('11.5.2')) { $this->runExtensionScript(RegisterDefaultKvPersistence::class); $this->setVersion('11.6.0'); } $this->skip('11.6.0', '12.1.0'); if ($this->isBetween('12.1.0', '12.2.0')) { $fs = $this->getServiceManager()->get(FileSystemService::SERVICE_ID); $adapters = $fs->getOption(FileSystemService::OPTION_ADAPTERS); if (!isset($adapters['default'])) { if (get_class($fs) == FileSystemService::class) { // override default behavior to ensure an adapter and not a directory is created $adapters['default'] = [ 'class' => Local::class, 'options' => ['root' => $fs->getOption(FileSystemService::OPTION_FILE_PATH)] ]; $fs->setOption(FileSystemService::OPTION_ADAPTERS, $adapters); } else { $fs->createFileSystem('default', ''); } $this->getServiceManager()->register(FileSystemService::SERVICE_ID, $fs); } $this->setVersion('12.2.0'); } $this->skip('12.2.0', '12.4.0'); if ($this->isVersion('12.4.0')) { $uriService = $this->getServiceManager()->get(UriProvider::SERVICE_ID); if ($uriService instanceof ConfigurationService) { $innerService = $uriService->getConfig(); if ($innerService instanceof UriProvider) { $this->getServiceManager()->register(UriProvider::SERVICE_ID, $innerService); } else { throw new \common_exception_InconsistentData('Unknown URI Provider found'); } } $this->setVersion('12.4.1'); } $this->skip('12.4.1', '12.11.0'); if ($this->isVersion('12.11.0')) { /** @var \common_persistence_Persistence $defaultPersistence */ $defaultPersistence = $this->getServiceManager() ->get(PersistenceManager::SERVICE_ID) ->getPersistenceById('default'); /** @var \common_persistence_sql_SchemaManager $schemaManager */ $schemaManager = $defaultPersistence->getDriver()->getSchemaManager(); $schema = $schemaManager->createSchema(); $fromSchema = clone $schema; $schema->dropTable('models'); $queries = $defaultPersistence->getPlatform()->getMigrateSchemaSql($fromSchema, $schema); foreach ($queries as $query) { $defaultPersistence->exec($query); } $this->setVersion('12.12.0'); } $this->skip('12.12.0', '12.20.2'); if ($this->isVersion('12.20.2')) { $file = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'core' . DIRECTORY_SEPARATOR . 'ontology' . DIRECTORY_SEPARATOR . 'generis.rdf'; $api = core_kernel_impl_ApiModelOO::singleton(); $api->importXmlRdf('http://www.tao.lu/Ontologies/generis.rdf', $file); $this->setVersion('12.21.0'); } $this->skip('12.21.0', '12.22.1'); if ($this->isVersion('12.22.1')) { /** @var FileSystemService $fs */ $fs = $this->getServiceManager()->get(FileSystemService::SERVICE_ID); $adapters = $fs->getOption(FileSystemService::OPTION_ADAPTERS); $adapters['memory'] = [ 'class' => MemoryAdapter::class, ]; $fs->setOption(FileSystemService::OPTION_ADAPTERS, $adapters); $this->getServiceManager()->register(FileSystemService::SERVICE_ID, $fs); $this->setVersion('12.23.0'); } $this->skip('12.23.0', '12.26.1'); if ($this->isVersion('12.26.1')) { core_kernel_impl_ApiModelOO::singleton()->importXmlRdf( WidgetRdf::NAMESPACE, __DIR__ . '/../../core/ontology/widgetdefinitions.rdf' ); $this->setVersion('12.27.0'); } $this->skip('12.27.0', '12.28.0'); if ($this->isVersion('12.28.0')) { $this->removeDuplicates(new FileIterator(__DIR__ . '/../../core/ontology/widgetdefinitions.rdf')); $this->setVersion('12.28.1'); } //Updater files are deprecated. Please use migrations. //See: https://github.com/oat-sa/generis/wiki/Tao-Update-Process $this->setVersion($this->getExtension()->getManifest()->getVersion()); } /** * Helper for the unfortunate scenario where we generated duplicate * entries in the statement table. * * Fixes the duplicates by removing all matching triples and then * readding them only once */ protected function removeDuplicates(Traversable $triples): void { $rdfModel = $this->getServiceLocator()->get(Ontology::SERVICE_ID)->getRdfInterface(); foreach ($triples as $triple) { $rdfModel->remove($triple); } $rdfModel->addTripleCollection($triples); } /** * Runs required fixes that allow the rest of the updates to run */ protected function runPreChecks(): void { // 12.22.0 introduced PSR-16 cache required for update process if (!$this->getServiceManager()->has(SimpleCache::SERVICE_ID)) { $psrCache = new KeyValueCache([KeyValueCache::OPTION_PERSISTENCE => 'cache']); $this->getServiceManager()->register(SimpleCache::SERVICE_ID, $psrCache); } } }