entityManager = $entityManager; $this->config = $config; $this->configWriter = $configWriter; $this->fileManager = $fileManager; $this->metadata = $metadata; $this->ormMetadataData = $ormMetadataData; $this->hookManager = $hookManager; $this->schemaProxy = $schemaProxy; } /** * Rebuild the system with metadata, database and cache clearing. */ public function rebuild(?array $entityList = null): void { $this->clearCache(); $this->disableHooks(); $this->populateConfigParameters(); $this->rebuildMetadata(); $this->rebuildDatabase($entityList); $this->rebuildScheduledJobs(); $this->enableHooks(); } /** * Clear a cache. */ public function clearCache(): void { $result = $this->fileManager->removeInDir($this->cachePath); if ($result != true) { throw new Error("Error while clearing cache"); } $this->updateCacheTimestamp(); } /** * Rebuild database. */ public function rebuildDatabase(?array $entityList = null): void { $schema = $this->schemaProxy; try { $result = $schema->rebuild($entityList); } catch (Throwable $e) { $result = false; $GLOBALS['log']->error( "Fault to rebuild database schema. Details: ". $e->getMessage() . " at " . $e->getFile() . ":" . $e->getLine() ); } if ($result != true) { throw new Error("Error while rebuilding database. See log file for details."); } $databaseType = strtolower($schema->getDatabaseHelper()->getDatabaseType()); if ( !$this->config->get('actualDatabaseType') || $this->config->get('actualDatabaseType') !== $databaseType ) { $this->configWriter->set('actualDatabaseType', $databaseType); } $databaseVersion = $schema->getDatabaseHelper()->getDatabaseVersion(); if ( !$this->config->get('actualDatabaseVersion') || $this->config->get('actualDatabaseVersion') !== $databaseVersion ) { $this->configWriter->set('actualDatabaseVersion', $databaseVersion); } $this->configWriter->updateCacheTimestamp(); $this->configWriter->save(); } /** * Rebuild metadata. */ public function rebuildMetadata(): void { $metadata = $this->metadata; $metadata->init(true); $ormData = $this->ormMetadataData->getData(true); $this->entityManager->getMetadata()->updateData(); $this->updateCacheTimestamp(); if (empty($ormData)) { throw new Error("Error while rebuilding metadata. See log file for details."); } } /** * Rebuild scheduled jobs. Create system jobs. */ public function rebuildScheduledJobs(): void { $metadata = $this->metadata; $entityManager = $this->entityManager; $jobs = $metadata->get(['entityDefs', 'ScheduledJob', 'jobs'], []); $systemJobNameList = []; foreach ($jobs as $jobName => $defs) { if (!$jobName) { continue; } if (empty($defs['isSystem']) || empty($defs['scheduling'])) { continue; } $systemJobNameList[] = $jobName; $sj = $entityManager ->getRepository('ScheduledJob') ->where([ 'job' => $jobName, 'status' => 'Active', 'scheduling' => $defs['scheduling'], ]) ->findOne(); if ($sj) { continue; } $job = $entityManager ->getRepository('ScheduledJob') ->where([ 'job' => $jobName, ]) ->findOne(); if ($job) { $entityManager->removeEntity($job); } $name = $jobName; if (!empty($defs['name'])) { $name = $defs['name']; } $job = $entityManager->getEntity('ScheduledJob'); $job->set([ 'job' => $jobName, 'status' => 'Active', 'scheduling' => $defs['scheduling'], 'isInternal' => true, 'name' => $name, ]); $entityManager->saveEntity($job); } $internalScheduledJobList = $entityManager ->getRepository('ScheduledJob') ->where([ 'isInternal' => true, ]) ->find(); foreach ($internalScheduledJobList as $scheduledJob) { $jobName = $scheduledJob->get('job'); if (!in_array($jobName, $systemJobNameList)) { $entityManager->getRepository('ScheduledJob')->deleteFromDb($scheduledJob->id); } } } /** * Update cache timestamp. */ public function updateCacheTimestamp(): void { $this->configWriter->updateCacheTimestamp(); $this->configWriter->save(); } protected function populateConfigParameters(): void { $this->setFullTextConfigParameters(); $this->setCryptKeyConfigParameter(); $this->configWriter->save(); } protected function setFullTextConfigParameters(): void { $platform = $this->config->get('database.platform') ?? null; $driver = $this->config->get('database.driver') ?? ''; if ($platform !== 'Mysql' && strpos($driver, 'mysql') === false) { return; } $pdo = $this->entityManager->getPDO(); $sql = "SHOW VARIABLES LIKE 'ft_min_word_len'"; $sth = $pdo->prepare($sql); $sth->execute(); $fullTextSearchMinLength = null; $row = $sth->fetch(PDO::FETCH_ASSOC); if ($row && isset($row['Value'])) { $fullTextSearchMinLength = intval($row['Value']); } $this->configWriter->set('fullTextSearchMinLength', $fullTextSearchMinLength); } protected function setCryptKeyConfigParameter(): void { if ($this->config->get('cryptKey')) { return; } $cryptKey = Util::generateSecretKey(); $this->configWriter->set('cryptKey', $cryptKey); } protected function disableHooks(): void { $this->hookManager->disable(); } protected function enableHooks(): void { $this->hookManager->enable(); } }