diff --git a/config/services.yaml b/config/services.yaml
index 13744b48..b6acd224 100644
--- a/config/services.yaml
+++ b/config/services.yaml
@@ -21,6 +21,7 @@ services:
$emailSender: '%app.notifications.email_sender%'
$projectDir: '%kernel.project_dir%'
$publicFolder: '%bolt.public_folder%'
+ $tablePrefix: '%bolt.table_prefix%'
# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
@@ -41,7 +42,6 @@ services:
$debug: '%kernel.debug%'
Bolt\Doctrine\TablePrefix:
- arguments: [ "%bolt.table_prefix%" ]
tags:
- { name: doctrine.event_listener, event: loadClassMetadata, lazy: true }
@@ -54,9 +54,6 @@ services:
tags:
- { name: doctrine.event_listener, event: loadClassMetadata }
- Bolt\Event\Subscriber\TimedPublishSubscriber:
- arguments: [ "%bolt.table_prefix%" ]
-
Bolt\Extension\RoutesLoader:
tags: [routing.loader]
diff --git a/src/Command/AddUserCommand.php b/src/Command/AddUserCommand.php
index 0f29a706..cd6cb114 100644
--- a/src/Command/AddUserCommand.php
+++ b/src/Command/AddUserCommand.php
@@ -141,7 +141,7 @@ class AddUserCommand extends Command
if ($password !== null) {
$this->io->text(' > Password: ' . str_repeat('*', mb_strlen($password)));
} else {
- $passwordQuestion = new Question('Password', Str::generatePassword());
+ $passwordQuestion = new Question('Password (input is hidden)', Str::generatePassword());
$passwordQuestion->setHidden(true);
$passwordQuestion->setValidator([$this->validator, 'validatePassword']);
diff --git a/src/Command/InfoCommand.php b/src/Command/InfoCommand.php
index f67e8d05..1b7e6796 100644
--- a/src/Command/InfoCommand.php
+++ b/src/Command/InfoCommand.php
@@ -58,9 +58,11 @@ HELP
$connection = ! empty($platform['connection_status']) ? sprintf('- %s', $platform['connection_status']) : '';
+ $tableExists = $this->doctrineVersion->tableContentExists() ? '' : sprintf('- Tables not initialised');
+
$io->listing([
sprintf('Install type: %s', Version::installType()),
- sprintf('Database: %s %s %s', $platform['driver_name'], $platform['server_version'], $connection),
+ sprintf('Database: %s %s %s %s', $platform['driver_name'], $platform['server_version'], $connection, $tableExists),
sprintf('PHP version: %s', PHP_VERSION),
sprintf('Operating System: %s - %s', php_uname('s'), php_uname('r')),
]);
diff --git a/src/Command/SetupCommand.php b/src/Command/SetupCommand.php
index 8c6a0749..a06119b3 100644
--- a/src/Command/SetupCommand.php
+++ b/src/Command/SetupCommand.php
@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace Bolt\Command;
+use Doctrine\DBAL\Connection;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputInterface;
@@ -15,6 +16,16 @@ class SetupCommand extends Command
{
protected static $defaultName = 'bolt:setup';
+ /** @var Connection */
+ private $connection;
+
+ public function __construct(Connection $connection)
+ {
+ $this->connection = $connection;
+
+ parent::__construct();
+ }
+
protected function configure(): void
{
$this
@@ -28,17 +39,21 @@ class SetupCommand extends Command
$exitCode = 0;
$io = new SymfonyStyle($input, $output);
+ // Because SQLite breaks on `--if-not-exists`, we need to check for that here.
+ // See: https://github.com/doctrine/DoctrineBundle/issues/542
+ $options = ['-q' => true];
+ if ($this->connection->getDatabasePlatform()->getName() !== 'sqlite') {
+ $options[] = ['--if-not-exists' => true];
+ }
+
$command = $this->getApplication()->find('doctrine:database:create');
- $commandInput = new ArrayInput(['-q' => true]);
- $exitCode += $command->run($commandInput, $output);
+ $exitCode += $command->run(new ArrayInput($options), $output);
$command = $this->getApplication()->find('doctrine:schema:create');
- $commandInput = new ArrayInput([]);
- $exitCode += $command->run($commandInput, $output);
+ $exitCode += $command->run(new ArrayInput([]), $output);
$command = $this->getApplication()->find('bolt:reset-secret');
- $commandInput = new ArrayInput([]);
- $exitCode += $command->run($commandInput, $output);
+ $exitCode += $command->run(new ArrayInput([]), $output);
$command = $this->getApplication()->find('bolt:add-user');
$commandInput = new ArrayInput(['--admin' => true]);
diff --git a/src/Doctrine/TablePrefix.php b/src/Doctrine/TablePrefix.php
index c12e212c..5b2ccd00 100644
--- a/src/Doctrine/TablePrefix.php
+++ b/src/Doctrine/TablePrefix.php
@@ -10,11 +10,11 @@ use Doctrine\ORM\Mapping\ClassMetadataInfo;
class TablePrefix
{
- private $prefix;
+ private $tablePrefix;
- public function __construct(string $prefix)
+ public function __construct(string $tablePrefix)
{
- $this->prefix = Str::ensureEndsWith($prefix, '_');
+ $this->tablePrefix = Str::ensureEndsWith($tablePrefix, '_');
}
public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs): void
@@ -23,14 +23,14 @@ class TablePrefix
if (! $classMetadata->isInheritanceTypeSingleTable() || $classMetadata->getName() === $classMetadata->rootEntityName) {
$classMetadata->setPrimaryTable([
- 'name' => $this->prefix . $classMetadata->getTableName(),
+ 'name' => $this->tablePrefix . $classMetadata->getTableName(),
]);
}
foreach ($classMetadata->getAssociationMappings() as $fieldName => $mapping) {
if ($mapping['type'] === ClassMetadataInfo::MANY_TO_MANY && $mapping['isOwningSide']) {
$mappedTableName = $mapping['joinTable']['name'];
- $classMetadata->associationMappings[$fieldName]['joinTable']['name'] = $this->prefix . $mappedTableName;
+ $classMetadata->associationMappings[$fieldName]['joinTable']['name'] = $this->tablePrefix . $mappedTableName;
}
}
}
diff --git a/src/Doctrine/Version.php b/src/Doctrine/Version.php
index 4f60f03e..f82f17b8 100644
--- a/src/Doctrine/Version.php
+++ b/src/Doctrine/Version.php
@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace Bolt\Doctrine;
+use Bolt\Common\Str;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Driver\PDOConnection;
@@ -12,9 +13,13 @@ class Version
/** @var Connection */
private $connection;
- public function __construct(Connection $connection)
+ /** @var string */
+ private $tablePrefix;
+
+ public function __construct(Connection $connection, string $tablePrefix = 'bolt')
{
$this->connection = $connection;
+ $this->tablePrefix = Str::ensureEndsWith($tablePrefix, '_');
}
public function getPlatform(): array
@@ -37,4 +42,15 @@ class Version
'server_version' => $wrapped->getAttribute(\PDO::ATTR_SERVER_VERSION),
];
}
+
+ public function tableContentExists(): bool
+ {
+ try {
+ $this->connection->executeQuery('SELECT 1 FROM ' . $this->tablePrefix . 'content LIMIT 1; ');
+ } catch (\Throwable $e) {
+ return false;
+ }
+
+ return true;
+ }
}
diff --git a/src/Event/Subscriber/TimedPublishSubscriber.php b/src/Event/Subscriber/TimedPublishSubscriber.php
index 1167844d..9b9a7a20 100644
--- a/src/Event/Subscriber/TimedPublishSubscriber.php
+++ b/src/Event/Subscriber/TimedPublishSubscriber.php
@@ -19,12 +19,12 @@ class TimedPublishSubscriber implements EventSubscriberInterface
private $entityManager;
/** @var string */
- private $prefix;
+ private $tablePrefix;
- public function __construct(string $prefix, EntityManagerInterface $entityManager)
+ public function __construct(string $tablePrefix, EntityManagerInterface $entityManager)
{
$this->entityManager = $entityManager;
- $this->prefix = Str::ensureEndsWith($prefix, '_');
+ $this->tablePrefix = Str::ensureEndsWith($tablePrefix, '_');
}
/**
@@ -37,8 +37,8 @@ class TimedPublishSubscriber implements EventSubscriberInterface
// Publish timed Content records when 'publish_at' has passed and Depublish published Content
// records when 'depublish_at' has passed. Note: Placeholders in DBAL don't work for tablenames.
- $queryPublish = sprintf('update %scontent SET status = "published", published_at = :now WHERE status = "timed" AND published_at < :now', $this->prefix);
- $queryDepublish = sprintf('update %scontent SET status = "held", depublished_at = :now WHERE status = "published" AND depublished_at < :now', $this->prefix);
+ $queryPublish = sprintf('update %scontent SET status = "published", published_at = :now WHERE status = "timed" AND published_at < :now', $this->tablePrefix);
+ $queryDepublish = sprintf('update %scontent SET status = "held", depublished_at = :now WHERE status = "published" AND depublished_at < :now', $this->tablePrefix);
try {
$conn->executeUpdate($queryPublish, [':now' => $now]);