aboutsummaryrefslogtreecommitdiffhomepage
path: root/main/app/system/Bakery
diff options
context:
space:
mode:
Diffstat (limited to 'main/app/system/Bakery')
-rw-r--r--main/app/system/Bakery/Bakery.php320
-rw-r--r--main/app/system/Bakery/BaseCommand.php114
-rw-r--r--main/app/system/Bakery/Command/Bake.php150
-rw-r--r--main/app/system/Bakery/Command/BuildAssets.php344
-rw-r--r--main/app/system/Bakery/Command/ClearCache.php180
-rw-r--r--main/app/system/Bakery/Command/Debug.php356
-rw-r--r--main/app/system/Bakery/Command/Migrate.php92
-rw-r--r--main/app/system/Bakery/Command/MigrateRefresh.php100
-rw-r--r--main/app/system/Bakery/Command/MigrateReset.php94
-rw-r--r--main/app/system/Bakery/Command/MigrateRollback.php98
-rw-r--r--main/app/system/Bakery/Command/Setup.php440
-rw-r--r--main/app/system/Bakery/Command/Test.php108
-rw-r--r--main/app/system/Bakery/DatabaseTest.php102
-rw-r--r--main/app/system/Bakery/Migration.php134
-rw-r--r--main/app/system/Bakery/Migrator.php1140
15 files changed, 1886 insertions, 1886 deletions
diff --git a/main/app/system/Bakery/Bakery.php b/main/app/system/Bakery/Bakery.php
index 273b25c..99a32b3 100644
--- a/main/app/system/Bakery/Bakery.php
+++ b/main/app/system/Bakery/Bakery.php
@@ -1,160 +1,160 @@
-<?php
-/**
- * UserFrosting (http://www.userfrosting.com)
- *
- * @link https://github.com/userfrosting/UserFrosting
- * @license https://github.com/userfrosting/UserFrosting/blob/master/licenses/UserFrosting.md (MIT License)
- */
-
-namespace UserFrosting\System\Bakery;
-
-use Symfony\Component\Console\Application;
-use UserFrosting\System\UserFrosting;
-use Illuminate\Support\Str;
-
-/**
- * Base class for UserFrosting Bakery CLI tools.
- *
- * @author Alex Weissman (https://alexanderweissman.com)
- */
-class Bakery
-{
- /**
- * @var $app Symfony\Component\Console\Application
- */
- protected $app;
-
- /**
- * @var ContainerInterface The global container object, which holds all your services.
- */
- protected $ci;
-
- /**
- * Constructor
- */
- public function __construct() {
- // Check for Sprinkles schema file
- $sprinklesFile = @file_get_contents(\UserFrosting\SPRINKLES_SCHEMA_FILE);
- if ($sprinklesFile === FALSE) {
- $sprinklesFile = $this->setupBaseSprinkleList();
- }
-
- // Create Symfony Console App
- $this->app = new Application("UserFrosting Bakery", \UserFrosting\VERSION);
-
- // Setup the sprinkles
- $uf = new UserFrosting();
-
- // Set argument as false, we are using the CLI
- $uf->setupSprinkles(FALSE);
-
- // Get the container
- $this->ci = $uf->getContainer();
-
- // Add each commands to the Console App
- $this->loadCommands();
- }
-
- /**
- * Run the Symfony Console App
- */
- public function run() {
- $this->app->run();
- }
-
- /**
- * Return the list of available commands for a specific sprinkle
- */
- protected function loadCommands() {
- // Get base Bakery command
- $commands = $this->getBakeryCommands();
-
- // Get the sprinkles commands
- $sprinkles = $this->ci->sprinkleManager->getSprinkleNames();
- foreach ($sprinkles as $sprinkle) {
- $commands = $commands->merge($this->getSprinkleCommands($sprinkle));
- }
-
- // Add commands to the App
- $commands->each(function ($command) {
- $instance = new $command();
- $instance->setContainer($this->ci);
- $this->app->add($instance);
- });
- }
-
- /**
- * Return the list of available commands for a specific sprinkle
- * Sprinkles commands should be located in `src/Bakery/`
- */
- protected function getSprinkleCommands($sprinkle) {
- // Find all the migration files
- $path = $this->commandDirectoryPath($sprinkle);
- $files = glob($path . "*.php");
- $commands = collect($files);
-
- // Transform the path into a class names
- $commands->transform(function ($file) use ($sprinkle, $path) {
- $className = basename($file, '.php');
- $sprinkleName = Str::studly($sprinkle);
- $className = "\\UserFrosting\\Sprinkle\\" . $sprinkleName . "\\Bakery\\" . $className;
- return $className;
- });
-
- return $commands;
- }
-
- /**
- * Return the list of available commands in system/Bakery/Command/
- */
- protected function getBakeryCommands() {
- // Find all the migration files
- $files = glob(\UserFrosting\APP_DIR . "/system/Bakery/Command/" . "*.php");
- $commands = collect($files);
-
- // Transform the path into a class names
- $commands->transform(function ($file) {
- $className = basename($file, '.php');
- $className = "\\UserFrosting\\System\\Bakery\\Command\\" . $className;
- return $className;
- });
-
- return $commands;
- }
-
- /**
- * Returns the path of the Migration directory.
- *
- * @access protected
- * @param mixed $sprinkleName
- * @return void
- */
- protected function commandDirectoryPath($sprinkleName) {
- return \UserFrosting\SPRINKLES_DIR .
- \UserFrosting\DS .
- $sprinkleName .
- \UserFrosting\DS .
- \UserFrosting\SRC_DIR_NAME .
- "/Bakery/";
- }
-
- /**
- * Write the base Sprinkles schema file if it doesn't exist.
- *
- * @access protected
- * @return void
- */
- protected function setupBaseSprinkleList() {
- $model = \UserFrosting\APP_DIR . '/sprinkles.example.json';
- $destination = \UserFrosting\SPRINKLES_SCHEMA_FILE;
- $sprinklesModelFile = @file_get_contents($model);
- if ($sprinklesModelFile === FALSE) {
- $this->io->error("File `$sprinklesModelFile` not found. Please create '$destination' manually and try again.");
- exit(1);
- }
-
- file_put_contents($destination, $sprinklesModelFile);
-
- return $sprinklesModelFile;
- }
-}
+<?php
+/**
+ * UserFrosting (http://www.userfrosting.com)
+ *
+ * @link https://github.com/userfrosting/UserFrosting
+ * @license https://github.com/userfrosting/UserFrosting/blob/master/licenses/UserFrosting.md (MIT License)
+ */
+
+namespace UserFrosting\System\Bakery;
+
+use Symfony\Component\Console\Application;
+use UserFrosting\System\UserFrosting;
+use Illuminate\Support\Str;
+
+/**
+ * Base class for UserFrosting Bakery CLI tools.
+ *
+ * @author Alex Weissman (https://alexanderweissman.com)
+ */
+class Bakery
+{
+ /**
+ * @var $app Symfony\Component\Console\Application
+ */
+ protected $app;
+
+ /**
+ * @var ContainerInterface The global container object, which holds all your services.
+ */
+ protected $ci;
+
+ /**
+ * Constructor
+ */
+ public function __construct() {
+ // Check for Sprinkles schema file
+ $sprinklesFile = @file_get_contents(\UserFrosting\SPRINKLES_SCHEMA_FILE);
+ if ($sprinklesFile === FALSE) {
+ $sprinklesFile = $this->setupBaseSprinkleList();
+ }
+
+ // Create Symfony Console App
+ $this->app = new Application("UserFrosting Bakery", \UserFrosting\VERSION);
+
+ // Setup the sprinkles
+ $uf = new UserFrosting();
+
+ // Set argument as false, we are using the CLI
+ $uf->setupSprinkles(FALSE);
+
+ // Get the container
+ $this->ci = $uf->getContainer();
+
+ // Add each commands to the Console App
+ $this->loadCommands();
+ }
+
+ /**
+ * Run the Symfony Console App
+ */
+ public function run() {
+ $this->app->run();
+ }
+
+ /**
+ * Return the list of available commands for a specific sprinkle
+ */
+ protected function loadCommands() {
+ // Get base Bakery command
+ $commands = $this->getBakeryCommands();
+
+ // Get the sprinkles commands
+ $sprinkles = $this->ci->sprinkleManager->getSprinkleNames();
+ foreach ($sprinkles as $sprinkle) {
+ $commands = $commands->merge($this->getSprinkleCommands($sprinkle));
+ }
+
+ // Add commands to the App
+ $commands->each(function ($command) {
+ $instance = new $command();
+ $instance->setContainer($this->ci);
+ $this->app->add($instance);
+ });
+ }
+
+ /**
+ * Return the list of available commands for a specific sprinkle
+ * Sprinkles commands should be located in `src/Bakery/`
+ */
+ protected function getSprinkleCommands($sprinkle) {
+ // Find all the migration files
+ $path = $this->commandDirectoryPath($sprinkle);
+ $files = glob($path . "*.php");
+ $commands = collect($files);
+
+ // Transform the path into a class names
+ $commands->transform(function ($file) use ($sprinkle, $path) {
+ $className = basename($file, '.php');
+ $sprinkleName = Str::studly($sprinkle);
+ $className = "\\UserFrosting\\Sprinkle\\" . $sprinkleName . "\\Bakery\\" . $className;
+ return $className;
+ });
+
+ return $commands;
+ }
+
+ /**
+ * Return the list of available commands in system/Bakery/Command/
+ */
+ protected function getBakeryCommands() {
+ // Find all the migration files
+ $files = glob(\UserFrosting\APP_DIR . "/system/Bakery/Command/" . "*.php");
+ $commands = collect($files);
+
+ // Transform the path into a class names
+ $commands->transform(function ($file) {
+ $className = basename($file, '.php');
+ $className = "\\UserFrosting\\System\\Bakery\\Command\\" . $className;
+ return $className;
+ });
+
+ return $commands;
+ }
+
+ /**
+ * Returns the path of the Migration directory.
+ *
+ * @access protected
+ * @param mixed $sprinkleName
+ * @return void
+ */
+ protected function commandDirectoryPath($sprinkleName) {
+ return \UserFrosting\SPRINKLES_DIR .
+ \UserFrosting\DS .
+ $sprinkleName .
+ \UserFrosting\DS .
+ \UserFrosting\SRC_DIR_NAME .
+ "/Bakery/";
+ }
+
+ /**
+ * Write the base Sprinkles schema file if it doesn't exist.
+ *
+ * @access protected
+ * @return void
+ */
+ protected function setupBaseSprinkleList() {
+ $model = \UserFrosting\APP_DIR . '/sprinkles.example.json';
+ $destination = \UserFrosting\SPRINKLES_SCHEMA_FILE;
+ $sprinklesModelFile = @file_get_contents($model);
+ if ($sprinklesModelFile === FALSE) {
+ $this->io->error("File `$sprinklesModelFile` not found. Please create '$destination' manually and try again.");
+ exit(1);
+ }
+
+ file_put_contents($destination, $sprinklesModelFile);
+
+ return $sprinklesModelFile;
+ }
+}
diff --git a/main/app/system/Bakery/BaseCommand.php b/main/app/system/Bakery/BaseCommand.php
index bc1c005..bcefe3d 100644
--- a/main/app/system/Bakery/BaseCommand.php
+++ b/main/app/system/Bakery/BaseCommand.php
@@ -1,57 +1,57 @@
-<?php
-/**
- * UserFrosting (http://www.userfrosting.com)
- *
- * @link https://github.com/userfrosting/UserFrosting
- * @license https://github.com/userfrosting/UserFrosting/blob/master/licenses/UserFrosting.md (MIT License)
- */
-
-namespace UserFrosting\System\Bakery;
-
-use Symfony\Component\Console\Command\Command;
-use Symfony\Component\Console\Input\InputInterface;
-use Symfony\Component\Console\Output\OutputInterface;
-use Symfony\Component\Console\Input\InputArgument;
-use Symfony\Component\Console\Input\InputOption;
-use Symfony\Component\Console\Formatter\OutputFormatterStyle;
-use Symfony\Component\Console\Style\SymfonyStyle;
-use Interop\Container\ContainerInterface;
-
-/**
- * Base class for UserFrosting Bakery CLI tools.
- *
- * @author Alex Weissman (https://alexanderweissman.com)
- */
-abstract class BaseCommand extends Command
-{
- /**
- * @var @Symfony\Component\Console\Style\SymfonyStyle
- * See http://symfony.com/doc/current/console/style.html
- */
- protected $io;
-
- /**
- * @var string Path to the project root folder
- */
- protected $projectRoot;
-
- /**
- * @var ContainerInterface $ci The global container object, which holds all of the UserFrosting services.
- */
- protected $ci;
-
- /**
- * {@inheritDoc}
- */
- protected function initialize(InputInterface $input, OutputInterface $output) {
- $this->io = new SymfonyStyle($input, $output);
- $this->projectRoot = \UserFrosting\ROOT_DIR;
- }
-
- /**
- * Setup the global container object
- */
- public function setContainer(ContainerInterface $ci) {
- $this->ci = $ci;
- }
-}
+<?php
+/**
+ * UserFrosting (http://www.userfrosting.com)
+ *
+ * @link https://github.com/userfrosting/UserFrosting
+ * @license https://github.com/userfrosting/UserFrosting/blob/master/licenses/UserFrosting.md (MIT License)
+ */
+
+namespace UserFrosting\System\Bakery;
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Formatter\OutputFormatterStyle;
+use Symfony\Component\Console\Style\SymfonyStyle;
+use Interop\Container\ContainerInterface;
+
+/**
+ * Base class for UserFrosting Bakery CLI tools.
+ *
+ * @author Alex Weissman (https://alexanderweissman.com)
+ */
+abstract class BaseCommand extends Command
+{
+ /**
+ * @var @Symfony\Component\Console\Style\SymfonyStyle
+ * See http://symfony.com/doc/current/console/style.html
+ */
+ protected $io;
+
+ /**
+ * @var string Path to the project root folder
+ */
+ protected $projectRoot;
+
+ /**
+ * @var ContainerInterface $ci The global container object, which holds all of the UserFrosting services.
+ */
+ protected $ci;
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function initialize(InputInterface $input, OutputInterface $output) {
+ $this->io = new SymfonyStyle($input, $output);
+ $this->projectRoot = \UserFrosting\ROOT_DIR;
+ }
+
+ /**
+ * Setup the global container object
+ */
+ public function setContainer(ContainerInterface $ci) {
+ $this->ci = $ci;
+ }
+}
diff --git a/main/app/system/Bakery/Command/Bake.php b/main/app/system/Bakery/Command/Bake.php
index d12dccd..999171c 100644
--- a/main/app/system/Bakery/Command/Bake.php
+++ b/main/app/system/Bakery/Command/Bake.php
@@ -1,76 +1,76 @@
-<?php
-/**
- * UserFrosting (http://www.userfrosting.com)
- *
- * @link https://github.com/userfrosting/UserFrosting
- * @license https://github.com/userfrosting/UserFrosting/blob/master/licenses/UserFrosting.md (MIT License)
- */
-
-namespace UserFrosting\System\Bakery\Command;
-
-use Symfony\Component\Console\Input\InputInterface;
-use Symfony\Component\Console\Output\OutputInterface;
-use Symfony\Component\Console\Input\InputArgument;
-use Symfony\Component\Console\Input\InputOption;
-use UserFrosting\System\Bakery\BaseCommand;
-
-/**
- * Bake command.
- * Shortcut to run multiple commands at once
- *
- * @author Alex Weissman (https://alexanderweissman.com)
- */
-class Bake extends BaseCommand
-{
- /**
- * @var string Path to the build/ directory
- */
- protected $buildPath;
-
- /**
- * @var String $ufArt The UserFrosting ASCII art.
- */
- public $title = "
- _ _ ______ _ _
-| | | | | ___| | | (_)
-| | | |___ ___ _ __| |_ _ __ ___ ___| |_ _ _ __ __ _
-| | | / __|/ _ \ '__| _| '__/ _ \/ __| __| | '_ \ / _` |
-| |_| \__ \ __/ | | | | | | (_) \__ \ |_| | | | | (_| |
- \___/|___/\___|_| \_| |_| \___/|___/\__|_|_| |_|\__, |
- __/ |
- |___/";
-
- /**
- * {@inheritDoc}
- */
- protected function configure() {
- $this->setName("bake")
- ->setDescription("UserFrosting installation command")
- ->setHelp("This command combine the <info>debug</info>, <info>migrate</info> and <info>build-assets</info> commands.");
- }
-
- /**
- * {@inheritDoc}
- */
- protected function execute(InputInterface $input, OutputInterface $output) {
- $this->io->writeln("<info>{$this->title}</info>");
-
- $command = $this->getApplication()->find('setup');
- $command->run($input, $output);
-
- $command = $this->getApplication()->find('debug');
- $command->run($input, $output);
-
- $command = $this->getApplication()->find('migrate');
- $command->run($input, $output);
-
- $command = $this->getApplication()->find('create-admin');
- $command->run($input, $output);
-
- $command = $this->getApplication()->find('build-assets');
- $command->run($input, $output);
-
- $command = $this->getApplication()->find('clear-cache');
- $command->run($input, $output);
- }
+<?php
+/**
+ * UserFrosting (http://www.userfrosting.com)
+ *
+ * @link https://github.com/userfrosting/UserFrosting
+ * @license https://github.com/userfrosting/UserFrosting/blob/master/licenses/UserFrosting.md (MIT License)
+ */
+
+namespace UserFrosting\System\Bakery\Command;
+
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+use UserFrosting\System\Bakery\BaseCommand;
+
+/**
+ * Bake command.
+ * Shortcut to run multiple commands at once
+ *
+ * @author Alex Weissman (https://alexanderweissman.com)
+ */
+class Bake extends BaseCommand
+{
+ /**
+ * @var string Path to the build/ directory
+ */
+ protected $buildPath;
+
+ /**
+ * @var String $ufArt The UserFrosting ASCII art.
+ */
+ public $title = "
+ _ _ ______ _ _
+| | | | | ___| | | (_)
+| | | |___ ___ _ __| |_ _ __ ___ ___| |_ _ _ __ __ _
+| | | / __|/ _ \ '__| _| '__/ _ \/ __| __| | '_ \ / _` |
+| |_| \__ \ __/ | | | | | | (_) \__ \ |_| | | | | (_| |
+ \___/|___/\___|_| \_| |_| \___/|___/\__|_|_| |_|\__, |
+ __/ |
+ |___/";
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function configure() {
+ $this->setName("bake")
+ ->setDescription("UserFrosting installation command")
+ ->setHelp("This command combine the <info>debug</info>, <info>migrate</info> and <info>build-assets</info> commands.");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function execute(InputInterface $input, OutputInterface $output) {
+ $this->io->writeln("<info>{$this->title}</info>");
+
+ $command = $this->getApplication()->find('setup');
+ $command->run($input, $output);
+
+ $command = $this->getApplication()->find('debug');
+ $command->run($input, $output);
+
+ $command = $this->getApplication()->find('migrate');
+ $command->run($input, $output);
+
+ $command = $this->getApplication()->find('create-admin');
+ $command->run($input, $output);
+
+ $command = $this->getApplication()->find('build-assets');
+ $command->run($input, $output);
+
+ $command = $this->getApplication()->find('clear-cache');
+ $command->run($input, $output);
+ }
} \ No newline at end of file
diff --git a/main/app/system/Bakery/Command/BuildAssets.php b/main/app/system/Bakery/Command/BuildAssets.php
index 4a1ab99..d7df634 100644
--- a/main/app/system/Bakery/Command/BuildAssets.php
+++ b/main/app/system/Bakery/Command/BuildAssets.php
@@ -1,173 +1,173 @@
-<?php
-/**
- * UserFrosting (http://www.userfrosting.com)
- *
- * @link https://github.com/userfrosting/UserFrosting
- * @license https://github.com/userfrosting/UserFrosting/blob/master/licenses/UserFrosting.md (MIT License)
- */
-
-namespace UserFrosting\System\Bakery\Command;
-
-use Symfony\Component\Console\Input\InputInterface;
-use Symfony\Component\Console\Output\OutputInterface;
-use Symfony\Component\Console\Input\InputArgument;
-use Symfony\Component\Console\Input\InputOption;
-use UserFrosting\System\Bakery\BaseCommand;
-
-/**
- * Assets builder CLI Tools.
- * Wrapper for npm/node commands
- *
- * @author Alex Weissman (https://alexanderweissman.com)
- */
-class BuildAssets extends BaseCommand
-{
- /**
- * @var string Path to the build/ directory
- */
- protected $buildPath;
-
- /**
- * {@inheritDoc}
- */
- protected function configure() {
- $this->setName("build-assets")
- ->setDescription("Build the assets using node and npm")
- ->setHelp("The build directory contains the scripts and configuration files required to download Javascript, CSS, and other assets used by UserFrosting. This command will install Gulp, Bower, and several other required npm packages locally. With <info>npm</info> set up with all of its required packages, it can be use it to automatically download and install the assets in the correct directories. For more info, see <comment>https://learn.userfrosting.com/basics/installation</comment>")
- ->addOption("compile", "c", InputOption::VALUE_NONE, "Compile the assets and asset bundles for production environment")
- ->addOption("force", "f", InputOption::VALUE_NONE, "Force assets compilation by deleting cached data and installed assets before proceeding");
- }
-
- /**
- * {@inheritDoc}
- */
- protected function execute(InputInterface $input, OutputInterface $output) {
- // Display header,
- $this->io->title("UserFrosting's Assets Builder");
-
- // Set $path
- $this->buildPath = $this->projectRoot . \UserFrosting\DS . \UserFrosting\BUILD_DIR_NAME;
-
- // Delete cached data is requested
- if ($input->getOption('force')) {
- $this->clean();
- }
-
- // Perform tasks
- $this->npmInstall();
- $this->assetsInstall();
-
- // Compile if requested
- if ($input->getOption('compile') || $this->isProduction()) {
- $this->buildAssets();
- }
-
- // Test the result
- $this->checkAssets();
-
- // If all went well and there's no fatal errors, we are successful
- $this->io->success("Assets install looks successful");
- }
-
- /**
- * Install npm package
- *
- * @access protected
- * @return void
- */
- protected function npmInstall() {
- $this->io->section("<info>Installing npm dependencies</info>");
- $this->io->writeln("> <comment>npm install</comment>");
-
- // Temporarily change the working directory so we can install npm dependencies
- $wd = getcwd();
- chdir($this->buildPath);
- passthru("npm install");
- chdir($wd);
- }
-
- /**
- * Perform UF Assets installation
- *
- * @access protected
- * @return void
- */
- protected function assetsInstall() {
- $this->io->section("Installing assets bundles");
- $this->io->writeln("> <comment>npm run uf-assets-install</comment>");
- passthru("npm run uf-assets-install --prefix " . $this->buildPath);
- }
-
- /**
- * Build the production bundle.
- *
- * @access protected
- * @return void
- */
- protected function buildAssets() {
- $this->io->section("Building assets for production");
-
- $this->io->writeln("> <comment>npm run uf-bundle-build</comment>");
- passthru("npm run uf-bundle-build --prefix " . $this->buildPath);
-
- $this->io->writeln("> <comment>npm run uf-bundle</comment>");
- passthru("npm run uf-bundle --prefix " . $this->buildPath);
-
- $this->io->writeln("> <comment>npm run uf-bundle-clean</comment>");
- passthru("npm run uf-bundle-clean --prefix " . $this->buildPath);
- }
-
- /**
- * Check that the assets where installed in the core sprinkles
- *
- * @access protected
- * @return void
- */
- protected function checkAssets() {
- $this->io->section("Testing assets installation");
-
- // Get path and vendor files
- $vendorPath = \UserFrosting\SPRINKLES_DIR . "/core/assets/vendor/*";
- $coreVendorFiles = glob($vendorPath);
-
- if (!$coreVendorFiles) {
- $this->io->error("Assets installation seems to have failed. Directory `$vendorPath` is empty, but it shouldn't be. Check the above log for any errors.");
- exit(1);
- }
-
- // Check that `bundle.result.json` is present in production mode
- $config = $this->ci->config;
- $resultFile = \UserFrosting\ROOT_DIR . \UserFrosting\DS . \UserFrosting\BUILD_DIR_NAME . \UserFrosting\DS . $config['assets.compiled.schema'];
- if ($this->isProduction() && !file_exists($resultFile)) {
- $this->io->error("Assets building seems to have failed. File `$resultFile` not found. This file is required for production envrionement. Check the above log for any errors.");
- exit(1);
- }
- }
-
- /**
- * Run the `uf-clean` command to delete installed assets, delete compiled
- * bundle config file and delete compiled assets
- *
- * @access protected
- * @return void
- */
- protected function clean() {
- $this->io->section("Cleaning cached data");
- $this->io->writeln("> <comment>npm run uf-clean</comment>");
- passthru("npm run uf-clean --prefix " . $this->buildPath);
- }
-
- /**
- * Return if the app is in production mode
- *
- * @access protected
- * @return bool
- */
- protected function isProduction() {
- // N.B.: Need to touch the config service first to load dotenv values
- $config = $this->ci->config;
- $mode = getenv("UF_MODE") ?: '';
-
- return ($mode == "production");
- }
+<?php
+/**
+ * UserFrosting (http://www.userfrosting.com)
+ *
+ * @link https://github.com/userfrosting/UserFrosting
+ * @license https://github.com/userfrosting/UserFrosting/blob/master/licenses/UserFrosting.md (MIT License)
+ */
+
+namespace UserFrosting\System\Bakery\Command;
+
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+use UserFrosting\System\Bakery\BaseCommand;
+
+/**
+ * Assets builder CLI Tools.
+ * Wrapper for npm/node commands
+ *
+ * @author Alex Weissman (https://alexanderweissman.com)
+ */
+class BuildAssets extends BaseCommand
+{
+ /**
+ * @var string Path to the build/ directory
+ */
+ protected $buildPath;
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function configure() {
+ $this->setName("build-assets")
+ ->setDescription("Build the assets using node and npm")
+ ->setHelp("The build directory contains the scripts and configuration files required to download Javascript, CSS, and other assets used by UserFrosting. This command will install Gulp, Bower, and several other required npm packages locally. With <info>npm</info> set up with all of its required packages, it can be use it to automatically download and install the assets in the correct directories. For more info, see <comment>https://learn.userfrosting.com/basics/installation</comment>")
+ ->addOption("compile", "c", InputOption::VALUE_NONE, "Compile the assets and asset bundles for production environment")
+ ->addOption("force", "f", InputOption::VALUE_NONE, "Force assets compilation by deleting cached data and installed assets before proceeding");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function execute(InputInterface $input, OutputInterface $output) {
+ // Display header,
+ $this->io->title("UserFrosting's Assets Builder");
+
+ // Set $path
+ $this->buildPath = $this->projectRoot . \UserFrosting\DS . \UserFrosting\BUILD_DIR_NAME;
+
+ // Delete cached data is requested
+ if ($input->getOption('force')) {
+ $this->clean();
+ }
+
+ // Perform tasks
+ $this->npmInstall();
+ $this->assetsInstall();
+
+ // Compile if requested
+ if ($input->getOption('compile') || $this->isProduction()) {
+ $this->buildAssets();
+ }
+
+ // Test the result
+ $this->checkAssets();
+
+ // If all went well and there's no fatal errors, we are successful
+ $this->io->success("Assets install looks successful");
+ }
+
+ /**
+ * Install npm package
+ *
+ * @access protected
+ * @return void
+ */
+ protected function npmInstall() {
+ $this->io->section("<info>Installing npm dependencies</info>");
+ $this->io->writeln("> <comment>npm install</comment>");
+
+ // Temporarily change the working directory so we can install npm dependencies
+ $wd = getcwd();
+ chdir($this->buildPath);
+ passthru("npm install");
+ chdir($wd);
+ }
+
+ /**
+ * Perform UF Assets installation
+ *
+ * @access protected
+ * @return void
+ */
+ protected function assetsInstall() {
+ $this->io->section("Installing assets bundles");
+ $this->io->writeln("> <comment>npm run uf-assets-install</comment>");
+ passthru("npm run uf-assets-install --prefix " . $this->buildPath);
+ }
+
+ /**
+ * Build the production bundle.
+ *
+ * @access protected
+ * @return void
+ */
+ protected function buildAssets() {
+ $this->io->section("Building assets for production");
+
+ $this->io->writeln("> <comment>npm run uf-bundle-build</comment>");
+ passthru("npm run uf-bundle-build --prefix " . $this->buildPath);
+
+ $this->io->writeln("> <comment>npm run uf-bundle</comment>");
+ passthru("npm run uf-bundle --prefix " . $this->buildPath);
+
+ $this->io->writeln("> <comment>npm run uf-bundle-clean</comment>");
+ passthru("npm run uf-bundle-clean --prefix " . $this->buildPath);
+ }
+
+ /**
+ * Check that the assets where installed in the core sprinkles
+ *
+ * @access protected
+ * @return void
+ */
+ protected function checkAssets() {
+ $this->io->section("Testing assets installation");
+
+ // Get path and vendor files
+ $vendorPath = \UserFrosting\SPRINKLES_DIR . "/core/assets/vendor/*";
+ $coreVendorFiles = glob($vendorPath);
+
+ if (!$coreVendorFiles) {
+ $this->io->error("Assets installation seems to have failed. Directory `$vendorPath` is empty, but it shouldn't be. Check the above log for any errors.");
+ exit(1);
+ }
+
+ // Check that `bundle.result.json` is present in production mode
+ $config = $this->ci->config;
+ $resultFile = \UserFrosting\ROOT_DIR . \UserFrosting\DS . \UserFrosting\BUILD_DIR_NAME . \UserFrosting\DS . $config['assets.compiled.schema'];
+ if ($this->isProduction() && !file_exists($resultFile)) {
+ $this->io->error("Assets building seems to have failed. File `$resultFile` not found. This file is required for production envrionement. Check the above log for any errors.");
+ exit(1);
+ }
+ }
+
+ /**
+ * Run the `uf-clean` command to delete installed assets, delete compiled
+ * bundle config file and delete compiled assets
+ *
+ * @access protected
+ * @return void
+ */
+ protected function clean() {
+ $this->io->section("Cleaning cached data");
+ $this->io->writeln("> <comment>npm run uf-clean</comment>");
+ passthru("npm run uf-clean --prefix " . $this->buildPath);
+ }
+
+ /**
+ * Return if the app is in production mode
+ *
+ * @access protected
+ * @return bool
+ */
+ protected function isProduction() {
+ // N.B.: Need to touch the config service first to load dotenv values
+ $config = $this->ci->config;
+ $mode = getenv("UF_MODE") ?: '';
+
+ return ($mode == "production");
+ }
} \ No newline at end of file
diff --git a/main/app/system/Bakery/Command/ClearCache.php b/main/app/system/Bakery/Command/ClearCache.php
index 4d30209..ca8e5ed 100644
--- a/main/app/system/Bakery/Command/ClearCache.php
+++ b/main/app/system/Bakery/Command/ClearCache.php
@@ -1,91 +1,91 @@
-<?php
-/**
- * UserFrosting (http://www.userfrosting.com)
- *
- * @link https://github.com/userfrosting/UserFrosting
- * @license https://github.com/userfrosting/UserFrosting/blob/master/licenses/UserFrosting.md (MIT License)
- */
-
-namespace UserFrosting\System\Bakery\Command;
-
-use Symfony\Component\Console\Input\InputInterface;
-use Symfony\Component\Console\Output\OutputInterface;
-use Symfony\Component\Console\Input\InputArgument;
-use Symfony\Component\Console\Input\InputOption;
-use UserFrosting\System\Bakery\BaseCommand;
-use UserFrosting\Sprinkle\Core\Twig\CacheHelper;
-
-/**
- * ClearCache CLI Command.
- *
- * @author Alex Weissman (https://alexanderweissman.com)
- */
-class ClearCache extends BaseCommand
-{
- /**
- * {@inheritDoc}
- */
- protected function configure() {
- $this->setName("clear-cache")
- ->setDescription("Clears the application cache. Includes cache service, Twig and Router cached data");
- }
-
- /**
- * {@inheritDoc}
- */
- protected function execute(InputInterface $input, OutputInterface $output) {
- $this->io->title("Clearing cache");
-
- // Clear normal cache
- $this->io->writeln("<info> > Clearing Illuminate cache instance</info>", OutputInterface::VERBOSITY_VERBOSE);
- $this->clearIlluminateCache();
-
- // Clear Twig cache
- $this->io->writeln("<info> > Clearing Twig cached data</info>", OutputInterface::VERBOSITY_VERBOSE);
- if (!$this->clearTwigCache()) {
- $this->io->error("Failed to clear Twig cached data. Make sure you have write access to the `app/cache/twig` directory.");
- exit(1);
- }
-
- // Clear router cache
- $this->io->writeln("<info> > Clearing Router cache file</info>", OutputInterface::VERBOSITY_VERBOSE);
- if (!$this->clearRouterCache()) {
- $file = $this->ci->config['settings.routerCacheFile'];
- $this->io->error("Failed to delete Router cache file. Make sure you have write access to the `$file` file.");
- exit(1);
- }
-
- $this->io->success("Cache cleared !");
- }
-
- /**
- * Flush the cached data from the cache service
- *
- * @access protected
- * @return void
- */
- protected function clearIlluminateCache() {
- $this->ci->cache->flush();
- }
-
- /**
- * Clear the Twig cache using the Twig CacheHelper class
- *
- * @access protected
- * @return bool true/false if operation is successfull
- */
- protected function clearTwigCache() {
- $cacheHelper = new CacheHelper($this->ci);
- return $cacheHelper->clearCache();
- }
-
- /**
- * Clear the Router cache data file
- *
- * @access protected
- * @return bool true/false if operation is successfull
- */
- protected function clearRouterCache() {
- return $this->ci->router->clearCache();
- }
+<?php
+/**
+ * UserFrosting (http://www.userfrosting.com)
+ *
+ * @link https://github.com/userfrosting/UserFrosting
+ * @license https://github.com/userfrosting/UserFrosting/blob/master/licenses/UserFrosting.md (MIT License)
+ */
+
+namespace UserFrosting\System\Bakery\Command;
+
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+use UserFrosting\System\Bakery\BaseCommand;
+use UserFrosting\Sprinkle\Core\Twig\CacheHelper;
+
+/**
+ * ClearCache CLI Command.
+ *
+ * @author Alex Weissman (https://alexanderweissman.com)
+ */
+class ClearCache extends BaseCommand
+{
+ /**
+ * {@inheritDoc}
+ */
+ protected function configure() {
+ $this->setName("clear-cache")
+ ->setDescription("Clears the application cache. Includes cache service, Twig and Router cached data");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function execute(InputInterface $input, OutputInterface $output) {
+ $this->io->title("Clearing cache");
+
+ // Clear normal cache
+ $this->io->writeln("<info> > Clearing Illuminate cache instance</info>", OutputInterface::VERBOSITY_VERBOSE);
+ $this->clearIlluminateCache();
+
+ // Clear Twig cache
+ $this->io->writeln("<info> > Clearing Twig cached data</info>", OutputInterface::VERBOSITY_VERBOSE);
+ if (!$this->clearTwigCache()) {
+ $this->io->error("Failed to clear Twig cached data. Make sure you have write access to the `app/cache/twig` directory.");
+ exit(1);
+ }
+
+ // Clear router cache
+ $this->io->writeln("<info> > Clearing Router cache file</info>", OutputInterface::VERBOSITY_VERBOSE);
+ if (!$this->clearRouterCache()) {
+ $file = $this->ci->config['settings.routerCacheFile'];
+ $this->io->error("Failed to delete Router cache file. Make sure you have write access to the `$file` file.");
+ exit(1);
+ }
+
+ $this->io->success("Cache cleared !");
+ }
+
+ /**
+ * Flush the cached data from the cache service
+ *
+ * @access protected
+ * @return void
+ */
+ protected function clearIlluminateCache() {
+ $this->ci->cache->flush();
+ }
+
+ /**
+ * Clear the Twig cache using the Twig CacheHelper class
+ *
+ * @access protected
+ * @return bool true/false if operation is successfull
+ */
+ protected function clearTwigCache() {
+ $cacheHelper = new CacheHelper($this->ci);
+ return $cacheHelper->clearCache();
+ }
+
+ /**
+ * Clear the Router cache data file
+ *
+ * @access protected
+ * @return bool true/false if operation is successfull
+ */
+ protected function clearRouterCache() {
+ return $this->ci->router->clearCache();
+ }
} \ No newline at end of file
diff --git a/main/app/system/Bakery/Command/Debug.php b/main/app/system/Bakery/Command/Debug.php
index 60565a4..efbf229 100644
--- a/main/app/system/Bakery/Command/Debug.php
+++ b/main/app/system/Bakery/Command/Debug.php
@@ -1,178 +1,178 @@
-<?php
-/**
- * UserFrosting (http://www.userfrosting.com)
- *
- * @link https://github.com/userfrosting/UserFrosting
- * @license https://github.com/userfrosting/UserFrosting/blob/master/licenses/UserFrosting.md (MIT License)
- */
-
-namespace UserFrosting\System\Bakery\Command;
-
-use Symfony\Component\Console\Input\InputInterface;
-use Symfony\Component\Console\Output\OutputInterface;
-use Symfony\Component\Console\Input\InputArgument;
-use Symfony\Component\Console\Input\InputOption;
-use UserFrosting\System\Bakery\BaseCommand;
-use UserFrosting\System\Bakery\DatabaseTest;
-
-/**
- * Debug CLI tool.
- *
- * @author Alex Weissman (https://alexanderweissman.com)
- */
-class Debug extends BaseCommand
-{
- use DatabaseTest;
-
- /**
- * {@inheritDoc}
- */
- protected function configure() {
- $this->setName("debug")
- ->setDescription("Test the UserFrosting installation and setup the database")
- ->setHelp("This command is used to check if the various dependencies of UserFrosting are met and display useful debugging information. \nIf any error occurs, check out the online documentation for more info about that error. \nThis command also provide the necessary tools to setup the database credentials");
- }
-
- /**
- * {@inheritDoc}
- */
- protected function execute(InputInterface $input, OutputInterface $output) {
- // Display header,
- $this->io->title("UserFrosting");
- $this->io->writeln("UserFrosing version : " . \UserFrosting\VERSION);
- $this->io->writeln("OS Name : " . php_uname('s'));
- $this->io->writeln("Project Root : {$this->projectRoot}");
-
- // Need to touch the config service first to load dotenv values
- $config = $this->ci->config;
- $this->io->writeln("Environment mode : " . getenv("UF_MODE"));
-
- // Perform tasks
- $this->checkPhpVersion();
- $this->checkNodeVersion();
- $this->checkNpmVersion();
- $this->listSprinkles();
- $this->showConfig();
- $this->checkDatabase();
-
- // If all went well and there's no fatal errors, we are ready to bake
- $this->io->success("Ready to bake !");
- }
-
- /**
- * Check the minimum version of php.
- * This is done by composer itself, but we do it again for good mesure
- *
- * @access public
- * @return void
- */
- protected function checkPhpVersion() {
- $this->io->writeln("PHP Version : " . phpversion());
- if (version_compare(phpversion(), \UserFrosting\PHP_MIN_VERSION, '<')) {
- $this->io->error("UserFrosting requires php version " . \UserFrosting\PHP_MIN_VERSION . " or above. You'll need to update you PHP version before you can continue.");
- exit(1);
- }
- }
-
- /**
- * Check the minimum version requirement of Node installed
- *
- * @access public
- * @return void
- */
- protected function checkNodeVersion() {
- $npmVersion = trim(exec('node -v'));
- $this->io->writeln("Node Version : $npmVersion");
-
- if (version_compare($npmVersion, 'v4', '<')) {
- $this->io->error("UserFrosting requires Node version 4.x or above. Check the documentation for more details.");
- exit(1);
- }
- }
-
- /**
- * Check the minimum version requirement for Npm
- *
- * @access public
- * @return void
- */
- protected function checkNpmVersion() {
- $npmVersion = trim(exec('npm -v'));
- $this->io->writeln("NPM Version : $npmVersion");
-
- if (version_compare($npmVersion, '3', '<')) {
- $this->io->error("UserFrosting requires npm version 3.x or above. Check the documentation for more details.");
- exit(1);
- }
- }
-
- /**
- * List all sprinkles defined in the Sprinkles schema file,
- * making sure this file exist at the same time
- *
- * @access protected
- * @return void
- */
- protected function listSprinkles() {
- // Check for Sprinkles schema file
- $path = \UserFrosting\SPRINKLES_SCHEMA_FILE;
- $sprinklesFile = @file_get_contents($path);
- if ($sprinklesFile === FALSE) {
- $this->io->error("The file `$path` not found.");
- }
-
- // List installed sprinkles
- $sprinkles = json_decode($sprinklesFile)->base;
- $this->io->section("Loaded sprinkles");
- $this->io->listing($sprinkles);
-
- // Throw fatal error if the `core` sprinkle is missing
- if (!in_array("core", $sprinkles)) {
- $this->io->error("The `core` sprinkle is missing from the 'sprinkles.json' file.");
- exit(1);
- }
- }
-
- /**
- * Check the database connexion and setup the `.env` file if we can't
- * connect and there's no one found.
- *
- * @access protected
- * @return void
- */
- protected function checkDatabase() {
- $this->io->section("Testing database connection...");
-
- try {
- $this->testDB();
- $this->io->writeln("Database connection successful");
- return;
- } catch (\Exception $e) {
- $error = $e->getMessage();
- $this->io->error($error);
- exit(1);
- }
- }
-
- /**
- * Display database config as for debug purposes
- *
- * @access protected
- * @return void
- */
- protected function showConfig() {
- // Get config
- $config = $this->ci->config;
-
- // Display database info
- $this->io->section("Database config");
- $this->io->writeln([
- "DRIVER : " . $config['db.default.driver'],
- "HOST : " . $config['db.default.host'],
- "PORT : " . $config['db.default.port'],
- "DATABASE : " . $config['db.default.database'],
- "USERNAME : " . $config['db.default.username'],
- "PASSWORD : " . ($config['db.default.password'] ? "*********" : "")
- ]);
- }
-}
+<?php
+/**
+ * UserFrosting (http://www.userfrosting.com)
+ *
+ * @link https://github.com/userfrosting/UserFrosting
+ * @license https://github.com/userfrosting/UserFrosting/blob/master/licenses/UserFrosting.md (MIT License)
+ */
+
+namespace UserFrosting\System\Bakery\Command;
+
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+use UserFrosting\System\Bakery\BaseCommand;
+use UserFrosting\System\Bakery\DatabaseTest;
+
+/**
+ * Debug CLI tool.
+ *
+ * @author Alex Weissman (https://alexanderweissman.com)
+ */
+class Debug extends BaseCommand
+{
+ use DatabaseTest;
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function configure() {
+ $this->setName("debug")
+ ->setDescription("Test the UserFrosting installation and setup the database")
+ ->setHelp("This command is used to check if the various dependencies of UserFrosting are met and display useful debugging information. \nIf any error occurs, check out the online documentation for more info about that error. \nThis command also provide the necessary tools to setup the database credentials");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function execute(InputInterface $input, OutputInterface $output) {
+ // Display header,
+ $this->io->title("UserFrosting");
+ $this->io->writeln("UserFrosing version : " . \UserFrosting\VERSION);
+ $this->io->writeln("OS Name : " . php_uname('s'));
+ $this->io->writeln("Project Root : {$this->projectRoot}");
+
+ // Need to touch the config service first to load dotenv values
+ $config = $this->ci->config;
+ $this->io->writeln("Environment mode : " . getenv("UF_MODE"));
+
+ // Perform tasks
+ $this->checkPhpVersion();
+ $this->checkNodeVersion();
+ $this->checkNpmVersion();
+ $this->listSprinkles();
+ $this->showConfig();
+ $this->checkDatabase();
+
+ // If all went well and there's no fatal errors, we are ready to bake
+ $this->io->success("Ready to bake !");
+ }
+
+ /**
+ * Check the minimum version of php.
+ * This is done by composer itself, but we do it again for good mesure
+ *
+ * @access public
+ * @return void
+ */
+ protected function checkPhpVersion() {
+ $this->io->writeln("PHP Version : " . phpversion());
+ if (version_compare(phpversion(), \UserFrosting\PHP_MIN_VERSION, '<')) {
+ $this->io->error("UserFrosting requires php version " . \UserFrosting\PHP_MIN_VERSION . " or above. You'll need to update you PHP version before you can continue.");
+ exit(1);
+ }
+ }
+
+ /**
+ * Check the minimum version requirement of Node installed
+ *
+ * @access public
+ * @return void
+ */
+ protected function checkNodeVersion() {
+ $npmVersion = trim(exec('node -v'));
+ $this->io->writeln("Node Version : $npmVersion");
+
+ if (version_compare($npmVersion, 'v4', '<')) {
+ $this->io->error("UserFrosting requires Node version 4.x or above. Check the documentation for more details.");
+ exit(1);
+ }
+ }
+
+ /**
+ * Check the minimum version requirement for Npm
+ *
+ * @access public
+ * @return void
+ */
+ protected function checkNpmVersion() {
+ $npmVersion = trim(exec('npm -v'));
+ $this->io->writeln("NPM Version : $npmVersion");
+
+ if (version_compare($npmVersion, '3', '<')) {
+ $this->io->error("UserFrosting requires npm version 3.x or above. Check the documentation for more details.");
+ exit(1);
+ }
+ }
+
+ /**
+ * List all sprinkles defined in the Sprinkles schema file,
+ * making sure this file exist at the same time
+ *
+ * @access protected
+ * @return void
+ */
+ protected function listSprinkles() {
+ // Check for Sprinkles schema file
+ $path = \UserFrosting\SPRINKLES_SCHEMA_FILE;
+ $sprinklesFile = @file_get_contents($path);
+ if ($sprinklesFile === FALSE) {
+ $this->io->error("The file `$path` not found.");
+ }
+
+ // List installed sprinkles
+ $sprinkles = json_decode($sprinklesFile)->base;
+ $this->io->section("Loaded sprinkles");
+ $this->io->listing($sprinkles);
+
+ // Throw fatal error if the `core` sprinkle is missing
+ if (!in_array("core", $sprinkles)) {
+ $this->io->error("The `core` sprinkle is missing from the 'sprinkles.json' file.");
+ exit(1);
+ }
+ }
+
+ /**
+ * Check the database connexion and setup the `.env` file if we can't
+ * connect and there's no one found.
+ *
+ * @access protected
+ * @return void
+ */
+ protected function checkDatabase() {
+ $this->io->section("Testing database connection...");
+
+ try {
+ $this->testDB();
+ $this->io->writeln("Database connection successful");
+ return;
+ } catch (\Exception $e) {
+ $error = $e->getMessage();
+ $this->io->error($error);
+ exit(1);
+ }
+ }
+
+ /**
+ * Display database config as for debug purposes
+ *
+ * @access protected
+ * @return void
+ */
+ protected function showConfig() {
+ // Get config
+ $config = $this->ci->config;
+
+ // Display database info
+ $this->io->section("Database config");
+ $this->io->writeln([
+ "DRIVER : " . $config['db.default.driver'],
+ "HOST : " . $config['db.default.host'],
+ "PORT : " . $config['db.default.port'],
+ "DATABASE : " . $config['db.default.database'],
+ "USERNAME : " . $config['db.default.username'],
+ "PASSWORD : " . ($config['db.default.password'] ? "*********" : "")
+ ]);
+ }
+}
diff --git a/main/app/system/Bakery/Command/Migrate.php b/main/app/system/Bakery/Command/Migrate.php
index e398628..aad2521 100644
--- a/main/app/system/Bakery/Command/Migrate.php
+++ b/main/app/system/Bakery/Command/Migrate.php
@@ -1,47 +1,47 @@
-<?php
-/**
- * UserFrosting (http://www.userfrosting.com)
- *
- * @link https://github.com/userfrosting/UserFrosting
- * @license https://github.com/userfrosting/UserFrosting/blob/master/licenses/UserFrosting.md (MIT License)
- */
-
-namespace UserFrosting\System\Bakery\Command;
-
-use Symfony\Component\Console\Input\InputInterface;
-use Symfony\Component\Console\Output\OutputInterface;
-use Symfony\Component\Console\Input\InputArgument;
-use Symfony\Component\Console\Input\InputOption;
-use UserFrosting\System\Bakery\BaseCommand;
-use UserFrosting\System\Bakery\Migrator;
-
-/**
- * Migrate CLI Tools.
- * Perform database migrations commands
- *
- * @author Alex Weissman (https://alexanderweissman.com)
- */
-class Migrate extends BaseCommand
-{
- /**
- * {@inheritDoc}
- */
- protected function configure() {
- $this->setName("migrate")
- ->setDescription("Perform database migration")
- ->setHelp("This command runs all the pending database migrations.")
- ->addOption('pretend', 'p', InputOption::VALUE_NONE, 'Run migrations in "dry run" mode');
- }
-
- /**
- * {@inheritDoc}
- */
- protected function execute(InputInterface $input, OutputInterface $output) {
- $this->io->title("UserFrosting's Migrator");
-
- $pretend = $input->getOption('pretend');
-
- $migrator = new Migrator($this->io, $this->ci);
- $migrator->runUp($pretend);
- }
+<?php
+/**
+ * UserFrosting (http://www.userfrosting.com)
+ *
+ * @link https://github.com/userfrosting/UserFrosting
+ * @license https://github.com/userfrosting/UserFrosting/blob/master/licenses/UserFrosting.md (MIT License)
+ */
+
+namespace UserFrosting\System\Bakery\Command;
+
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+use UserFrosting\System\Bakery\BaseCommand;
+use UserFrosting\System\Bakery\Migrator;
+
+/**
+ * Migrate CLI Tools.
+ * Perform database migrations commands
+ *
+ * @author Alex Weissman (https://alexanderweissman.com)
+ */
+class Migrate extends BaseCommand
+{
+ /**
+ * {@inheritDoc}
+ */
+ protected function configure() {
+ $this->setName("migrate")
+ ->setDescription("Perform database migration")
+ ->setHelp("This command runs all the pending database migrations.")
+ ->addOption('pretend', 'p', InputOption::VALUE_NONE, 'Run migrations in "dry run" mode');
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function execute(InputInterface $input, OutputInterface $output) {
+ $this->io->title("UserFrosting's Migrator");
+
+ $pretend = $input->getOption('pretend');
+
+ $migrator = new Migrator($this->io, $this->ci);
+ $migrator->runUp($pretend);
+ }
} \ No newline at end of file
diff --git a/main/app/system/Bakery/Command/MigrateRefresh.php b/main/app/system/Bakery/Command/MigrateRefresh.php
index eb05b61..4c464d0 100644
--- a/main/app/system/Bakery/Command/MigrateRefresh.php
+++ b/main/app/system/Bakery/Command/MigrateRefresh.php
@@ -1,51 +1,51 @@
-<?php
-/**
- * UserFrosting (http://www.userfrosting.com)
- *
- * @link https://github.com/userfrosting/UserFrosting
- * @license https://github.com/userfrosting/UserFrosting/blob/master/licenses/UserFrosting.md (MIT License)
- */
-
-namespace UserFrosting\System\Bakery\Command;
-
-use Symfony\Component\Console\Input\InputInterface;
-use Symfony\Component\Console\Output\OutputInterface;
-use Symfony\Component\Console\Input\InputArgument;
-use Symfony\Component\Console\Input\InputOption;
-use UserFrosting\System\Bakery\BaseCommand;
-use UserFrosting\System\Bakery\Migrator;
-
-/**
- * Migrate CLI Tools.
- * Perform database migrations commands
- *
- * @author Alex Weissman (https://alexanderweissman.com)
- */
-class MigrateRefresh extends BaseCommand
-{
- /**
- * {@inheritDoc}
- */
- protected function configure() {
- $this->setName("migrate:refresh")
- ->setDescription("Rollback the last migration operation and run it up again")
- ->addOption('steps', 's', InputOption::VALUE_REQUIRED, 'Number of steps to rollback', 1)
- ->addOption('sprinkle', NULL, InputOption::VALUE_REQUIRED, 'The sprinkle to rollback', "")
- ->addOption('pretend', 'p', InputOption::VALUE_NONE, 'Run migrations in "dry run" mode');
- }
-
- /**
- * {@inheritDoc}
- */
- protected function execute(InputInterface $input, OutputInterface $output) {
- $this->io->title("Migration refresh");
-
- $step = $input->getOption('steps');
- $sprinkle = $input->getOption('sprinkle');
- $pretend = $input->getOption('pretend');
-
- $migrator = new Migrator($this->io, $this->ci);
- $migrator->runDown($step, $sprinkle, $pretend);
- $migrator->runUp($pretend);
- }
+<?php
+/**
+ * UserFrosting (http://www.userfrosting.com)
+ *
+ * @link https://github.com/userfrosting/UserFrosting
+ * @license https://github.com/userfrosting/UserFrosting/blob/master/licenses/UserFrosting.md (MIT License)
+ */
+
+namespace UserFrosting\System\Bakery\Command;
+
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+use UserFrosting\System\Bakery\BaseCommand;
+use UserFrosting\System\Bakery\Migrator;
+
+/**
+ * Migrate CLI Tools.
+ * Perform database migrations commands
+ *
+ * @author Alex Weissman (https://alexanderweissman.com)
+ */
+class MigrateRefresh extends BaseCommand
+{
+ /**
+ * {@inheritDoc}
+ */
+ protected function configure() {
+ $this->setName("migrate:refresh")
+ ->setDescription("Rollback the last migration operation and run it up again")
+ ->addOption('steps', 's', InputOption::VALUE_REQUIRED, 'Number of steps to rollback', 1)
+ ->addOption('sprinkle', NULL, InputOption::VALUE_REQUIRED, 'The sprinkle to rollback', "")
+ ->addOption('pretend', 'p', InputOption::VALUE_NONE, 'Run migrations in "dry run" mode');
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function execute(InputInterface $input, OutputInterface $output) {
+ $this->io->title("Migration refresh");
+
+ $step = $input->getOption('steps');
+ $sprinkle = $input->getOption('sprinkle');
+ $pretend = $input->getOption('pretend');
+
+ $migrator = new Migrator($this->io, $this->ci);
+ $migrator->runDown($step, $sprinkle, $pretend);
+ $migrator->runUp($pretend);
+ }
} \ No newline at end of file
diff --git a/main/app/system/Bakery/Command/MigrateReset.php b/main/app/system/Bakery/Command/MigrateReset.php
index ad66a6c..ceaf5ea 100644
--- a/main/app/system/Bakery/Command/MigrateReset.php
+++ b/main/app/system/Bakery/Command/MigrateReset.php
@@ -1,48 +1,48 @@
-<?php
-/**
- * UserFrosting (http://www.userfrosting.com)
- *
- * @link https://github.com/userfrosting/UserFrosting
- * @license https://github.com/userfrosting/UserFrosting/blob/master/licenses/UserFrosting.md (MIT License)
- */
-
-namespace UserFrosting\System\Bakery\Command;
-
-use Symfony\Component\Console\Input\InputInterface;
-use Symfony\Component\Console\Output\OutputInterface;
-use Symfony\Component\Console\Input\InputArgument;
-use Symfony\Component\Console\Input\InputOption;
-use UserFrosting\System\Bakery\BaseCommand;
-use UserFrosting\System\Bakery\Migrator;
-
-/**
- * Migrate CLI Tools.
- * Perform database migrations commands
- *
- * @author Alex Weissman (https://alexanderweissman.com)
- */
-class MigrateReset extends BaseCommand
-{
- /**
- * {@inheritDoc}
- */
- protected function configure() {
- $this->setName("migrate:reset")
- ->setDescription("Reset the whole database to an empty state")
- ->addOption('sprinkle', NULL, InputOption::VALUE_REQUIRED, 'The sprinkle to rollback', "")
- ->addOption('pretend', 'p', InputOption::VALUE_NONE, 'Run migrations in "dry run" mode');
- }
-
- /**
- * {@inheritDoc}
- */
- protected function execute(InputInterface $input, OutputInterface $output) {
- $this->io->title("Migration reset");
-
- $sprinkle = $input->getOption('sprinkle');
- $pretend = $input->getOption('pretend');
-
- $migrator = new Migrator($this->io, $this->ci);
- $migrator->runDown(-1, $sprinkle, $pretend);
- }
+<?php
+/**
+ * UserFrosting (http://www.userfrosting.com)
+ *
+ * @link https://github.com/userfrosting/UserFrosting
+ * @license https://github.com/userfrosting/UserFrosting/blob/master/licenses/UserFrosting.md (MIT License)
+ */
+
+namespace UserFrosting\System\Bakery\Command;
+
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+use UserFrosting\System\Bakery\BaseCommand;
+use UserFrosting\System\Bakery\Migrator;
+
+/**
+ * Migrate CLI Tools.
+ * Perform database migrations commands
+ *
+ * @author Alex Weissman (https://alexanderweissman.com)
+ */
+class MigrateReset extends BaseCommand
+{
+ /**
+ * {@inheritDoc}
+ */
+ protected function configure() {
+ $this->setName("migrate:reset")
+ ->setDescription("Reset the whole database to an empty state")
+ ->addOption('sprinkle', NULL, InputOption::VALUE_REQUIRED, 'The sprinkle to rollback', "")
+ ->addOption('pretend', 'p', InputOption::VALUE_NONE, 'Run migrations in "dry run" mode');
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function execute(InputInterface $input, OutputInterface $output) {
+ $this->io->title("Migration reset");
+
+ $sprinkle = $input->getOption('sprinkle');
+ $pretend = $input->getOption('pretend');
+
+ $migrator = new Migrator($this->io, $this->ci);
+ $migrator->runDown(-1, $sprinkle, $pretend);
+ }
} \ No newline at end of file
diff --git a/main/app/system/Bakery/Command/MigrateRollback.php b/main/app/system/Bakery/Command/MigrateRollback.php
index ca2302a..bbc37bb 100644
--- a/main/app/system/Bakery/Command/MigrateRollback.php
+++ b/main/app/system/Bakery/Command/MigrateRollback.php
@@ -1,50 +1,50 @@
-<?php
-/**
- * UserFrosting (http://www.userfrosting.com)
- *
- * @link https://github.com/userfrosting/UserFrosting
- * @license https://github.com/userfrosting/UserFrosting/blob/master/licenses/UserFrosting.md (MIT License)
- */
-
-namespace UserFrosting\System\Bakery\Command;
-
-use Symfony\Component\Console\Input\InputInterface;
-use Symfony\Component\Console\Output\OutputInterface;
-use Symfony\Component\Console\Input\InputArgument;
-use Symfony\Component\Console\Input\InputOption;
-use UserFrosting\System\Bakery\BaseCommand;
-use UserFrosting\System\Bakery\Migrator;
-
-/**
- * Migrate CLI Tools.
- * Perform database migrations commands
- *
- * @author Alex Weissman (https://alexanderweissman.com)
- */
-class MigrateRollback extends BaseCommand
-{
- /**
- * {@inheritDoc}
- */
- protected function configure() {
- $this->setName("migrate:rollback")
- ->setDescription("Rollback last database migration")
- ->addOption('steps', 's', InputOption::VALUE_REQUIRED, 'Number of steps to rollback', 1)
- ->addOption('sprinkle', NULL, InputOption::VALUE_REQUIRED, 'The sprinkle to rollback', "")
- ->addOption('pretend', 'p', InputOption::VALUE_NONE, 'Run migrations in "dry run" mode');
- }
-
- /**
- * {@inheritDoc}
- */
- protected function execute(InputInterface $input, OutputInterface $output) {
- $this->io->title("Migration rollback");
-
- $step = $input->getOption('steps');
- $sprinkle = $input->getOption('sprinkle');
- $pretend = $input->getOption('pretend');
-
- $migrator = new Migrator($this->io, $this->ci);
- $migrator->runDown($step, $sprinkle, $pretend);
- }
+<?php
+/**
+ * UserFrosting (http://www.userfrosting.com)
+ *
+ * @link https://github.com/userfrosting/UserFrosting
+ * @license https://github.com/userfrosting/UserFrosting/blob/master/licenses/UserFrosting.md (MIT License)
+ */
+
+namespace UserFrosting\System\Bakery\Command;
+
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+use UserFrosting\System\Bakery\BaseCommand;
+use UserFrosting\System\Bakery\Migrator;
+
+/**
+ * Migrate CLI Tools.
+ * Perform database migrations commands
+ *
+ * @author Alex Weissman (https://alexanderweissman.com)
+ */
+class MigrateRollback extends BaseCommand
+{
+ /**
+ * {@inheritDoc}
+ */
+ protected function configure() {
+ $this->setName("migrate:rollback")
+ ->setDescription("Rollback last database migration")
+ ->addOption('steps', 's', InputOption::VALUE_REQUIRED, 'Number of steps to rollback', 1)
+ ->addOption('sprinkle', NULL, InputOption::VALUE_REQUIRED, 'The sprinkle to rollback', "")
+ ->addOption('pretend', 'p', InputOption::VALUE_NONE, 'Run migrations in "dry run" mode');
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function execute(InputInterface $input, OutputInterface $output) {
+ $this->io->title("Migration rollback");
+
+ $step = $input->getOption('steps');
+ $sprinkle = $input->getOption('sprinkle');
+ $pretend = $input->getOption('pretend');
+
+ $migrator = new Migrator($this->io, $this->ci);
+ $migrator->runDown($step, $sprinkle, $pretend);
+ }
} \ No newline at end of file
diff --git a/main/app/system/Bakery/Command/Setup.php b/main/app/system/Bakery/Command/Setup.php
index afea37b..f3f07c8 100644
--- a/main/app/system/Bakery/Command/Setup.php
+++ b/main/app/system/Bakery/Command/Setup.php
@@ -1,220 +1,220 @@
-<?php
-/**
- * UserFrosting (http://www.userfrosting.com)
- *
- * @link https://github.com/userfrosting/UserFrosting
- * @license https://github.com/userfrosting/UserFrosting/blob/master/licenses/UserFrosting.md (MIT License)
- */
-
-namespace UserFrosting\System\Bakery\Command;
-
-use Illuminate\Database\Capsule\Manager as Capsule;
-use Symfony\Component\Console\Input\InputInterface;
-use Symfony\Component\Console\Output\OutputInterface;
-use Symfony\Component\Console\Input\InputArgument;
-use Symfony\Component\Console\Input\InputOption;
-use UserFrosting\System\Bakery\BaseCommand;
-
-/**
- * Setup wizard CLI Tools.
- * Helper command to setup .env file
- *
- * @author Alex Weissman (https://alexanderweissman.com)
- */
-class Setup extends BaseCommand
-{
- /**
- * envfile path
- */
- protected $envPath = \UserFrosting\APP_DIR . '/.env';
-
- /**
- * {@inheritDoc}
- */
- protected function configure() {
- $this->setName("setup")
- ->setDescription("UserFrosting configuration wizard")
- ->setHelp("Helper command to setup the database and email configuration. This can also be done manually by editing the <comment>app/.env</comment> file or using global server environment variables.")
- ->addOption("force", "f", InputOption::VALUE_NONE, "If `.env` file exist, force setup to run again");
- }
-
- /**
- * {@inheritDoc}
- */
- protected function execute(InputInterface $input, OutputInterface $output) {
- // Get config
- $config = $this->ci->config;
-
- // Get options
- $force = $input->getOption('force');
-
- // Display header,
- $this->io->title("UserFrosting's Setup Wizard");
-
- // Check if the .env file exist.
- if (!$force && file_exists($this->envPath)) {
- $this->io->note("File `{$this->envPath}` already exist. Use the `php bakery setup -f` command to force setup to run again.");
- return;
- }
-
- // There might not be any `.env` file because there may be some custom config or global env values defined on the server.
- // We'll check for that. If the configs are empty, we'll assume nothing is defined and go strait to setup.
- if (!$force && $config["db.default.host"] != "" && $config["db.default.database"] != "" && $config["db.default.username"] != "") {
- $this->io->note("File `{$this->envPath}` was not found, but some database configuration variables are present. Global system environment variables might be defined. If this is not right, use -f option to force setup to run.");
- return;
- }
-
- //Goto setup
- $this->setupEnv();
- }
-
- /**
- * Setup the `.env` file.
- *
- * @access public
- * @return void
- */
- public function setupEnv() {
- // Get config
- $config = $this->ci->config;
-
- // Get the db driver choices
- $drivers = $this->databaseDrivers();
-
-
- // Ask the questions
- $this->io->section("Setting up database");
- $this->io->note("Database credentials will be saved in `app/.env`");
-
- $driver = $this->io->choice("Database type", $drivers->pluck('name')->toArray());
- $driver = $drivers->where('name', $driver)->first();
-
- $driverName = $driver['driver'];
- $defaultDBName = $driver['defaultDBName'];
-
- if ($driverName == 'sqlite') {
- $name = $this->io->ask("Database name", $defaultDBName);
-
- $dbParams = [
- 'driver' => $driverName,
- 'database' => $name
- ];
- } else {
- $defaultPort = $driver['defaultPort'];
-
- $host = $this->io->ask("Hostname", "localhost");
- $port = $this->io->ask("Port", $defaultPort);
- $name = $this->io->ask("Database name", $defaultDBName);
- $user = $this->io->ask("Username", "userfrosting");
- $password = $this->io->askHidden("Password", function ($password) {
- // Use custom validator to accept empty password
- return $password;
- });
-
- $dbParams = [
- 'driver' => $driverName,
- 'host' => $host,
- 'port' => $port,
- 'database' => $name,
- 'username' => $user,
- 'password' => $password,
- 'charset' => $config['db.default.charset']
- ];
- }
-
- // Setup a new db connection
- $capsule = new Capsule;
- $capsule->addConnection($dbParams);
-
- // Test the db connexion.
- try {
- $conn = $capsule->getConnection();
- $conn->getPdo();
- $this->io->success("Database connection successful");
- $success = TRUE;
- } catch (\PDOException $e) {
- $message = "Could not connect to the database '{$dbParams['username']}@{$dbParams['host']}/{$dbParams['database']}':" . PHP_EOL;
- $message .= "Exception: " . $e->getMessage() . PHP_EOL . PHP_EOL;
- $message .= "Please check your database configuration and/or google the exception shown above and run the command again.";
- $this->io->error($message);
- exit(1);
- }
-
- // Ask for the smtp values now
- $this->io->section("Enter your SMTP credentials");
- $this->io->write("This is used to send emails from the system. Edit `app/.env` if you have problems with this later.");
- $smtpHost = $this->io->ask("SMTP Host", "host.example.com");
- $smtpUser = $this->io->ask("SMTP User", "relay@example.com");
- $smtpPassword = $this->io->askHidden("SMTP Password", function ($password) {
- // Use custom validator to accept empty password
- return $password;
- });
-
- if ($driverName == 'sqlite') {
- $fileContent = [
- "UF_MODE=\"\"\n",
- "DB_DRIVER=\"{$dbParams['driver']}\"\n",
- "DB_NAME=\"{$dbParams['database']}\"\n",
- "SMTP_HOST=\"$smtpHost\"\n",
- "SMTP_USER=\"$smtpUser\"\n",
- "SMTP_PASSWORD=\"$smtpPassword\"\n"
- ];
- } else {
- $fileContent = [
- "UF_MODE=\"\"\n",
- "DB_DRIVER=\"{$dbParams['driver']}\"\n",
- "DB_HOST=\"{$dbParams['host']}\"\n",
- "DB_PORT=\"{$dbParams['port']}\"\n",
- "DB_NAME=\"{$dbParams['database']}\"\n",
- "DB_USER=\"{$dbParams['username']}\"\n",
- "DB_PASSWORD=\"{$dbParams['password']}\"\n",
- "SMTP_HOST=\"$smtpHost\"\n",
- "SMTP_USER=\"$smtpUser\"\n",
- "SMTP_PASSWORD=\"$smtpPassword\"\n"
- ];
- }
-
- // Let's save this config
- file_put_contents($this->envPath, $fileContent);
-
- // At this point, `$this->uf` is still using the old configs.
- // We need to refresh the `db.default` config values
- $newConfig = array_merge($config['db.default'], $dbParams);
- $this->ci->config->set("db.default", $newConfig);
- }
-
- /**
- * Return the database choices for the env setup.
- *
- * @access protected
- * @return void
- */
- protected function databaseDrivers() {
- return collect([
- [
- "driver" => "mysql",
- "name" => "MySQL / MariaDB",
- "defaultDBName" => "userfrosting",
- "defaultPort" => 3306
- ],
- [
- "driver" => "pgsql",
- "name" => "ProgreSQL",
- "defaultDBName" => "userfrosting",
- "defaultPort" => 5432
- ],
- [
- "driver" => "sqlsrv",
- "name" => "SQL Server",
- "defaultDBName" => "userfrosting",
- "defaultPort" => 1433
- ],
- [
- "driver" => "sqlite",
- "name" => "SQLite",
- "defaultDBName" => \UserFrosting\DB_DIR . \UserFrosting\DS . 'userfrosting.db',
- "defaultPort" => NULL
- ]
- ]);
- }
-}
+<?php
+/**
+ * UserFrosting (http://www.userfrosting.com)
+ *
+ * @link https://github.com/userfrosting/UserFrosting
+ * @license https://github.com/userfrosting/UserFrosting/blob/master/licenses/UserFrosting.md (MIT License)
+ */
+
+namespace UserFrosting\System\Bakery\Command;
+
+use Illuminate\Database\Capsule\Manager as Capsule;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+use UserFrosting\System\Bakery\BaseCommand;
+
+/**
+ * Setup wizard CLI Tools.
+ * Helper command to setup .env file
+ *
+ * @author Alex Weissman (https://alexanderweissman.com)
+ */
+class Setup extends BaseCommand
+{
+ /**
+ * envfile path
+ */
+ protected $envPath = \UserFrosting\APP_DIR . '/.env';
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function configure() {
+ $this->setName("setup")
+ ->setDescription("UserFrosting configuration wizard")
+ ->setHelp("Helper command to setup the database and email configuration. This can also be done manually by editing the <comment>app/.env</comment> file or using global server environment variables.")
+ ->addOption("force", "f", InputOption::VALUE_NONE, "If `.env` file exist, force setup to run again");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function execute(InputInterface $input, OutputInterface $output) {
+ // Get config
+ $config = $this->ci->config;
+
+ // Get options
+ $force = $input->getOption('force');
+
+ // Display header,
+ $this->io->title("UserFrosting's Setup Wizard");
+
+ // Check if the .env file exist.
+ if (!$force && file_exists($this->envPath)) {
+ $this->io->note("File `{$this->envPath}` already exist. Use the `php bakery setup -f` command to force setup to run again.");
+ return;
+ }
+
+ // There might not be any `.env` file because there may be some custom config or global env values defined on the server.
+ // We'll check for that. If the configs are empty, we'll assume nothing is defined and go strait to setup.
+ if (!$force && $config["db.default.host"] != "" && $config["db.default.database"] != "" && $config["db.default.username"] != "") {
+ $this->io->note("File `{$this->envPath}` was not found, but some database configuration variables are present. Global system environment variables might be defined. If this is not right, use -f option to force setup to run.");
+ return;
+ }
+
+ //Goto setup
+ $this->setupEnv();
+ }
+
+ /**
+ * Setup the `.env` file.
+ *
+ * @access public
+ * @return void
+ */
+ public function setupEnv() {
+ // Get config
+ $config = $this->ci->config;
+
+ // Get the db driver choices
+ $drivers = $this->databaseDrivers();
+
+
+ // Ask the questions
+ $this->io->section("Setting up database");
+ $this->io->note("Database credentials will be saved in `app/.env`");
+
+ $driver = $this->io->choice("Database type", $drivers->pluck('name')->toArray());
+ $driver = $drivers->where('name', $driver)->first();
+
+ $driverName = $driver['driver'];
+ $defaultDBName = $driver['defaultDBName'];
+
+ if ($driverName == 'sqlite') {
+ $name = $this->io->ask("Database name", $defaultDBName);
+
+ $dbParams = [
+ 'driver' => $driverName,
+ 'database' => $name
+ ];
+ } else {
+ $defaultPort = $driver['defaultPort'];
+
+ $host = $this->io->ask("Hostname", "localhost");
+ $port = $this->io->ask("Port", $defaultPort);
+ $name = $this->io->ask("Database name", $defaultDBName);
+ $user = $this->io->ask("Username", "userfrosting");
+ $password = $this->io->askHidden("Password", function ($password) {
+ // Use custom validator to accept empty password
+ return $password;
+ });
+
+ $dbParams = [
+ 'driver' => $driverName,
+ 'host' => $host,
+ 'port' => $port,
+ 'database' => $name,
+ 'username' => $user,
+ 'password' => $password,
+ 'charset' => $config['db.default.charset']
+ ];
+ }
+
+ // Setup a new db connection
+ $capsule = new Capsule;
+ $capsule->addConnection($dbParams);
+
+ // Test the db connexion.
+ try {
+ $conn = $capsule->getConnection();
+ $conn->getPdo();
+ $this->io->success("Database connection successful");
+ $success = TRUE;
+ } catch (\PDOException $e) {
+ $message = "Could not connect to the database '{$dbParams['username']}@{$dbParams['host']}/{$dbParams['database']}':" . PHP_EOL;
+ $message .= "Exception: " . $e->getMessage() . PHP_EOL . PHP_EOL;
+ $message .= "Please check your database configuration and/or google the exception shown above and run the command again.";
+ $this->io->error($message);
+ exit(1);
+ }
+
+ // Ask for the smtp values now
+ $this->io->section("Enter your SMTP credentials");
+ $this->io->write("This is used to send emails from the system. Edit `app/.env` if you have problems with this later.");
+ $smtpHost = $this->io->ask("SMTP Host", "host.example.com");
+ $smtpUser = $this->io->ask("SMTP User", "relay@example.com");
+ $smtpPassword = $this->io->askHidden("SMTP Password", function ($password) {
+ // Use custom validator to accept empty password
+ return $password;
+ });
+
+ if ($driverName == 'sqlite') {
+ $fileContent = [
+ "UF_MODE=\"\"\n",
+ "DB_DRIVER=\"{$dbParams['driver']}\"\n",
+ "DB_NAME=\"{$dbParams['database']}\"\n",
+ "SMTP_HOST=\"$smtpHost\"\n",
+ "SMTP_USER=\"$smtpUser\"\n",
+ "SMTP_PASSWORD=\"$smtpPassword\"\n"
+ ];
+ } else {
+ $fileContent = [
+ "UF_MODE=\"\"\n",
+ "DB_DRIVER=\"{$dbParams['driver']}\"\n",
+ "DB_HOST=\"{$dbParams['host']}\"\n",
+ "DB_PORT=\"{$dbParams['port']}\"\n",
+ "DB_NAME=\"{$dbParams['database']}\"\n",
+ "DB_USER=\"{$dbParams['username']}\"\n",
+ "DB_PASSWORD=\"{$dbParams['password']}\"\n",
+ "SMTP_HOST=\"$smtpHost\"\n",
+ "SMTP_USER=\"$smtpUser\"\n",
+ "SMTP_PASSWORD=\"$smtpPassword\"\n"
+ ];
+ }
+
+ // Let's save this config
+ file_put_contents($this->envPath, $fileContent);
+
+ // At this point, `$this->uf` is still using the old configs.
+ // We need to refresh the `db.default` config values
+ $newConfig = array_merge($config['db.default'], $dbParams);
+ $this->ci->config->set("db.default", $newConfig);
+ }
+
+ /**
+ * Return the database choices for the env setup.
+ *
+ * @access protected
+ * @return void
+ */
+ protected function databaseDrivers() {
+ return collect([
+ [
+ "driver" => "mysql",
+ "name" => "MySQL / MariaDB",
+ "defaultDBName" => "userfrosting",
+ "defaultPort" => 3306
+ ],
+ [
+ "driver" => "pgsql",
+ "name" => "ProgreSQL",
+ "defaultDBName" => "userfrosting",
+ "defaultPort" => 5432
+ ],
+ [
+ "driver" => "sqlsrv",
+ "name" => "SQL Server",
+ "defaultDBName" => "userfrosting",
+ "defaultPort" => 1433
+ ],
+ [
+ "driver" => "sqlite",
+ "name" => "SQLite",
+ "defaultDBName" => \UserFrosting\DB_DIR . \UserFrosting\DS . 'userfrosting.db',
+ "defaultPort" => NULL
+ ]
+ ]);
+ }
+}
diff --git a/main/app/system/Bakery/Command/Test.php b/main/app/system/Bakery/Command/Test.php
index dde187f..9f760b5 100644
--- a/main/app/system/Bakery/Command/Test.php
+++ b/main/app/system/Bakery/Command/Test.php
@@ -1,55 +1,55 @@
-<?php
-/**
- * UserFrosting (http://www.userfrosting.com)
- *
- * @link https://github.com/userfrosting/UserFrosting
- * @license https://github.com/userfrosting/UserFrosting/blob/master/licenses/UserFrosting.md (MIT License)
- */
-
-namespace UserFrosting\System\Bakery\Command;
-
-use Symfony\Component\Console\Input\InputInterface;
-use Symfony\Component\Console\Output\OutputInterface;
-use Symfony\Component\Console\Input\InputArgument;
-use Symfony\Component\Console\Input\InputOption;
-use UserFrosting\System\Bakery\BaseCommand;
-
-/**
- * Automated testing CLI tool.
- * Sets up environment and runs PHPUnit tests in each Sprinkle.
- *
- * @author Alex Weissman (https://alexanderweissman.com)
- */
-class Test extends BaseCommand
-{
- /**
- * @var string Path to the build/ directory
- */
- protected $buildPath;
-
- /**
- * {@inheritDoc}
- */
- protected function configure() {
- $this->setName("test")
- ->setDescription("Run tests")
- ->setHelp("Run php unit tests");
- }
-
- /**
- * {@inheritDoc}
- */
- protected function execute(InputInterface $input, OutputInterface $output) {
- $this->io->title("UserFrosting's Tester");
-
- // Get command
- $command = \UserFrosting\VENDOR_DIR . "/bin/phpunit --colors=always";
- if ($output->isVerbose() || $output->isVeryVerbose()) {
- $command .= " -v";
- }
-
- // Execute
- $this->io->writeln("> <comment>$command</comment>");
- passthru($command);
- }
+<?php
+/**
+ * UserFrosting (http://www.userfrosting.com)
+ *
+ * @link https://github.com/userfrosting/UserFrosting
+ * @license https://github.com/userfrosting/UserFrosting/blob/master/licenses/UserFrosting.md (MIT License)
+ */
+
+namespace UserFrosting\System\Bakery\Command;
+
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+use UserFrosting\System\Bakery\BaseCommand;
+
+/**
+ * Automated testing CLI tool.
+ * Sets up environment and runs PHPUnit tests in each Sprinkle.
+ *
+ * @author Alex Weissman (https://alexanderweissman.com)
+ */
+class Test extends BaseCommand
+{
+ /**
+ * @var string Path to the build/ directory
+ */
+ protected $buildPath;
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function configure() {
+ $this->setName("test")
+ ->setDescription("Run tests")
+ ->setHelp("Run php unit tests");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected function execute(InputInterface $input, OutputInterface $output) {
+ $this->io->title("UserFrosting's Tester");
+
+ // Get command
+ $command = \UserFrosting\VENDOR_DIR . "/bin/phpunit --colors=always";
+ if ($output->isVerbose() || $output->isVeryVerbose()) {
+ $command .= " -v";
+ }
+
+ // Execute
+ $this->io->writeln("> <comment>$command</comment>");
+ passthru($command);
+ }
} \ No newline at end of file
diff --git a/main/app/system/Bakery/DatabaseTest.php b/main/app/system/Bakery/DatabaseTest.php
index 91d2c2b..046c4c5 100644
--- a/main/app/system/Bakery/DatabaseTest.php
+++ b/main/app/system/Bakery/DatabaseTest.php
@@ -1,52 +1,52 @@
-<?php
-/**
- * UserFrosting (http://www.userfrosting.com)
- *
- * @link https://github.com/userfrosting/UserFrosting
- * @license https://github.com/userfrosting/UserFrosting/blob/master/licenses/UserFrosting.md (MIT License)
- */
-
-namespace UserFrosting\System\Bakery;
-
-use Illuminate\Database\Capsule\Manager as Capsule;
-
-/**
- * Database Test Trait. Include method to test the db connexion
- *
- * @author Alex Weissman (https://alexanderweissman.com)
- */
-trait DatabaseTest
-{
-
- /**
- * Function to test the db connexion.
- *
- * @access protected
- * @return bool True if success
- */
- protected function testDB() {
- // Boot db
- $this->ci->db;
-
- // Get config
- $config = $this->ci->config;
-
- // Check params are valids
- $dbParams = $config['db.default'];
- if (!$dbParams) {
- throw new \Exception("'default' database connection not found. Please double-check your configuration.");
- }
-
- // Test database connection directly using PDO
- try {
- Capsule::connection()->getPdo();
- } catch (\PDOException $e) {
- $message = "Could not connect to the database '{$dbParams['username']}@{$dbParams['host']}/{$dbParams['database']}':" . PHP_EOL;
- $message .= "Exception: " . $e->getMessage() . PHP_EOL . PHP_EOL;
- $message .= "Please check your database configuration and/or google the exception shown above and run command again.";
- throw new \Exception($message);
- }
-
- return TRUE;
- }
+<?php
+/**
+ * UserFrosting (http://www.userfrosting.com)
+ *
+ * @link https://github.com/userfrosting/UserFrosting
+ * @license https://github.com/userfrosting/UserFrosting/blob/master/licenses/UserFrosting.md (MIT License)
+ */
+
+namespace UserFrosting\System\Bakery;
+
+use Illuminate\Database\Capsule\Manager as Capsule;
+
+/**
+ * Database Test Trait. Include method to test the db connexion
+ *
+ * @author Alex Weissman (https://alexanderweissman.com)
+ */
+trait DatabaseTest
+{
+
+ /**
+ * Function to test the db connexion.
+ *
+ * @access protected
+ * @return bool True if success
+ */
+ protected function testDB() {
+ // Boot db
+ $this->ci->db;
+
+ // Get config
+ $config = $this->ci->config;
+
+ // Check params are valids
+ $dbParams = $config['db.default'];
+ if (!$dbParams) {
+ throw new \Exception("'default' database connection not found. Please double-check your configuration.");
+ }
+
+ // Test database connection directly using PDO
+ try {
+ Capsule::connection()->getPdo();
+ } catch (\PDOException $e) {
+ $message = "Could not connect to the database '{$dbParams['username']}@{$dbParams['host']}/{$dbParams['database']}':" . PHP_EOL;
+ $message .= "Exception: " . $e->getMessage() . PHP_EOL . PHP_EOL;
+ $message .= "Please check your database configuration and/or google the exception shown above and run command again.";
+ throw new \Exception($message);
+ }
+
+ return TRUE;
+ }
} \ No newline at end of file
diff --git a/main/app/system/Bakery/Migration.php b/main/app/system/Bakery/Migration.php
index 7c4ef62..c4255d9 100644
--- a/main/app/system/Bakery/Migration.php
+++ b/main/app/system/Bakery/Migration.php
@@ -1,67 +1,67 @@
-<?php
-/**
- * UserFrosting (http://www.userfrosting.com)
- *
- * @link https://github.com/userfrosting/UserFrosting
- * @license https://github.com/userfrosting/UserFrosting/blob/master/licenses/UserFrosting.md (MIT License)
- */
-
-namespace UserFrosting\System\Bakery;
-
-use Illuminate\Database\Schema\Builder;
-use Symfony\Component\Console\Style\SymfonyStyle;
-
-/**
- * Abstract Migration class.
- *
- * @abstract
- * @author Alex Weissman (https://alexanderweissman.com)
- */
-abstract class Migration
-{
- /**
- * @var Illuminate\Database\Schema\Builder $schema
- */
- protected $schema;
-
- /**
- * @var @Composer\IO\IOInterface
- */
- protected $io;
-
- /**
- * List of dependencies for this migration.
- * Should return an array of class required to be run before this migration
- */
- public $dependencies = [];
-
- /**
- * __construct function.
- *
- * @access public
- * @param Illuminate\Database\Schema\Builder $schema
- * @return void
- */
- public function __construct(Builder $schema, SymfonyStyle $io) {
- $this->schema = $schema;
- $this->io = $io;
- }
-
- /**
- * Method to apply changes to the database
- */
- public function up() {
- }
-
- /**
- * Method to revert changes applied by the `up` method
- */
- public function down() {
- }
-
- /**
- * Method to seed new information to the database
- */
- public function seed() {
- }
-}
+<?php
+/**
+ * UserFrosting (http://www.userfrosting.com)
+ *
+ * @link https://github.com/userfrosting/UserFrosting
+ * @license https://github.com/userfrosting/UserFrosting/blob/master/licenses/UserFrosting.md (MIT License)
+ */
+
+namespace UserFrosting\System\Bakery;
+
+use Illuminate\Database\Schema\Builder;
+use Symfony\Component\Console\Style\SymfonyStyle;
+
+/**
+ * Abstract Migration class.
+ *
+ * @abstract
+ * @author Alex Weissman (https://alexanderweissman.com)
+ */
+abstract class Migration
+{
+ /**
+ * @var Illuminate\Database\Schema\Builder $schema
+ */
+ protected $schema;
+
+ /**
+ * @var @Composer\IO\IOInterface
+ */
+ protected $io;
+
+ /**
+ * List of dependencies for this migration.
+ * Should return an array of class required to be run before this migration
+ */
+ public $dependencies = [];
+
+ /**
+ * __construct function.
+ *
+ * @access public
+ * @param Illuminate\Database\Schema\Builder $schema
+ * @return void
+ */
+ public function __construct(Builder $schema, SymfonyStyle $io) {
+ $this->schema = $schema;
+ $this->io = $io;
+ }
+
+ /**
+ * Method to apply changes to the database
+ */
+ public function up() {
+ }
+
+ /**
+ * Method to revert changes applied by the `up` method
+ */
+ public function down() {
+ }
+
+ /**
+ * Method to seed new information to the database
+ */
+ public function seed() {
+ }
+}
diff --git a/main/app/system/Bakery/Migrator.php b/main/app/system/Bakery/Migrator.php
index ff00b0b..568febd 100644
--- a/main/app/system/Bakery/Migrator.php
+++ b/main/app/system/Bakery/Migrator.php
@@ -1,570 +1,570 @@
-<?php
-/**
- * UserFrosting (http://www.userfrosting.com)
- *
- * @link https://github.com/userfrosting/UserFrosting
- * @license https://github.com/userfrosting/UserFrosting/blob/master/licenses/UserFrosting.md (MIT License)
- */
-
-namespace UserFrosting\System\Bakery;
-
-use Illuminate\Database\Capsule\Manager as Capsule;
-use Illuminate\Support\Str;
-use Interop\Container\ContainerInterface;
-use Symfony\Component\Console\Input\InputInterface;
-use Symfony\Component\Console\Input\InputArgument;
-use Symfony\Component\Console\Input\InputOption;
-use Symfony\Component\Console\Output\OutputInterface;
-use Symfony\Component\Console\Style\SymfonyStyle;
-use UserFrosting\Sprinkle\Core\Util\BadClassNameException;
-use UserFrosting\System\Database\Model\Migrations;
-use UserFrosting\System\Bakery\DatabaseTest;
-
-/**
- * Migrator class
- *
- * @author Alex Weissman (https://alexanderweissman.com)
- */
-class Migrator
-{
- use DatabaseTest;
-
- /**
- * @var @Symfony\Component\Console\Style\SymfonyStyle
- * See http://symfony.com/doc/current/console/style.html
- */
- protected $io;
-
- /**
- * @var ContainerInterface $ci The global container object, which holds all of UserFristing services.
- */
- protected $ci;
-
- /**
- * @var @Illuminate\Database\Schema
- */
- protected $schema;
-
- /**
- * @var String table The name of the migration table
- */
- protected $table = "migrations";
-
- /**
- * @var Array sprinkles The list of defined sprinkles
- */
- protected $sprinkles;
-
- /**
- * @var Int Current batch number. All the migration class run `up` in a single command will be grouped by this batch number
- */
- protected $batch;
-
- /**
- * @var Collection List of pending migration that require installation
- */
- protected $pending;
-
- /**
- * @var Collection List of installed migration. This is built from the log data in the database
- */
- protected $installed;
-
- /**
- * @var List of fulfillable migration (Migration that needs to be run and their dependencies are met)
- * This list is very important. While `pending` is a list of migrations that needs to be run, `fulfillable`
- * contain the order in which they are required to be run. When resolving the dependencies, this list will
- * automatically be sorted to make sure the dependencies are run in the correct order
- */
- protected $fulfillable;
-
- /**
- * @var List of unfulfillable migration (Migration that needs to be run and their dependencies are NOT met)
- * Note : An error could be thrown when an unfulfillable migration is met, but it makes much nicer cli error this way
- */
- protected $unfulfillable;
-
- /**
- * Constructor.
- *
- * @access public
- * @param SymfonyStyle $io
- * @param ContainerInterface $ci
- * @return void
- */
- public function __construct(SymfonyStyle $io, ContainerInterface $ci) {
- $this->io = $io;
- $this->ci = $ci;
-
- // Start by testing the DB connexion, just in case
- try {
- $this->io->writeln("<info>Testing database connection</info>", OutputInterface::VERBOSITY_VERBOSE);
- $this->testDB();
- $this->io->writeln("Ok", OutputInterface::VERBOSITY_VERBOSE);
- } catch (\Exception $e) {
- $this->io->error($e->getMessage());
- exit(1);
- }
-
- // Get schema required to run the table blueprints
- $this->schema = Capsule::schema();
-
- // Make sure the setup table exist
- $this->setupVersionTable();
- }
-
- /**
- * Run all the migrations available
- *
- * @access public
- * @param bool $pretend (default: false)
- * @return void
- */
- public function runUp($pretend = FALSE) {
- // Get installed migrations and pluck by class name. We only need this for now
- $migrations = Migrations::get();
- $this->installed = $migrations->pluck('migration');
-
- $this->io->writeln("\n<info>Installed migrations:</info>", OutputInterface::VERBOSITY_VERBOSE);
- $this->io->writeln($this->installed->toArray(), OutputInterface::VERBOSITY_VERBOSE);
-
- // Get pending migrations
- $this->io->section("Fetching available migrations");
- $this->pending = $this->getPendingMigrations();
-
- // If there's no pending migration, don't need to go further
- if ($this->pending->isEmpty()) {
- $this->io->success("Nothing to migrate !");
- return;
- }
-
- // Resolve the dependencies
- $this->resolveDependencies();
-
- // If there are any unfulfillable migration, we can't continue
- if (!$this->unfulfillable->isEmpty()) {
-
- $msg = "\nSome migrations dependencies can't be met. Check those migrations for unmet dependencies and try again:";
-
- foreach ($this->unfulfillable as $migration) {
- $msg .= "\n{$migration->className} depends on \n - ";
- $msg .= implode("\n - ", $migration->dependencies);
- $msg .= "\n";
- }
-
- $this->io->error($msg);
- exit(1);
- }
-
- // Ready to run !
- $this->io->section("Running migrations");
-
- if ($pretend) {
- $this->io->note("Running migration in pretend mode");
- }
-
- // We have a list of fulfillable migration, we run them up!
- foreach ($this->fulfillable as $migration) {
- $this->io->write("\n> <info>Migrating {$migration->className}...</info>");
-
- if ($pretend) {
- $this->io->newLine();
- $this->pretendToRun($migration, 'up');
- } else {
- $migration->up();
- $migration->seed();
- $this->log($migration);
- $this->io->writeln(" Done!");
- }
- }
-
- // If all went well and there's no fatal errors, we are ready to bake
- $this->io->success("Migration successful !");
- }
-
- /**
- * Rollback the last btach of migrations.
- *
- * @access public
- * @param int $step (default: 1). Number of batch we will be going back. -1 revert all migrations
- * @param string $sprinkle (default: "") Limit rollback to a specific sprinkle
- * @param bool $pretend (default: false)
- * @return void
- */
- public function runDown($step = 1, $sprinkle = "", $pretend = FALSE) {
- // Can't go furhter down than 1 step
- if ($step <= 0 && $step != -1) {
- throw new \InvalidArgumentException("Step can't be 0 or less");
- }
-
- // Get last batch number
- $batch = $this->getNextBatchNumber();
-
- // Calculate the number of steps back we need to take
- if ($step == -1) {
- $stepsBack = 1;
- $this->io->warning("Rolling back all migrations");
- } else {
- $stepsBack = max($batch - $step, 1);
- $this->io->note("Rolling back $step steps to batch $stepsBack", OutputInterface::VERBOSITY_VERBOSE);
- }
-
- // Get installed migrations
- $migrations = Migrations::orderBy("id", "desc")->where('batch', '>=', $stepsBack);
-
- // Add the sprinkle requirement too
- if ($sprinkle != "") {
- $this->io->note("Rolling back sprinkle `$sprinkle`", OutputInterface::VERBOSITY_VERBOSE);
- $migrations->where('sprinkle', $sprinkle);
- }
-
- // Run query
- $migrations = $migrations->get();
-
- // If there's nothing to rollback, stop here
- if ($migrations->isEmpty()) {
- $this->io->writeln("<info>Nothing to rollback</info>");
- exit(1);
- }
-
- // Get pending migrations
- $this->io->writeln("<info>Migration to rollback:</info>");
- $this->io->listing($migrations->pluck('migration')->toArray());
-
- // Ask confirmation to continue.
- if (!$pretend && !$this->io->confirm("Continue?", FALSE)) {
- exit(1);
- }
-
- if ($pretend) {
- $this->io->note("Rolling back in pretend mode");
- }
-
- // Loop again to run down each migration
- foreach ($migrations as $migration) {
-
- // Check if those migration class are available
- if (!class_exists($migration->migration)) {
- $this->io->warning("Migration class {$migration->migration} doesn't exist.");
- continue;
- }
-
- $this->io->write("> <info>Rolling back {$migration->migration}...</info>");
- $migrationClass = $migration->migration;
- $instance = new $migrationClass($this->schema, $this->io);
-
- if ($pretend) {
- $this->io->newLine();
- $this->pretendToRun($instance, 'down');
- } else {
- $instance->down();
- $migration->delete();
- $this->io->writeln(" Done!");
- }
-
- $this->io->newLine();
- }
-
- // If all went well and there's no fatal errors, we are ready to bake
- $this->io->success("Rollback successful !");
- }
-
- /**
- * Pretend to run migration class.
- *
- * @access protected
- * @param mixed $migration
- * @param string $method up/down
- */
- protected function pretendToRun($migration, $method) {
- foreach ($this->getQueries($migration, $method) as $query) {
- $this->io->writeln($query['query'], OutputInterface::VERBOSITY_VERBOSE);
- }
- }
-
- /**
- * Return all of the queries that would be run for a migration.
- *
- * @access protected
- * @param mixed $migration
- * @param string $method up/down
- * @return void
- */
- protected function getQueries($migration, $method) {
- $db = $this->schema->getConnection();
-
- return $db->pretend(function () use ($migration, $method) {
- if (method_exists($migration, $method)) {
- $migration->{$method}();
- }
- });
- }
-
- /**
- * Get pending migrations by looking at all the migration files
- * and finding the one not yet runed by compairing with the ran migrations
- *
- * @access protected
- * @return void
- */
- protected function getPendingMigrations() {
- $pending = collect([]);
-
- // Get the sprinkle list
- $sprinkles = $this->ci->sprinkleManager->getSprinkleNames();
-
- // Loop all the sprinkles to find their pending migrations
- foreach ($sprinkles as $sprinkle) {
-
- $this->io->writeln("> Fetching from `$sprinkle`");
-
- // We get all the migrations. This will return them as a colleciton of class names
- $migrations = $this->getMigrations($sprinkle);
-
- // We filter the available migration by removing the one that have already been run
- // This reject the class name found in the installed collection
- $migrations = $migrations->reject(function ($value, $key) {
- return $this->installed->contains($value);
- });
-
- // Load each class
- foreach ($migrations as $migrationClass) {
-
- // Make sure the class exist
- if (!class_exists($migrationClass)) {
- throw new BadClassNameException("Unable to find the migration class '$migrationClass'.");
- }
-
- // Load the migration class
- $migration = new $migrationClass($this->schema, $this->io);
-
- //Set the sprinkle
- $migration->sprinkle = $sprinkle;
-
- // Also set the class name. We could find it using ::class, but this
- // will make it easier to manipulate the collection
- $migration->className = $migrationClass;
-
- // Add it to the pending list
- $pending->push($migration);
- }
- }
-
- // Get pending migrations
- $pendingArray = ($pending->pluck('className')->toArray()) ?: "";
- $this->io->writeln("\n<info>Pending migrations:</info>", OutputInterface::VERBOSITY_VERBOSE);
- $this->io->writeln($pendingArray, OutputInterface::VERBOSITY_VERBOSE);
-
- return $pending;
- }
-
- /**
- * Get the list of migrations avaiables in the filesystem.
- * Return a list of resolved className
- *
- * @access public
- * @param string $sprinkleName
- * @return void
- */
- public function getMigrations($sprinkle) {
- // Find all the migration files
- $path = $this->migrationDirectoryPath($sprinkle);
- $files = glob($path . "*/*.php");
-
- // Transform the array in a collection
- $migrations = collect($files);
-
- // We transform the path into a migration object
- $migrations->transform(function ($file) use ($sprinkle, $path) {
- // Deconstruct the path
- $migration = str_replace($path, "", $file);
- $className = basename($file, '.php');
- $sprinkleName = Str::studly($sprinkle);
- $version = str_replace("/$className.php", "", $migration);
-
- // Reconstruct the classname
- $className = "\\UserFrosting\\Sprinkle\\" . $sprinkleName . "\\Database\\Migrations\\" . $version . "\\" . $className;
-
- return $className;
- });
-
- return $migrations;
- }
-
- /**
- * Resolve all the dependencies for all the pending migrations
- * This function fills in the `fullfillable` and `unfulfillable` list
- *
- * @access protected
- * @return void
- */
- protected function resolveDependencies() {
- $this->io->writeln("\n<info>Resolving migrations dependencies...</info>", OutputInterface::VERBOSITY_VERBOSE);
-
- // Reset fulfillable/unfulfillable lists
- $this->fulfillable = collect([]);
- $this->unfulfillable = collect([]);
-
- // Loop pending and check for dependencies
- foreach ($this->pending as $migration) {
- $this->validateClassDependencies($migration);
- }
-
- $fulfillable = ($this->fulfillable->pluck('className')->toArray()) ?: "";
- $this->io->writeln("\n<info>Fulfillable migrations:</info>", OutputInterface::VERBOSITY_VERBOSE);
- $this->io->writeln($fulfillable, OutputInterface::VERBOSITY_VERBOSE);
-
- $unfulfillable = ($this->unfulfillable->pluck('className')->toArray()) ?: "";
- $this->io->writeln("\n<info>Unfulfillable migrations:</info>", OutputInterface::VERBOSITY_VERBOSE);
- $this->io->writeln($unfulfillable, OutputInterface::VERBOSITY_VERBOSE);
- }
-
- /**
- * Check if a migration dependencies are met.
- * To test if a migration is fulfillable, the class must :
- * Already been installed OR exist and have all it's dependencies met
- *
- * @access protected
- * @param $migration
- * @return bool true/false if all conditions are met
- */
- protected function validateClassDependencies($migration) {
- $this->io->writeln("> Checking dependencies for {$migration->className}", OutputInterface::VERBOSITY_VERBOSE);
-
- // If it's already marked as fulfillable, it's fulfillable
- // Return true directly (it's already marked)
- if ($this->fulfillable->contains($migration)) {
- return TRUE;
- }
-
- // If it's already marked as unfulfillable, it's unfulfillable
- // Return false directly (it's already marked)
- if ($this->unfulfillable->contains($migration)) {
- return FALSE;
- }
-
- // If it's already run, it's fulfillable
- // Mark it as such for next time it comes up in this loop
- if ($this->installed->contains($migration->className)) {
- return $this->markAsFulfillable($migration);
- }
-
- // Loop dependencies. If one is not fulfillable, then this one is not either
- foreach ($migration->dependencies as $dependencyClass) {
-
- // The dependency might already be installed. Check that first
- if ($this->installed->contains($dependencyClass)) {
- continue;
- }
-
- // Try to find it in the `pending` list. Cant' find it? Then it's not fulfillable
- $dependency = $this->pending->where('className', $dependencyClass)->first();
-
- // Check migration dependencies of this one right now
- // If ti's not fullfillable, then this one isn't either
- if (!$dependency || !$this->validateClassDependencies($dependency)) {
- return $this->markAsUnfulfillable($migration);
- }
- }
-
- // If no dependencies returned false, it's fulfillable
- return $this->markAsFulfillable($migration);
- }
-
- /**
- * Mark a dependency as fulfillable.
- * Removes it from the pending list and add it to the fulfillable list
- *
- * @access protected
- * @param $migration
- * @return true
- */
- protected function markAsFulfillable($migration) {
- $this->fulfillable->push($migration);
- return TRUE;
- }
-
- /**
- * Mark a dependency as unfulfillable.
- * Removes it from the pending list and add it to the unfulfillable list
- *
- * @access protected
- * @param $migration
- * @return false
- */
- protected function markAsUnfulfillable($migration) {
- $this->unfulfillable->push($migration);
- return FALSE;
- }
-
- /**
- * Log that a migration was run.
- *
- * @access public
- * @param mixed $migration
- * @return void
- */
- protected function log($migration) {
- // Get the next batch number if not defined
- if (!$this->batch) {
- $this->batch = $this->getNextBatchNumber();
- }
-
- $log = new Migrations([
- 'sprinkle' => $migration->sprinkle,
- 'migration' => $migration->className,
- 'batch' => $this->batch
- ]);
- $log->save();
- }
-
- /**
- * Return the next batch number from the db.
- * Batch number is used to group together migration run in the same operation
- *
- * @access public
- * @return int the next batch number
- */
- public function getNextBatchNumber() {
- $batch = Migrations::max('batch');
- return ($batch) ? $batch + 1 : 1;
- }
-
- /**
- * Create the migration history table if needed.
- * Also check if the tables requires migrations
- * We run the migration file manually for this one
- *
- * @access public
- * @return void
- */
- protected function setupVersionTable() {
- // Check if the `migrations` table exist. Create it manually otherwise
- if (!$this->schema->hasColumn($this->table, 'id')) {
- $this->io->section("Creating the `{$this->table}` table");
-
- $migration = new \UserFrosting\System\Database\Migrations\v410\MigrationTable($this->schema, $this->io);
- $migration->up();
-
- $this->io->success("Table `{$this->table}` created");
- }
- }
-
- /**
- * Returns the path of the Migration directory.
- *
- * @access protected
- * @param mixed $sprinkleName
- * @return void
- */
- protected function migrationDirectoryPath($sprinkleName) {
- $path = \UserFrosting\SPRINKLES_DIR .
- \UserFrosting\DS .
- $sprinkleName .
- \UserFrosting\DS .
- \UserFrosting\SRC_DIR_NAME .
- "/Database/Migrations/";
-
- return $path;
- }
-}
+<?php
+/**
+ * UserFrosting (http://www.userfrosting.com)
+ *
+ * @link https://github.com/userfrosting/UserFrosting
+ * @license https://github.com/userfrosting/UserFrosting/blob/master/licenses/UserFrosting.md (MIT License)
+ */
+
+namespace UserFrosting\System\Bakery;
+
+use Illuminate\Database\Capsule\Manager as Capsule;
+use Illuminate\Support\Str;
+use Interop\Container\ContainerInterface;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
+use UserFrosting\Sprinkle\Core\Util\BadClassNameException;
+use UserFrosting\System\Database\Model\Migrations;
+use UserFrosting\System\Bakery\DatabaseTest;
+
+/**
+ * Migrator class
+ *
+ * @author Alex Weissman (https://alexanderweissman.com)
+ */
+class Migrator
+{
+ use DatabaseTest;
+
+ /**
+ * @var @Symfony\Component\Console\Style\SymfonyStyle
+ * See http://symfony.com/doc/current/console/style.html
+ */
+ protected $io;
+
+ /**
+ * @var ContainerInterface $ci The global container object, which holds all of UserFristing services.
+ */
+ protected $ci;
+
+ /**
+ * @var @Illuminate\Database\Schema
+ */
+ protected $schema;
+
+ /**
+ * @var String table The name of the migration table
+ */
+ protected $table = "migrations";
+
+ /**
+ * @var Array sprinkles The list of defined sprinkles
+ */
+ protected $sprinkles;
+
+ /**
+ * @var Int Current batch number. All the migration class run `up` in a single command will be grouped by this batch number
+ */
+ protected $batch;
+
+ /**
+ * @var Collection List of pending migration that require installation
+ */
+ protected $pending;
+
+ /**
+ * @var Collection List of installed migration. This is built from the log data in the database
+ */
+ protected $installed;
+
+ /**
+ * @var List of fulfillable migration (Migration that needs to be run and their dependencies are met)
+ * This list is very important. While `pending` is a list of migrations that needs to be run, `fulfillable`
+ * contain the order in which they are required to be run. When resolving the dependencies, this list will
+ * automatically be sorted to make sure the dependencies are run in the correct order
+ */
+ protected $fulfillable;
+
+ /**
+ * @var List of unfulfillable migration (Migration that needs to be run and their dependencies are NOT met)
+ * Note : An error could be thrown when an unfulfillable migration is met, but it makes much nicer cli error this way
+ */
+ protected $unfulfillable;
+
+ /**
+ * Constructor.
+ *
+ * @access public
+ * @param SymfonyStyle $io
+ * @param ContainerInterface $ci
+ * @return void
+ */
+ public function __construct(SymfonyStyle $io, ContainerInterface $ci) {
+ $this->io = $io;
+ $this->ci = $ci;
+
+ // Start by testing the DB connexion, just in case
+ try {
+ $this->io->writeln("<info>Testing database connection</info>", OutputInterface::VERBOSITY_VERBOSE);
+ $this->testDB();
+ $this->io->writeln("Ok", OutputInterface::VERBOSITY_VERBOSE);
+ } catch (\Exception $e) {
+ $this->io->error($e->getMessage());
+ exit(1);
+ }
+
+ // Get schema required to run the table blueprints
+ $this->schema = Capsule::schema();
+
+ // Make sure the setup table exist
+ $this->setupVersionTable();
+ }
+
+ /**
+ * Run all the migrations available
+ *
+ * @access public
+ * @param bool $pretend (default: false)
+ * @return void
+ */
+ public function runUp($pretend = FALSE) {
+ // Get installed migrations and pluck by class name. We only need this for now
+ $migrations = Migrations::get();
+ $this->installed = $migrations->pluck('migration');
+
+ $this->io->writeln("\n<info>Installed migrations:</info>", OutputInterface::VERBOSITY_VERBOSE);
+ $this->io->writeln($this->installed->toArray(), OutputInterface::VERBOSITY_VERBOSE);
+
+ // Get pending migrations
+ $this->io->section("Fetching available migrations");
+ $this->pending = $this->getPendingMigrations();
+
+ // If there's no pending migration, don't need to go further
+ if ($this->pending->isEmpty()) {
+ $this->io->success("Nothing to migrate !");
+ return;
+ }
+
+ // Resolve the dependencies
+ $this->resolveDependencies();
+
+ // If there are any unfulfillable migration, we can't continue
+ if (!$this->unfulfillable->isEmpty()) {
+
+ $msg = "\nSome migrations dependencies can't be met. Check those migrations for unmet dependencies and try again:";
+
+ foreach ($this->unfulfillable as $migration) {
+ $msg .= "\n{$migration->className} depends on \n - ";
+ $msg .= implode("\n - ", $migration->dependencies);
+ $msg .= "\n";
+ }
+
+ $this->io->error($msg);
+ exit(1);
+ }
+
+ // Ready to run !
+ $this->io->section("Running migrations");
+
+ if ($pretend) {
+ $this->io->note("Running migration in pretend mode");
+ }
+
+ // We have a list of fulfillable migration, we run them up!
+ foreach ($this->fulfillable as $migration) {
+ $this->io->write("\n> <info>Migrating {$migration->className}...</info>");
+
+ if ($pretend) {
+ $this->io->newLine();
+ $this->pretendToRun($migration, 'up');
+ } else {
+ $migration->up();
+ $migration->seed();
+ $this->log($migration);
+ $this->io->writeln(" Done!");
+ }
+ }
+
+ // If all went well and there's no fatal errors, we are ready to bake
+ $this->io->success("Migration successful !");
+ }
+
+ /**
+ * Rollback the last btach of migrations.
+ *
+ * @access public
+ * @param int $step (default: 1). Number of batch we will be going back. -1 revert all migrations
+ * @param string $sprinkle (default: "") Limit rollback to a specific sprinkle
+ * @param bool $pretend (default: false)
+ * @return void
+ */
+ public function runDown($step = 1, $sprinkle = "", $pretend = FALSE) {
+ // Can't go furhter down than 1 step
+ if ($step <= 0 && $step != -1) {
+ throw new \InvalidArgumentException("Step can't be 0 or less");
+ }
+
+ // Get last batch number
+ $batch = $this->getNextBatchNumber();
+
+ // Calculate the number of steps back we need to take
+ if ($step == -1) {
+ $stepsBack = 1;
+ $this->io->warning("Rolling back all migrations");
+ } else {
+ $stepsBack = max($batch - $step, 1);
+ $this->io->note("Rolling back $step steps to batch $stepsBack", OutputInterface::VERBOSITY_VERBOSE);
+ }
+
+ // Get installed migrations
+ $migrations = Migrations::orderBy("id", "desc")->where('batch', '>=', $stepsBack);
+
+ // Add the sprinkle requirement too
+ if ($sprinkle != "") {
+ $this->io->note("Rolling back sprinkle `$sprinkle`", OutputInterface::VERBOSITY_VERBOSE);
+ $migrations->where('sprinkle', $sprinkle);
+ }
+
+ // Run query
+ $migrations = $migrations->get();
+
+ // If there's nothing to rollback, stop here
+ if ($migrations->isEmpty()) {
+ $this->io->writeln("<info>Nothing to rollback</info>");
+ exit(1);
+ }
+
+ // Get pending migrations
+ $this->io->writeln("<info>Migration to rollback:</info>");
+ $this->io->listing($migrations->pluck('migration')->toArray());
+
+ // Ask confirmation to continue.
+ if (!$pretend && !$this->io->confirm("Continue?", FALSE)) {
+ exit(1);
+ }
+
+ if ($pretend) {
+ $this->io->note("Rolling back in pretend mode");
+ }
+
+ // Loop again to run down each migration
+ foreach ($migrations as $migration) {
+
+ // Check if those migration class are available
+ if (!class_exists($migration->migration)) {
+ $this->io->warning("Migration class {$migration->migration} doesn't exist.");
+ continue;
+ }
+
+ $this->io->write("> <info>Rolling back {$migration->migration}...</info>");
+ $migrationClass = $migration->migration;
+ $instance = new $migrationClass($this->schema, $this->io);
+
+ if ($pretend) {
+ $this->io->newLine();
+ $this->pretendToRun($instance, 'down');
+ } else {
+ $instance->down();
+ $migration->delete();
+ $this->io->writeln(" Done!");
+ }
+
+ $this->io->newLine();
+ }
+
+ // If all went well and there's no fatal errors, we are ready to bake
+ $this->io->success("Rollback successful !");
+ }
+
+ /**
+ * Pretend to run migration class.
+ *
+ * @access protected
+ * @param mixed $migration
+ * @param string $method up/down
+ */
+ protected function pretendToRun($migration, $method) {
+ foreach ($this->getQueries($migration, $method) as $query) {
+ $this->io->writeln($query['query'], OutputInterface::VERBOSITY_VERBOSE);
+ }
+ }
+
+ /**
+ * Return all of the queries that would be run for a migration.
+ *
+ * @access protected
+ * @param mixed $migration
+ * @param string $method up/down
+ * @return void
+ */
+ protected function getQueries($migration, $method) {
+ $db = $this->schema->getConnection();
+
+ return $db->pretend(function () use ($migration, $method) {
+ if (method_exists($migration, $method)) {
+ $migration->{$method}();
+ }
+ });
+ }
+
+ /**
+ * Get pending migrations by looking at all the migration files
+ * and finding the one not yet runed by compairing with the ran migrations
+ *
+ * @access protected
+ * @return void
+ */
+ protected function getPendingMigrations() {
+ $pending = collect([]);
+
+ // Get the sprinkle list
+ $sprinkles = $this->ci->sprinkleManager->getSprinkleNames();
+
+ // Loop all the sprinkles to find their pending migrations
+ foreach ($sprinkles as $sprinkle) {
+
+ $this->io->writeln("> Fetching from `$sprinkle`");
+
+ // We get all the migrations. This will return them as a colleciton of class names
+ $migrations = $this->getMigrations($sprinkle);
+
+ // We filter the available migration by removing the one that have already been run
+ // This reject the class name found in the installed collection
+ $migrations = $migrations->reject(function ($value, $key) {
+ return $this->installed->contains($value);
+ });
+
+ // Load each class
+ foreach ($migrations as $migrationClass) {
+
+ // Make sure the class exist
+ if (!class_exists($migrationClass)) {
+ throw new BadClassNameException("Unable to find the migration class '$migrationClass'.");
+ }
+
+ // Load the migration class
+ $migration = new $migrationClass($this->schema, $this->io);
+
+ //Set the sprinkle
+ $migration->sprinkle = $sprinkle;
+
+ // Also set the class name. We could find it using ::class, but this
+ // will make it easier to manipulate the collection
+ $migration->className = $migrationClass;
+
+ // Add it to the pending list
+ $pending->push($migration);
+ }
+ }
+
+ // Get pending migrations
+ $pendingArray = ($pending->pluck('className')->toArray()) ?: "";
+ $this->io->writeln("\n<info>Pending migrations:</info>", OutputInterface::VERBOSITY_VERBOSE);
+ $this->io->writeln($pendingArray, OutputInterface::VERBOSITY_VERBOSE);
+
+ return $pending;
+ }
+
+ /**
+ * Get the list of migrations avaiables in the filesystem.
+ * Return a list of resolved className
+ *
+ * @access public
+ * @param string $sprinkleName
+ * @return void
+ */
+ public function getMigrations($sprinkle) {
+ // Find all the migration files
+ $path = $this->migrationDirectoryPath($sprinkle);
+ $files = glob($path . "*/*.php");
+
+ // Transform the array in a collection
+ $migrations = collect($files);
+
+ // We transform the path into a migration object
+ $migrations->transform(function ($file) use ($sprinkle, $path) {
+ // Deconstruct the path
+ $migration = str_replace($path, "", $file);
+ $className = basename($file, '.php');
+ $sprinkleName = Str::studly($sprinkle);
+ $version = str_replace("/$className.php", "", $migration);
+
+ // Reconstruct the classname
+ $className = "\\UserFrosting\\Sprinkle\\" . $sprinkleName . "\\Database\\Migrations\\" . $version . "\\" . $className;
+
+ return $className;
+ });
+
+ return $migrations;
+ }
+
+ /**
+ * Resolve all the dependencies for all the pending migrations
+ * This function fills in the `fullfillable` and `unfulfillable` list
+ *
+ * @access protected
+ * @return void
+ */
+ protected function resolveDependencies() {
+ $this->io->writeln("\n<info>Resolving migrations dependencies...</info>", OutputInterface::VERBOSITY_VERBOSE);
+
+ // Reset fulfillable/unfulfillable lists
+ $this->fulfillable = collect([]);
+ $this->unfulfillable = collect([]);
+
+ // Loop pending and check for dependencies
+ foreach ($this->pending as $migration) {
+ $this->validateClassDependencies($migration);
+ }
+
+ $fulfillable = ($this->fulfillable->pluck('className')->toArray()) ?: "";
+ $this->io->writeln("\n<info>Fulfillable migrations:</info>", OutputInterface::VERBOSITY_VERBOSE);
+ $this->io->writeln($fulfillable, OutputInterface::VERBOSITY_VERBOSE);
+
+ $unfulfillable = ($this->unfulfillable->pluck('className')->toArray()) ?: "";
+ $this->io->writeln("\n<info>Unfulfillable migrations:</info>", OutputInterface::VERBOSITY_VERBOSE);
+ $this->io->writeln($unfulfillable, OutputInterface::VERBOSITY_VERBOSE);
+ }
+
+ /**
+ * Check if a migration dependencies are met.
+ * To test if a migration is fulfillable, the class must :
+ * Already been installed OR exist and have all it's dependencies met
+ *
+ * @access protected
+ * @param $migration
+ * @return bool true/false if all conditions are met
+ */
+ protected function validateClassDependencies($migration) {
+ $this->io->writeln("> Checking dependencies for {$migration->className}", OutputInterface::VERBOSITY_VERBOSE);
+
+ // If it's already marked as fulfillable, it's fulfillable
+ // Return true directly (it's already marked)
+ if ($this->fulfillable->contains($migration)) {
+ return TRUE;
+ }
+
+ // If it's already marked as unfulfillable, it's unfulfillable
+ // Return false directly (it's already marked)
+ if ($this->unfulfillable->contains($migration)) {
+ return FALSE;
+ }
+
+ // If it's already run, it's fulfillable
+ // Mark it as such for next time it comes up in this loop
+ if ($this->installed->contains($migration->className)) {
+ return $this->markAsFulfillable($migration);
+ }
+
+ // Loop dependencies. If one is not fulfillable, then this one is not either
+ foreach ($migration->dependencies as $dependencyClass) {
+
+ // The dependency might already be installed. Check that first
+ if ($this->installed->contains($dependencyClass)) {
+ continue;
+ }
+
+ // Try to find it in the `pending` list. Cant' find it? Then it's not fulfillable
+ $dependency = $this->pending->where('className', $dependencyClass)->first();
+
+ // Check migration dependencies of this one right now
+ // If ti's not fullfillable, then this one isn't either
+ if (!$dependency || !$this->validateClassDependencies($dependency)) {
+ return $this->markAsUnfulfillable($migration);
+ }
+ }
+
+ // If no dependencies returned false, it's fulfillable
+ return $this->markAsFulfillable($migration);
+ }
+
+ /**
+ * Mark a dependency as fulfillable.
+ * Removes it from the pending list and add it to the fulfillable list
+ *
+ * @access protected
+ * @param $migration
+ * @return true
+ */
+ protected function markAsFulfillable($migration) {
+ $this->fulfillable->push($migration);
+ return TRUE;
+ }
+
+ /**
+ * Mark a dependency as unfulfillable.
+ * Removes it from the pending list and add it to the unfulfillable list
+ *
+ * @access protected
+ * @param $migration
+ * @return false
+ */
+ protected function markAsUnfulfillable($migration) {
+ $this->unfulfillable->push($migration);
+ return FALSE;
+ }
+
+ /**
+ * Log that a migration was run.
+ *
+ * @access public
+ * @param mixed $migration
+ * @return void
+ */
+ protected function log($migration) {
+ // Get the next batch number if not defined
+ if (!$this->batch) {
+ $this->batch = $this->getNextBatchNumber();
+ }
+
+ $log = new Migrations([
+ 'sprinkle' => $migration->sprinkle,
+ 'migration' => $migration->className,
+ 'batch' => $this->batch
+ ]);
+ $log->save();
+ }
+
+ /**
+ * Return the next batch number from the db.
+ * Batch number is used to group together migration run in the same operation
+ *
+ * @access public
+ * @return int the next batch number
+ */
+ public function getNextBatchNumber() {
+ $batch = Migrations::max('batch');
+ return ($batch) ? $batch + 1 : 1;
+ }
+
+ /**
+ * Create the migration history table if needed.
+ * Also check if the tables requires migrations
+ * We run the migration file manually for this one
+ *
+ * @access public
+ * @return void
+ */
+ protected function setupVersionTable() {
+ // Check if the `migrations` table exist. Create it manually otherwise
+ if (!$this->schema->hasColumn($this->table, 'id')) {
+ $this->io->section("Creating the `{$this->table}` table");
+
+ $migration = new \UserFrosting\System\Database\Migrations\v410\MigrationTable($this->schema, $this->io);
+ $migration->up();
+
+ $this->io->success("Table `{$this->table}` created");
+ }
+ }
+
+ /**
+ * Returns the path of the Migration directory.
+ *
+ * @access protected
+ * @param mixed $sprinkleName
+ * @return void
+ */
+ protected function migrationDirectoryPath($sprinkleName) {
+ $path = \UserFrosting\SPRINKLES_DIR .
+ \UserFrosting\DS .
+ $sprinkleName .
+ \UserFrosting\DS .
+ \UserFrosting\SRC_DIR_NAME .
+ "/Database/Migrations/";
+
+ return $path;
+ }
+}