Migrate local INI dashboards into this dashboard * home. (Default "Default Home") * * --user= Migrate local INI dashboards only for the given * user. (Default *) * * --delete Remove all INI files after successfully migrated * the dashboards to the database. * * --silent Suppress all kind of DB errors and have them handled automatically. */ public function indexAction() { $dashboardsPath = Config::resolvePath('dashboards'); if (! is_dir($dashboardsPath)) { Logger::info('There are no local user dashboards to migrate'); return; } $silent = $this->params->get('silent'); $user = $this->params->get('user'); $home = $this->params->get('home'); $deleteLegacyFiles = $this->params->get('delete'); $dashboardDirs = new DirectoryIterator($dashboardsPath); $dashboardHome = ! $home ? null : new DashboardHome($home); $dashboard = new Dashboard(); $rc = 0; foreach ($dashboardDirs as $dashboardDir) { $username = $user; if ($username && $username !== $dashboardDirs->key()) { continue; } $username = $username ?: $dashboardDirs->key(); $dashboardIni = $dashboardDir . '/dashboard.ini'; Logger::info('Migrating INI dashboards for user "%s" to database...', $username); try { $config = Config::fromIni($dashboardIni); if ($config->isEmpty()) { continue; } $dashboard->setUser(new User($username)); $dashboard->load(); if ($dashboardHome) { if ($dashboard->hasEntry($dashboardHome->getName())) { $dashboardHome = $dashboard->getEntry($dashboardHome->getName()); } else { $dashboard->manageEntry($dashboardHome); } } else { $dashboardHome = $dashboard->initGetDefaultHome(); } $dashboardHome->loadDashboardEntries(); $panes = []; $parsedPanes = []; $parsedDashlets = []; foreach ($config as $key => $part) { if (strpos($key, '.') === false) { // Panes $pane = $key; if ($silent && $dashboardHome->hasEntry($pane)) { while ($dashboardHome->hasEntry($pane)) { $pane = $this->getUniqueName($pane); } } elseif ($dashboardHome->hasEntry($pane)) { do { $pane = readline(sprintf( 'Pane "%s" already exists within the "%s" Dashboard Home.' . "\n" . 'Please enter another name for this pane or rerun the command with the "silent"' . ' param to suppress such errors!: ', $pane, $dashboardHome->getTitle() )); } while (empty($pane) || $dashboardHome->hasEntry($pane)); } $parsedPanes[$key] = $pane; $newPane = (new Pane($pane)) ->setHome($dashboardHome) ->setTitle($part->get('title', $pane)); if ($dashboardHome->hasEntry($key) && $dashboardHome->getEntry($key)->getTitle() === $newPane->getTitle() ) { $newPane->setTitle($pane); } $panes[$pane] = $newPane; } else { // Dashlets list($pane, $dashletName) = explode('.', $key, 2); if (! isset($parsedDashlets[$pane])) { $parsedDashlets[$pane] = []; } $dashlet = new Dashlet($dashletName, $part->get('url')); $dashlet->setTitle($part->get('title', $dashletName)); $parsedDashlets[$pane][$dashlet->getName()] = $dashlet; } } $dashboardHome->manageEntry($panes); foreach ($parsedDashlets as $key => $dashlets) { if (! isset($parsedPanes[$key])) { continue; } /** @var Pane $pane */ $pane = $panes[$parsedPanes[$key]]; $pane->manageEntry($dashlets); } if ($deleteLegacyFiles) { unlink($dashboardIni); } } catch (NotReadableError $e) { if ($e->getPrevious() !== null) { Logger::error('%s: %s', $e->getMessage(), $e->getPrevious()->getMessage()); } else { Logger::error($e->getMessage()); } $rc = 128; } catch (\PDOException $e) { Logger::error($e->getMessage()); $rc = 128; break; } } if ($rc > 0) { Logger::error('Failed to migrate some user dashboards'); exit($rc); } Logger::info('Successfully migrated all local user dashboards to the database'); } /** * Get a more unique version of the given name * * @param string $name * * @return string */ protected function getUniqueName(string $name): string { if (preg_match('/(\d+)$/', $name, $matches)) { $name = preg_replace('/\d+$/', ++$matches[1], $name); } else { $name .= 1; } return $name; } }