From b97cdd842d2ae9310272cb6d0d91c19d9dd09e5c Mon Sep 17 00:00:00 2001 From: alexweissman Date: Wed, 28 Mar 2018 18:26:56 -0400 Subject: [PATCH 01/10] bump version --- CHANGELOG.md | 4 +++- app/defines.php | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 44f7530d..8ee2cab1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,8 +5,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## v4.1.18 + ## v4.1.17-alpha -- Lock `gulp-uf-bundle-assets` at v2.28.0 until Silic0nS0ldier/gulp-uf-bundle-assets#5 is resolved (see #859) +- Lock `gulp-uf-bundle-assets` at v2.28.0 until userfrosting/gulp-uf-bundle-assets#5 is resolved (see #859) - Add missing getInfo methods for GroupController and RoleController (#837) ## v4.1.16-alpha diff --git a/app/defines.php b/app/defines.php index d1294240..03b8cae4 100755 --- a/app/defines.php +++ b/app/defines.php @@ -3,7 +3,7 @@ namespace UserFrosting; // Some standard defines -define('UserFrosting\VERSION', '4.1.17-alpha'); +define('UserFrosting\VERSION', '4.1.18'); define('UserFrosting\DS', '/'); define('UserFrosting\PHP_MIN_VERSION', '5.6'); define('UserFrosting\DEBUG_CONFIG', false); From c150bb98f8a07d3ec4f99f777226eb0e077a8600 Mon Sep 17 00:00:00 2001 From: Louis Charette Date: Fri, 11 May 2018 21:25:13 -0400 Subject: [PATCH 02/10] Bakery setup wizard for SMTP config + separate SMTP setup in it's own command (#874) --- CHANGELOG.md | 1 + app/system/Bakery/Command/Setup.php | 223 --------------- app/system/Bakery/Command/SetupCommand.php | 46 ++++ app/system/Bakery/Command/SetupDbCommand.php | 260 ++++++++++++++++++ app/system/Bakery/Command/SetupEnvCommand.php | 96 +++++++ .../Bakery/Command/SetupSmtpCommand.php | 209 ++++++++++++++ 6 files changed, 612 insertions(+), 223 deletions(-) delete mode 100644 app/system/Bakery/Command/Setup.php create mode 100644 app/system/Bakery/Command/SetupCommand.php create mode 100644 app/system/Bakery/Command/SetupDbCommand.php create mode 100644 app/system/Bakery/Command/SetupEnvCommand.php create mode 100644 app/system/Bakery/Command/SetupSmtpCommand.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ee2cab1..379823e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). ## v4.1.18 +- Bakery setup wizard for SMTP config + separate SMTP setup in it's own command (#874) ## v4.1.17-alpha - Lock `gulp-uf-bundle-assets` at v2.28.0 until userfrosting/gulp-uf-bundle-assets#5 is resolved (see #859) diff --git a/app/system/Bakery/Command/Setup.php b/app/system/Bakery/Command/Setup.php deleted file mode 100644 index b489ce26..00000000 --- a/app/system/Bakery/Command/Setup.php +++ /dev/null @@ -1,223 +0,0 @@ -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 app/.env 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/app/system/Bakery/Command/SetupCommand.php b/app/system/Bakery/Command/SetupCommand.php new file mode 100644 index 00000000..ca77066b --- /dev/null +++ b/app/system/Bakery/Command/SetupCommand.php @@ -0,0 +1,46 @@ +setName("setup") + ->setDescription("UserFrosting Configuration Wizard") + ->setHelp("This command combine the setup:env, setup:db and setup:smtp commands."); + } + + /** + * {@inheritDoc} + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $command = $this->getApplication()->find('setup:db'); + $command->run($input, $output); + + $command = $this->getApplication()->find('setup:smtp'); + $command->run($input, $output); + + $command = $this->getApplication()->find('setup:env'); + $command->run($input, $output); + } +} \ No newline at end of file diff --git a/app/system/Bakery/Command/SetupDbCommand.php b/app/system/Bakery/Command/SetupDbCommand.php new file mode 100644 index 00000000..593c6601 --- /dev/null +++ b/app/system/Bakery/Command/SetupDbCommand.php @@ -0,0 +1,260 @@ +setName("setup:db") + ->setDescription("UserFrosting Database Configuration Wizard") + ->setHelp("Helper command to setup the database configuration. This can also be done manually by editing the app/.env file or using global server environment variables.") + ->addOption('db_driver', null, InputOption::VALUE_OPTIONAL, "The database driver {$this->getDatabaseDriversList()}") + ->addOption('db_name', null, InputOption::VALUE_OPTIONAL, "The database name") + ->addOption('db_host', null, InputOption::VALUE_OPTIONAL, "The database hostname") + ->addOption('db_port', null, InputOption::VALUE_OPTIONAL, "The database port") + ->addOption('db_user', null, InputOption::VALUE_OPTIONAL, "The database user") + ->addOption('db_password', null, InputOption::VALUE_OPTIONAL, "The database password"); + } + + /** + * {@inheritDoc} + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + /** + * @var Config $config Get config + */ + $config = $this->ci->config; + + // Display header, + $this->io->title("UserFrosting's Database Setup Wizard"); + $this->io->note("Database credentials will be saved in `{$this->envPath}`"); + + // Get an instance of the DotenvEditor + $dotenvEditor = new DotenvEditor(\UserFrosting\APP_DIR, false); + $dotenvEditor->load($this->envPath); + $dotenvEditor->save(); // Save make sure empty file is created if none exist before reading it + + // Get keys + $keys = [ + 'DB_HOST' => ($dotenvEditor->keyExists('DB_HOST')) ? $dotenvEditor->getValue('DB_HOST') : '', + 'DB_NAME' => ($dotenvEditor->keyExists('DB_NAME')) ? $dotenvEditor->getValue('DB_NAME') : '', + 'DB_USER' => ($dotenvEditor->keyExists('DB_USER')) ? $dotenvEditor->getValue('DB_USER') : '', + 'DB_PASSWORD' => ($dotenvEditor->keyExists('DB_PASSWORD')) ? $dotenvEditor->getValue('DB_PASSWORD') : '' + ]; + + // There may be some custom config or global env values defined on the server. + // We'll check for that and ask for confirmation in this case. + if ($config["db.default.host"] != $keys['DB_HOST'] || + $config["db.default.database"] != $keys['DB_NAME'] || + $config["db.default.username"] != $keys['DB_USER'] || + $config["db.default.password"] != $keys['DB_PASSWORD']) { + + $this->io->warning("Current database configuration differ from the configuration defined in `{$this->envPath}`. Global system environment variables might be defined."); + + if (!$this->io->confirm('Continue?', false)) { + return; + } + } + + // Get database info + $dbParams = $this->askForDatabase($input); + + // Test database + $this->testDatabase($dbParams); + + // Time to save + $this->io->section("Saving data"); + + // Prepare file content + // N.B.: Can't use the `$dbParams` keys directly since they differ from + // the config one later used to update the config + $fileContent = [ + "DB_DRIVER" => $dbParams['driver'], + "DB_HOST" => $dbParams['host'], + "DB_PORT" => $dbParams['port'], + "DB_NAME" => $dbParams['database'], + "DB_USER" => $dbParams['username'], + "DB_PASSWORD" => $dbParams['password'] + ]; + + foreach ($fileContent as $key => $value) { + $dotenvEditor->setKey($key, $value); + } + $dotenvEditor->save(); + + // At this point, `$this->uf` is still using the old configs. + // We need to refresh the `db.default` config values + $newConfig = array_merge($this->ci->config['db.default'], $dbParams); + $this->ci->config->set("db.default", $newConfig); + + // Success + $this->io->success("Database config successfully saved in `{$this->envPath}`"); + } + + /** + * Ask for database crendentials + * + * @param InputInterface $args Command arguments + * @return array The databse credentials + */ + protected function askForDatabase(InputInterface $args) + { + // Get the db driver choices + $drivers = $this->databaseDrivers(); + $driversList = $drivers->pluck('name')->toArray(); + + // Ask for database type if not defined in command arguments + if ($args->getOption('db_driver')) { + $selectedDriver = $args->getOption('db_driver'); + $driver = $drivers->where('driver', $selectedDriver)->first(); + } else { + $selectedDriver = $this->io->choice("Database type", $driversList); + $driver = $drivers->where('name', $selectedDriver)->first(); + } + + // Get the selected driver. Make sure driver was found + if (!$driver) { + $this->io->error("Invalid database driver: $selectedDriver"); + exit(1); + } + + // Ask further questions based on driver + if ($driver['driver'] == 'sqlite') { + + $name = ($args->getOption('db_name')) ?: $this->io->ask("Database name", $driver['defaultDBName']); + + return [ + 'driver' => $driver['driver'], + 'host' => '', + 'port' => '', + 'database' => $name, + 'username' => '', + 'password' => '' + ]; + + } else { + $defaultPort = $driver['defaultPort']; + + $host = ($args->getOption('db_host')) ?: $this->io->ask("Hostname", "localhost"); + $port = ($args->getOption('db_port')) ?: $this->io->ask("Port", $defaultPort); + $name = ($args->getOption('db_name')) ?: $this->io->ask("Database name", $driver['defaultDBName']); + $user = ($args->getOption('db_user')) ?: $this->io->ask("Username", "userfrosting"); + $password = ($args->getOption('db_password')) ?: $this->io->askHidden("Password", function ($password) { + // Use custom validator to accept empty password + return $password; + }); + + return [ + 'driver' => $driver['driver'], + 'host' => $host, + 'port' => $port, + 'database' => $name, + 'username' => $user, + 'password' => $password, + 'charset' => $this->ci->config['db.default.charset'] // Used when replacing config later + ]; + } + } + + /** + * Test new database connecion + * + * @param array $dbParams Database params + * @return void (Exit if fails) + */ + protected function testDatabase($dbParams) + { + // 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"); + } 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); + } + } + + /** + * Return the database choices for the env setup. + * + * @return \Illuminate\Support\Collection + */ + 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 + ] + ]); + } + + /** + * Returns a list of available drivers + * + * @return array + */ + protected function getDatabaseDriversList() + { + $dbDriverList = $this->databaseDrivers(); + $dbDriverList = $dbDriverList->pluck('driver'); + return $dbDriverList; + } +} diff --git a/app/system/Bakery/Command/SetupEnvCommand.php b/app/system/Bakery/Command/SetupEnvCommand.php new file mode 100644 index 00000000..c92a5d05 --- /dev/null +++ b/app/system/Bakery/Command/SetupEnvCommand.php @@ -0,0 +1,96 @@ +setName("setup:env") + ->setDescription("UserFrosting Environment Configuration Wizard") + ->setHelp("Helper command to setup environement mode. This can also be done manually by editing the app/.env file or using global server environment variables.") + ->addOption('mode', null, InputOption::VALUE_OPTIONAL, "The environment to use"); + } + + /** + * {@inheritDoc} + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + // Display header, + $this->io->title("UserFrosting's Environment Setup Wizard"); + $this->io->note("Environment mode will be saved in `{$this->envPath}`"); + $this->io->write("Select desired envrionement mode. Production should only be used when deploying a live app."); + + // Get an instance of the DotenvEditor + $dotenvEditor = new DotenvEditor(\UserFrosting\APP_DIR, false); + $dotenvEditor->load($this->envPath); + + // Ask for mode + $newEnvMode = $this->askForEnv($input); + + // Save new value + $dotenvEditor->setKey($this->modeKey, $newEnvMode); + $dotenvEditor->save(); + + // Success + $this->io->success("Environment mode successfully changed to `$newEnvMode` in `{$this->envPath}`"); + } + + /** + * Ask for env mode + * + * @param InputInterface $args Command arguments + * @return string The new env mode + */ + protected function askForEnv(InputInterface $args) + { + // Ask for mode if not defined in command arguments + if ($args->getOption('mode')) { + return $args->getOption('mode'); + } else { + $newEnvMode = $this->io->choice("Environment Mode", [ + 'default', + 'production', + 'Other...' + ], 'default'); + } + + // Ask for manual input if 'other' was chosen + if ($newEnvMode == 'Other...') { + $newEnvMode = $this->io->ask('Enter desired environment mode'); + } + + return $newEnvMode; + } +} diff --git a/app/system/Bakery/Command/SetupSmtpCommand.php b/app/system/Bakery/Command/SetupSmtpCommand.php new file mode 100644 index 00000000..8ec1c33f --- /dev/null +++ b/app/system/Bakery/Command/SetupSmtpCommand.php @@ -0,0 +1,209 @@ +setName('setup:smtp') + ->setDescription('UserFrosting SMTP Configuration Wizard') + ->setHelp('Helper command to setup outgoing email configuration. This can also be done manually by editing the app/.env file or using global server environment variables.') + ->addOption('smtp_host', null, InputOption::VALUE_OPTIONAL, 'The SMTP server hostname') + ->addOption('smtp_user', null, InputOption::VALUE_OPTIONAL, 'The SMTP server user') + ->addOption('smtp_password', null, InputOption::VALUE_OPTIONAL, 'The SMTP server password'); + } + + /** + * {@inheritDoc} + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + /** + * @var Config $config Get config + */ + $config = $this->ci->config; + + // Display header, + $this->io->title("UserFrosting's SMTP Setup Wizard"); + $this->io->note("SMTP credentials will be saved in `{$this->envPath}`"); + + // Get an instance of the DotenvEditor + $dotenvEditor = new DotenvEditor(\UserFrosting\APP_DIR, false); + $dotenvEditor->load($this->envPath); + $dotenvEditor->save(); // Save make sure empty file is created if none exist before reading it + + // Get keys + $keys = [ + 'SMTP_HOST' => ($dotenvEditor->keyExists('SMTP_HOST')) ? $dotenvEditor->getValue('SMTP_HOST') : '', + 'SMTP_USER' => ($dotenvEditor->keyExists('SMTP_USER')) ? $dotenvEditor->getValue('SMTP_USER') : '', + 'SMTP_PASSWORD' => ($dotenvEditor->keyExists('SMTP_PASSWORD')) ? $dotenvEditor->getValue('SMTP_PASSWORD') : '' + ]; + + // There may be some custom config or global env values defined on the server. + // We'll check for that and ask for confirmation in this case. + if ($config['mail.host'] != $keys['SMTP_HOST'] || + $config['mail.username'] != $keys['SMTP_USER'] || + $config['mail.password'] != $keys['SMTP_PASSWORD']) { + + $this->io->warning("Current SMTP configuration differ from the configuration defined in `{$this->envPath}`. Global system environment variables might be defined."); + + if (!$this->io->confirm('Continue?', false)) { + return; + } + } + + // Ask for SMTP info + $smtpParams = $this->askForSmtpMethod($input); + + // Time to save + $this->io->section('Saving data'); + + foreach ($smtpParams as $key => $value) { + $dotenvEditor->setKey($key, $value); + } + $dotenvEditor->save(); + + // Success + $this->io->success("SMTP credentials saved to `{$this->envPath}`"); + } + + /** + * Ask with setup method to use + * + * @param InputInterface $input + * @return array The SMTP connection info + */ + protected function askForSmtpMethod(InputInterface $input) + { + // If the user defined any of the command input argument, skip right to SMTP method + if ($input->getOption('smtp_host') || $input->getOption('smtp_user') || $input->getOption('smtp_password')) { + return $this->askForSmtp($input); + } + + // Display nice explanation and ask wich method to use + $this->io->write("In order to send registration emails, UserFrosting requires an outgoing mail server. When using UserFrosting in a production environment, a SMTP server should be used. A Gmail account can be used if you're only playing with UserFrosting or on a local dev environment. You can also choose to not setup an outgoing mail server at the moment, but account registration won't work. You can always re-run this setup or edit `{$this->envPath}` if you have problems sending email later."); + + $choice = $this->io->choice('Select setup method', [self::Setup_SMTP, self::Setup_Gmail, self::Setup_None], self::Setup_SMTP); + + switch ($choice) { + case self::Setup_SMTP: + return $this->askForSmtp($input); + break; + case self::Setup_Gmail: + return $this->askForGmail($input); + break; + case self::Setup_None: + default: + return $this->askForNone($input); + break; + } + } + + /** + * Ask for SMTP credential + * + * @param InputInterface $input Command arguments + * @return array The SMTP connection info + */ + protected function askForSmtp(InputInterface $input) + { + // Ask for the smtp values now + $smtpHost = ($input->getOption('smtp_host')) ?: $this->io->ask('SMTP Server Host', 'host.example.com'); + $smtpUser = ($input->getOption('smtp_user')) ?: $this->io->ask('SMTP Server User', 'relay@example.com'); + $smtpPassword = ($input->getOption('smtp_password')) ?: $this->io->askHidden('SMTP Server Password', function ($password) { + // Use custom validator to accept empty password + return $password; + }); + + return [ + 'SMTP_HOST' => $smtpHost, + 'SMTP_USER' => $smtpUser, + 'SMTP_PASSWORD' => $smtpPassword + ]; + } + + /** + * Ask for Gmail + * + * @param InputInterface $input Command arguments + * @return array The SMTP connection info + */ + protected function askForGmail(InputInterface $input) + { + $smtpUser = ($input->getOption('smtp_user')) ?: $this->io->ask('Your full Gmail (e.g. example@gmail.com)'); + $smtpPassword = ($input->getOption('smtp_password')) ?: $this->io->askHidden('Your Gmail password', function ($password) { + // Use custom validator to accept empty password + return $password; + }); + + return [ + 'SMTP_HOST' => 'smtp.gmail.com', + 'SMTP_USER' => $smtpUser, + 'SMTP_PASSWORD' => $smtpPassword + ]; + } + + /** + * Process the "no email support" setup option + * + * @param InputInterface $input + * @return array The SMTP connection info + */ + protected function askForNone(InputInterface $input) + { + // Display big warning and confirmation + $this->io->warning("By not setting up any outgoing mail server, public account registration won't work."); + + if ($this->io->confirm('Continue ?', false)) { + return [ + 'SMTP_HOST' => '', + 'SMTP_USER' => '', + 'SMTP_PASSWORD' => '' + ]; + } else { + $this->askForSmtpMethod($input); + } + } +} From 4a99c4e327bbe35219589853bff2486c050b676a Mon Sep 17 00:00:00 2001 From: Louis Charette Date: Fri, 11 May 2018 21:27:42 -0400 Subject: [PATCH 03/10] Bump userfrosting/support version requirement based on last commit. --- app/sprinkles/core/composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/sprinkles/core/composer.json b/app/sprinkles/core/composer.json index f94c4864..b1e02bb0 100644 --- a/app/sprinkles/core/composer.json +++ b/app/sprinkles/core/composer.json @@ -33,7 +33,7 @@ "userfrosting/fortress": "~4.1.1", "userfrosting/i18n": "~4.1.0", "userfrosting/session": "~4.1.0", - "userfrosting/support": "~4.1.1", + "userfrosting/support": "~4.1.2", "vlucas/phpdotenv": "^2" }, "autoload": { From 436a4d937e36e2b4101597c7c67821208e08e15c Mon Sep 17 00:00:00 2001 From: Christian Date: Mon, 9 Apr 2018 12:57:56 +0200 Subject: [PATCH 04/10] Complete italian translations for every Sprinkle Corrected every locale of every sprinkle to a correct and real italian translation. --- .../account/locale/it_IT/messages.php | 96 +++++++++---------- .../account/locale/it_IT/validate.php | 2 +- app/sprinkles/admin/locale/it_IT/messages.php | 76 +++++++-------- app/sprinkles/core/locale/it_IT/errors.php | 26 ++--- app/sprinkles/core/locale/it_IT/messages.php | 74 +++++++------- app/sprinkles/core/locale/it_IT/validate.php | 12 +-- 6 files changed, 143 insertions(+), 143 deletions(-) diff --git a/app/sprinkles/account/locale/it_IT/messages.php b/app/sprinkles/account/locale/it_IT/messages.php index fee2e8cb..189d4074 100644 --- a/app/sprinkles/account/locale/it_IT/messages.php +++ b/app/sprinkles/account/locale/it_IT/messages.php @@ -17,41 +17,41 @@ "ACCOUNT" => [ "@TRANSLATION" => "Account", - "ACCESS_DENIED" => "Sembra tu non abbiamo il permesso di fare questo.", + "ACCESS_DENIED" => "Sembra tu non abbiamo il permesso per effettuare questa azione.", "DISABLED" => "Questo account è stato disattivato, contattaci per maggiori informazioni", "EMAIL_UPDATED" => "Email aggiornata", - "INVALID" => "Questo account non esiste. Può essere stato cancellato. Vi preghiamo di contattarci per ulteriori informazioni.", + "INVALID" => "Questo account non esiste. Può essere stato eliminato. Contattaci per ulteriori informazioni.", - "MASTER_NOT_EXISTS" => "Non puoi registrare un account finche l'account primario non sarà creato!", + "MASTER_NOT_EXISTS" => "Non puoi registrare un account finché l'account primario non sarà creato!", "MY" => "Il mio account", "SESSION_COMPROMISED" => [ - "@TRANSLATION" => "La tua sessione è stata compromessa. Devi eseguire il logout su tutti i dispositivi, quindi riaccenderti e assicurati che i tuoi dati non siano stati manomessi.", + "@TRANSLATION" => "La tua sessione è stata compromessa. Devi eseguire il logout su tutti i dispositivi, quindi accedere nuovamente e assicurarti che i tuoi dati non siano stati manomessi.", "TITLE" => "Il tuo account potrebbe essere stato compromesso", - "TEXT" => "Qualcuno potrebbe aver utilizzato le tue informazioni di accesso per accedere a questa pagina. Per la tua sicurezza tutte le sessioni sono state disconnesse. Accedi e controlla l'account per attività sospette. Potresti anche desiderare di cambiare la tua password." + "TEXT" => "Qualcuno potrebbe aver utilizzato le tue informazioni di accesso per accedere a questa pagina. Per la tua sicurezza tutte le sessioni sono state disconnesse. Accedi e controlla l'account per attività sospette. Potresti anche voler cambiare la password." ], "SESSION_EXPIRED" => "La tua sessione è scaduta. Accedi nuovamente.", "SETTINGS" => [ - "@TRANSLATION" => "Impostazioni dell 'account", + "@TRANSLATION" => "Impostazioni account", "DESCRIPTION" => "Aggiorna le impostazioni del tuo account, tra cui email, nome e password.", "UPDATED" => "Impostazioni account aggiornate" ], - "TOOLS" => "Account tools", + "TOOLS" => "Strumenti account", - "UNVERIFIED" => "Il tuo account non è stato attivato. Controlla nella tua mail ( anche nella cartella dello spam ) per riceve le instruzioni per attivare il tuo account", + "UNVERIFIED" => "Il tuo account non è stato attivato. Controlla nella tua mail (anche nella cartella dello spam) per ricevere le instruzioni per attivare il tuo account", "VERIFICATION" => [ "NEW_LINK_SENT" => "Ti è stato inviato un nuovo codice di attivazione, controlla la tua email ({{email}}).", "RESEND" => "Invia nuovamente email di verifica.", - "COMPLETE" => "Hai verificato con successo il tuo account. È ora possibile accedere.", - "EMAIL" => "Inserisci l'indirizzo email che hai utilizzato per registrarti e la tua email di verifica sarà resentata.", - "PAGE" => "Ripeti l'email di verifica per il tuo nuovo account.", - "SEND" => "Inviilo il collegamento di verifica per il mio account", + "COMPLETE" => "Hai verificato con successo il tuo account. Puoi ora accedere.", + "EMAIL" => "Inserisci l'indirizzo email che hai utilizzato per registrarti e la tua email di verifica sarà inviata nuovamente.", + "PAGE" => "Invia nuovamente l'email di verifica per il tuo nuovo account.", + "SEND" => "Invia il collegamento di verifica per il mio account", "TOKEN_NOT_FOUND" => "Il token non esiste / l'account è già stato attivato" ] ], @@ -59,29 +59,29 @@ "EMAIL" => [ "INVALID" => "Non esiste alcun account per {{email}}.", "IN_USE" => "L'email '{{email}}' è già in uso", - "VERIFICATION_REQUIRED" => "Email (verifica richiesta - utilizzare un indirizzo reale!)" + "VERIFICATION_REQUIRED" => "Email (verifica richiesta - utilizza un indirizzo reale!)" ], - "EMAIL_OR_USERNAME" => "Username o Indirizzo Email", + "EMAIL_OR_USERNAME" => "Nome utente o Indirizzo Email", "FIRST_NAME" => "Nome", - "HEADER_MESSAGE_ROOT" => "LOGGATO COME ROOT", + "HEADER_MESSAGE_ROOT" => "ACCESSO ROOT", "LAST_NAME" => "Cognome", "LOCALE" => [ - "ACCOUNT" => "La lingua e la località da utilizzare per il tuo account", - "INVALID" => "{{locale}} non è una località valida.", + "ACCOUNT" => "La lingua da utilizzare per il tuo account", + "INVALID" => "{{locale}} non è una lingua valida.", ], "LOGIN" => [ "@TRANSLATION" => "Accesso", - "ALREADY_COMPLETE" => "Sei già loggato!", + "ALREADY_COMPLETE" => "Hai già eseguito l'accesso!", "SOCIAL" => "O accedi con", - "REQUIRED" => "Devi essere loggato per accedere a questa risorsa" + "REQUIRED" => "Devi eseguire l'accesso per accedere a questa risorsa" ], - "LOGOUT" => "Logout", + "LOGOUT" => "Esci", "NAME" => "Nome", @@ -89,7 +89,7 @@ "PAGE" => [ "LOGIN" => [ - "DESCRIPTION" => "Accedi al tuo account {{site_name}} o registrati per un nuovo account.", + "DESCRIPTION" => "Accedi al tuo account {{site_name}} o iscriviti per un nuovo account.", "SUBTITLE" => "Registrati gratuitamente o accedi con un account esistente.", "TITLE" => "Iniziamo!", ] @@ -118,67 +118,67 @@ "@TRANSLATION" => "Ho dimenticato la mia password", "COULD_NOT_UPDATE" => "Password non aggiornata", - "EMAIL" => "Inserisci l'indirizzo email che hai utilizzato per iscriverti. Un collegamento con le istruzioni per reimpostare la tua password verrà inviata via email.", - "EMAIL_SEND" => "Email link di resetta password", - "INVALID" => "Questa richiesta di ripristino della password non è stata trovata o è scaduta. Prova a riprovare la tua richiesta.", + "EMAIL" => "Inserisci l'indirizzo email che hai utilizzato per iscriverti. Un link con le istruzioni per reimpostare la tua password verrà inviata via email.", + "EMAIL_SEND" => "Invia email per il reset della password", + "INVALID" => "Questa richiesta di ripristino della password non è stata trovata o è scaduta. Prova a reinviare la tua richiesta.", "PAGE" => "Ottieni un collegamento per reimpostare la tua password.", - "REQUEST_CANNED" => "Richiesta di recupero password cancellata.", - "REQUEST_SENT" => "Se l'email {{email}} corrisponde a un account nel nostro sistema, verrà inviato un collegamento per la reimpostazione della password a {{email}}." + "REQUEST_CANNED" => "Richiesta di recupero password annullata.", + "REQUEST_SENT" => "Se l'email {{email}} corrisponde a un account, verrà inviato un collegamento per la reimpostazione della password a {{email}}." ], "HASH_FAILED" => "Hash della password fallito. Contatta l'amministratore di sistema.", - "INVALID" => "La password corrente non corrisponde con quella in memoria", + "INVALID" => "La password corrente non corrisponde con quella attuale", "NEW" => "Nuova Password", - "NOTHING_TO_UPDATE" => "Non puoi aggiornare con la stessa password", + "NOTHING_TO_UPDATE" => "Non puoi impostare la stessa password precedente", "RESET" => [ - "@TRANSLATION" => "Resetta la Password", + "@TRANSLATION" => "Reimposta la Password", "CHOOSE" => "Inserisci la tua nuova password", "PAGE" => "Scegli una nuova password per il tuo account.", - "SEND" => "Impostare nuova password e accedere" + "SEND" => "Imposta nuova password e accedi" ], "UPDATED" => "Password aggiornata" ], "PROFILE" => [ - "SETTINGS" => "Impostazioni del profilo", - "UPDATED" => "Le impostazioni del profilo sono aggiornate" + "SETTINGS" => "Impostazioni profilo", + "UPDATED" => "Impostazioni profilo aggiornate" ], - "RATE_LIMIT_EXCEEDED" => "Il limite di velocità per questa azione è stato superato. Devi aspettare un altro {{delay}} secondi prima che ti sia permesso di fare un altro tentativo.", - "REGISTER" => "Registrare", + "RATE_LIMIT_EXCEEDED" => "Il limite di esecuzioni per questa azione è stato superato. Devi aspettare altri {{delay}} secondi prima che tu possa fare un altro tentativo.", + "REGISTER" => "Registrati", "REGISTER_ME" => "Iscrivimi", "REGISTRATION" => [ - "BROKEN" => "Ci dispiace, c'è un problema con il nostro processo di registrazione dell'account. Vi preghiamo di contattarci direttamente per assistenza.", - "COMPLETE_TYPE1" => "Sei stato registrato con successo ora puoi eseguire il login", - "COMPLETE_TYPE2" => "Sei stato registrato con successo. Riceverai presto una mail a {{email}} per l'attivazione. Devi attivare il tuo account prima di eseguire il login.", - "DISABLED" => "La registrazione di nuovi account è stata bloccata", - "LOGOUT" => "Non è possibile registrare un account mentre si è loggati", + "BROKEN" => "Siamo spiacenti, c'è un problema con il nostro processo di registrazione dell'account. Vi preghiamo di contattarci direttamente per assistenza.", + "COMPLETE_TYPE1" => "Registrazione effettuata con successo. Ora puoi eseguire il login", + "COMPLETE_TYPE2" => "Registrazione effettuata con successo. Riceverai presto una mail a {{email}} per l'attivazione. Devi attivare il tuo account prima di eseguire il login.", + "DISABLED" => "La registrazione di nuovi account è limitata", + "LOGOUT" => "Non è possibile registrare un account mentre hai eseguito l'accesso ad un altro account", "WELCOME" => "La registrazione è semplice e veloce" ], - "REMEMBER_ME" => "Ricordami!", - "REMEMBER_ME_ON_COMPUTER" => "Ricordami su questo computer (non consigliato per i computer pubblici)", + "REMEMBER_ME" => "Ricordami", + "REMEMBER_ME_ON_COMPUTER" => "Ricordami su questo dispositivo (non consigliato per i computer pubblici)", "SIGN_IN_HERE" => "Hai già un account? Accedi qui", "SIGNIN" => "Accedi", - "SIGNIN_OR_REGISTER" => "Accedi o registri", + "SIGNIN_OR_REGISTER" => "Accedi o iscriviti", "SIGNUP" => "Registrazione", "TOS" => "Termini e condizioni", - "TOS_AGREEMENT" => "Registrando un account con {{site_title}}, accetti il termini e condizioni.", - "TOS_FOR" => "Termini e condizioni per {{title}}", + "TOS_AGREEMENT" => "Registrando un account su {{site_title}}, accetti i Termini e le Condizioni.", + "TOS_FOR" => "Termini e condizioni di {{title}}", "USERNAME" => [ - "@TRANSLATION" => "Username", + "@TRANSLATION" => "Nome utente", - "CHOOSE" => "Inserisci il tuo username", - "INVALID" => "Username non valido", + "CHOOSE" => "Inserisci il tuo nome utente", + "INVALID" => "Nome utente non valido", "IN_USE" => "Il nome utente '{{user_name}}' è già in uso", "NOT_AVAILABLE" => "Il nome utente {{user_name}} non è disponibile. Scegli un nome diverso, oppure fai clic su \"suggerisci\"." ], - "USER_ID_INVALID" => "User ID richiesto non è valido", + "USER_ID_INVALID" => "Questo ID utente non esiste", "USER_OR_EMAIL_INVALID" => "L'indirizzo mail o il nome utente non sono validi", "USER_OR_PASS_INVALID" => "Il nome utente o la password non sono validi", diff --git a/app/sprinkles/account/locale/it_IT/validate.php b/app/sprinkles/account/locale/it_IT/validate.php index 713ccbac..c9144a0a 100644 --- a/app/sprinkles/account/locale/it_IT/validate.php +++ b/app/sprinkles/account/locale/it_IT/validate.php @@ -16,6 +16,6 @@ return [ "VALIDATE" => [ "PASSWORD_MISMATCH" => "I due campi devono combaciare", - "USERNAME" => "L'username può essere composto da caratteri alfanumerici, '.', '-', e '_'." + "USERNAME" => "Il nome utente può essere composto solo da caratteri alfanumerici, '.', '-', e '_'." ] ]; diff --git a/app/sprinkles/admin/locale/it_IT/messages.php b/app/sprinkles/admin/locale/it_IT/messages.php index c40d5b3f..7d17d8cd 100644 --- a/app/sprinkles/admin/locale/it_IT/messages.php +++ b/app/sprinkles/admin/locale/it_IT/messages.php @@ -24,44 +24,44 @@ ], "CACHE" => [ - "CLEAR" => "Cancellare la cache", - "CLEAR_CONFIRM" => "Sei sicuro di voler cancellare la cache del sito?", - "CLEAR_CONFIRM_YES" => "Sì, cancellare la cache", + "CLEAR" => "Elimina cache", + "CLEAR_CONFIRM" => "Sei sicuro di voler eliminare la cache del sito?", + "CLEAR_CONFIRM_YES" => "Sì, elimina la cache", "CLEARED" => "La cache è stata eliminata correttamente!" ], "DASHBOARD" => "Pannello di Controllo", - "NO_FEATURES_YET" => "Non sembra che alcune funzioni siano state create per questo account ... ancora. Forse non sono ancora state implementate, o forse qualcuno ha dimenticato di dare accesso. In entrambi i casi, siamo contenti di averti qui!", + "NO_FEATURES_YET" => "Sembra che nessuna funzione sia stata creata per questo account... ancora. Forse non sono ancora state implementate o qualcuno ha dimenticato di dartene accesso. In entrambi i casi, siamo contenti di averti qui!", "DELETE_MASTER" => "Non puoi eliminare l'account principale!", - "DELETION_SUCCESSFUL" => "Hai eliminato utente {{user_name}}.", - "DETAILS_UPDATED" => "Dettagli degli account aggiornati per l'utente {{user_name}}", + "DELETION_SUCCESSFUL" => "Hai eliminato l'utente utente {{user_name}}.", + "DETAILS_UPDATED" => "Dettagli account aggiornati per l'utente {{user_name}}", "DISABLE_MASTER" => "Non puoi disattivare l'account principale!", "DISABLE_SELF" => "Non puoi disattivare il tuo account!", - "DISABLE_SUCCESSFUL" => "Account per l'utente {{user_name}} disattivato con successo!", - "ENABLE_SUCCESSFUL" => "Account per l'utente {{user_name}} attivato con successo.", + "DISABLE_SUCCESSFUL" => "Account dell'utente {{user_name}} disattivato con successo!", + "ENABLE_SUCCESSFUL" => "Account dell'utente {{user_name}} attivato con successo.", "GROUP" => [ 1 => "Gruppo", 2 => "Gruppi", - "CREATE" => "Creare un gruppo", - "CREATION_SUCCESSFUL" => "Ha creato con successo il gruppo {{name}}", + "CREATE" => "Crea un gruppo", + "CREATION_SUCCESSFUL" => "Gruppo {{name}} creato con successo", "DELETE" => "Elimina gruppo", "DELETE_CONFIRM" => "Sei sicuro di voler eliminare il gruppo {{name}}?", "DELETE_DEFAULT" => "Non puoi eliminare il gruppo {{name}} perché è il gruppo predefinito per gli utenti appena registrati.", - "DELETE_YES" => "Sì, elimini il gruppo", - "DELETION_SUCCESSFUL" => "Eliminato il gruppo {{name}} con successo", + "DELETE_YES" => "Sì, elimina il gruppo", + "DELETION_SUCCESSFUL" => "Gruppo {{name}} eliminato con successo", "EDIT" => "Modifica gruppo", "ICON" => "Icona del gruppo", "ICON_EXPLAIN" => "Icona per i membri del gruppo", - "INFO_PAGE" => "Pagina informazioni di gruppo per {{name}}", + "INFO_PAGE" => "Pagina informazioni del Gruppo per {{name}}", "MANAGE" => "Gestisci gruppo", - "NAME" => "Nome del gruppo", + "NAME" => "Nome gruppo", "NAME_EXPLAIN" => "Inserisci un nome per il gruppo", "NOT_EMPTY" => "Non puoi farlo perché ci sono ancora utenti associati al gruppo {{name}}.", "PAGE_DESCRIPTION" => "Un elenco dei gruppi per il tuo sito. Fornisce strumenti di gestione per la modifica e l'eliminazione di gruppi.", - "SUMMARY" => "Riepilogo del gruppo", - "UPDATE" => "Dettagli aggiornati per il gruppo {{name}}." + "SUMMARY" => "Riepilogo Gruppo", + "UPDATE" => "Dettagli del gruppo {{name}} aggiornati." ], "MANUALLY_ACTIVATED" => "{{user_name}} è stato attivato manualmente", @@ -71,33 +71,33 @@ ], "PERMISSION" => [ - 1 => "Autorizzazione", - 2 => "Autorizzazioni", + 1 => "Permesso", + 2 => "Permessi", - "ASSIGN_NEW" => "Assegna nuova autorizzazione", + "ASSIGN_NEW" => "Assegna nuovo permesso", "HOOK_CONDITION" => "Hook/Condizioni", - "ID" => "ID di autorizzazione", + "ID" => "ID permesso", "INFO_PAGE" => "Pagina di informazioni sulle autorizzazioni per {{name}}", "MANAGE" => "Gestione delle autorizzazioni", - "NOTE_READ_ONLY" => "Si prega di notare: le autorizzazioni sono considerate \"parte del codice\" e non possono essere modificate tramite l'interfaccia. Per aggiungere, rimuovere o modificare le autorizzazioni, i gestori del sito devono utilizzare migrazione del database.", + "NOTE_READ_ONLY" => "Nota: le autorizzazioni sono considerate \"parte del codice\" e non possono essere modificate tramite l'interfaccia. Per aggiungere, rimuovere o modificare le autorizzazioni, i gestori del sito devono utilizzare migrazione del database.", "PAGE_DESCRIPTION" => "Un elenco delle autorizzazioni per il tuo sito. Fornisce strumenti di gestione per la modifica e l'eliminazione delle autorizzazioni.", - "SUMMARY" => "Sommario delle Autorizzazioni", - "UPDATE" => "Aggiorna le autorizzazioni", - "VIA_ROLES" => "Ha autorizzazione tramite ruoli" + "SUMMARY" => "Sommario autorizzazioni", + "UPDATE" => "Aggiorna autorizzazioni", + "VIA_ROLES" => "Ha i permessi tramite i ruoli" ], "ROLE" => [ 1 => "Ruolo", 2 => "Ruoli", - "ASSIGN_NEW" => "Assegna un nuovo ruolo", + "ASSIGN_NEW" => "Assegna nuovo ruolo", "CREATE" => "Crea ruolo", "CREATION_SUCCESSFUL" => "Creato con successo il ruolo {{name}}", - "DELETE" => "Elimina il ruolo", + "DELETE" => "Elimina ruolo", "DELETE_CONFIRM" => "Sei sicuro di voler eliminare il ruolo {{name}}?", "DELETE_DEFAULT" => "Non puoi eliminare il ruolo {{name}} perché è un ruolo predefinito per gli utenti appena registrati.", - "DELETE_YES" => "Sì, elimini il ruolo", - "DELETION_SUCCESSFUL" => "Eliminato il ruolo {{name}}", + "DELETE_YES" => "Sì, elimina il ruolo", + "DELETION_SUCCESSFUL" => "Ruolo {{name}} eliminato", "EDIT" => "Modifica ruolo", "HAS_USERS" => "Non puoi farlo perché ci sono ancora utenti che hanno il ruolo {{name}}.", "INFO_PAGE" => "Pagina di informazioni sui ruoli per {{name}}", @@ -106,9 +106,9 @@ "NAME_EXPLAIN" => "Inserisci un nome per il ruolo", "NAME_IN_USE" => "Esiste già un ruolo denominato {{name}}", "PAGE_DESCRIPTION" => "Un elenco dei ruoli per il tuo sito. Fornisce strumenti di gestione per la modifica e l'eliminazione di ruoli.", - "PERMISSIONS_UPDATED" => "Autorizzazioni aggiornate per ruolo {{name}}", + "PERMISSIONS_UPDATED" => "Autorizzazioni aggiornate per il ruolo {{name}}", "SUMMARY" => "Riepilogo dei Ruoli", - "UPDATED" => "Dettagli aggiornati per ruolo {{name}}" + "UPDATED" => "Dettagli aggiornati per il ruolo {{name}}" ], "SYSTEM_INFO" => [ @@ -118,10 +118,10 @@ "DB_VERSION" => "Versione del database", "DIRECTORY" => "Directory del progetto", "PHP_VERSION" => "Versione PHP", - "SERVER" => "Software del webserver", + "SERVER" => "Software Webserver", "SPRINKLES" => "Sprinkles caricati", "UF_VERSION" => "Versione UserFrosting", - "URL" => "Url della radice del sito" + "URL" => "Url della root del sito" ], "TOGGLE_COLUMNS" => "Scambia le colonne", @@ -131,20 +131,20 @@ 2 => "Utenti", "ADMIN" => [ - "CHANGE_PASSWORD" => "Cambia Password Utente", - "SEND_PASSWORD_LINK" => "Inviare all'utente un collegamento che permetterà loro di scegliere la propria password", + "CHANGE_PASSWORD" => "Cambia password utente", + "SEND_PASSWORD_LINK" => "Invia all'utente un link che gli permetterà di scegliere una nuova password.", "SET_PASSWORD" => "Impostare la password dell'utente come" ], - "ACTIVATE" => "Attiva l'utente", - "CREATE" => "Creare un utente", - "CREATED" => "Account per l'utente {{user_name}} è stato creato.", + "ACTIVATE" => "Attiva utente", + "CREATE" => "Creare utente", + "CREATED" => "Account utente {{user_name}} creato.", "DELETE" => "Elimina utente", "DELETE_CONFIRM" => "Sei sicuro di voler eliminare l'utente {{name}}?", "DELETE_YES" => "Sì, elimina l'utente", "DISABLE" => "Disabilita l'utente", "EDIT" => "Modifica utente", - "ENABLE" => "Abilita l'utente", + "ENABLE" => "Abilita utente", "INFO_PAGE" => "Pagina informazioni utente per {{name}}", "LATEST" => "Ultimi Utenti", "PAGE_DESCRIPTION" => "Un elenco degli utenti del tuo sito. Fornisce strumenti di gestione, tra cui la possibilità di modificare i dettagli utente, attivare manualmente gli utenti, abilitare / disabilitare gli utenti e altro ancora.", diff --git a/app/sprinkles/core/locale/it_IT/errors.php b/app/sprinkles/core/locale/it_IT/errors.php index c5d4eaaa..ed3df069 100644 --- a/app/sprinkles/core/locale/it_IT/errors.php +++ b/app/sprinkles/core/locale/it_IT/errors.php @@ -18,36 +18,36 @@ "@TRANSLATION" => "Errore", "400" => [ - "TITLE" => "Errore 400: Cattiva Richiesta", - "DESCRIPTION" => "Scusa per l'errore.", + "TITLE" => "Errore 400: Richiesta non valida", + "DESCRIPTION" => "Siamo spiacenti per l'errore.", ], "404" => [ - "TITLE" => "Errore 404 - Pagina Non Trovata", - "DESCRIPTION" => "Non possiamo sembrare trovare quello che stai cercando.", - "DETAIL" => "Abbiamo cercato di trovare la tua pagina ...", + "TITLE" => "Errore 404 - Pagina non trovata", + "DESCRIPTION" => "Non riusciamo a trovare quel che cerchi...", + "DETAIL" => "Abbiamo provato a trovare quello che cercavi...", "EXPLAIN" => "Non abbiamo trovato la pagina che stavi cercando.", - "RETURN" => "Fai clic su qui per tornare alla prima pagina." + "RETURN" => "Fai clic qui per tornare alla homepage." ], "CONFIG" => [ "TITLE" => "Problema di configurazione di UserFrosting!", - "DESCRIPTION" => "Alcuni requisiti di configurazione UserFrosting non sono stati soddisfatti.", - "DETAIL" => "Qualcosa non è proprio qui.", - "RETURN" => "Correggi i seguenti errori, quindi ricarica." + "DESCRIPTION" => "Alcuni requisiti di configurazione di UserFrosting non sono stati soddisfatti.", + "DETAIL" => "Qualcosa qui non va bene.", + "RETURN" => "Correggi i seguenti errori, quindi ricarica la pagina." ], - "DESCRIPTION" => "Abbiamo sentito un grande disturbo nella Forza.", + "DESCRIPTION" => "Abbiamo notato un grande disturbo della Forza.", "DETAIL" => "Ecco quello che sappiamo:", - "ENCOUNTERED" => "Uhhh...qualcosa è accaduto. Non sappiamo cosa.", + "ENCOUNTERED" => "Uhhh... è successo qualosa. Non sappiamo cosa.", "MAIL" => "Errore nell'invio della mail, contatta l'amministratore di sistema", - "RETURN" => "Fai clic su qui per tornare alla prima pagina.", + "RETURN" => "Fai clic qui per tornare alla homepage.", "SERVER" => "Sembra esserci un errore nel server. Se sei un admin, controlla i log di PHP o UserFrosting.", - "TITLE" => "Disturbo nella Forza" + "TITLE" => "Disturbo della Forza" ] ]; diff --git a/app/sprinkles/core/locale/it_IT/messages.php b/app/sprinkles/core/locale/it_IT/messages.php index 255d7321..e2dad286 100644 --- a/app/sprinkles/core/locale/it_IT/messages.php +++ b/app/sprinkles/core/locale/it_IT/messages.php @@ -16,47 +16,47 @@ return [ "@PLURAL_RULE" => 1, - "ABOUT" => "Riguardo a noi", + "ABOUT" => "Su di noi", "CAPTCHA" => [ "@TRANSLATION" => "Captcha", - "FAIL" => "Domanda di sicurezza sbagliata", - "SPECIFY" => "Inserire il captcha", - "VERIFY" => "Verifica la captcha" + "FAIL" => "Captcha errato", + "SPECIFY" => "Inserisci il captcha", + "VERIFY" => "Verifica captcha" ], - "CSRF_MISSING" => "Sigillo CSRF mancante. Prova a aggiornare la pagina e poi di inviarlo nuovamente?", + "CSRF_MISSING" => "Token CSRF mancante. Prova ad aggiornare la pagina e poi invia nuovamente la richiesta.", - "DB_INVALID" => "Impossibile connettersi al database. Se sei un amministratore, controlla il registro PHP o UserFrosting.", + "DB_INVALID" => "Impossibile connettersi al database. Se sei un amministratore, controlla il log PHP o di UserFrosting.", "DESCRIPTION" => "Descrizione", "DOWNLOAD" => [ - "@TRANSLATION" => "Scaricare", + "@TRANSLATION" => "Scarica", "CSV" => "Scarica CSV" ], "EMAIL" => [ - "@TRANSLATION" => "E-mail", + "@TRANSLATION" => "Email", "YOUR" => "La tua email" ], - "HOME" => "Inizio", + "HOME" => "Home", "LEGAL" => [ - "@TRANSLATION" => "Politica Legale", + "@TRANSLATION" => "Politica legale", "DESCRIPTION" => "La nostra politica legale si applica al tuo utilizzo di questo sito e dei nostri servizi." ], "LOCALE" => [ - "@TRANSLATION" => "Località" + "@TRANSLATION" => "Lingua" ], "NAME" => "Nome", "NAVIGATION" => "Navigazione", - "NO_RESULTS" => "Spiacenti, non abbiamo niente qui.", + "NO_RESULTS" => "Spiacenti, qui non c'è niente.", "PAGINATION" => [ "GOTO" => "Vai alla pagina", - "SHOW" => "Mostrare", + "SHOW" => "Mostra", // Paginator // possible variables: {size}, {page}, {totalPages}, {filteredPages}, {startRow}, {endRow}, {filteredRows} and {totalRows} @@ -69,55 +69,55 @@ ], "PRIVACY" => [ "@TRANSLATION" => "Politica sulla riservatezza", - "DESCRIPTION" => "La nostra politica sulla privacy descrive quali tipi di informazioni raccoglieremo da te e come lo useremo." + "DESCRIPTION" => "La nostra politica sulla privacy descrive quali tipi di informazioni raccoglieremo da te e come le useremo." ], "SLUG" => "Slug", "SLUG_CONDITION" => "Slug/Condizioni", "SLUG_IN_USE" => "Esiste già uno slug {{slug}}", "STATUS" => "Stato", - "SUGGEST" => "Suggerire", + "SUGGEST" => "Suggerisci", "UNKNOWN" => "Sconosciuto", // Actions words "ACTIONS" => "Azioni", - "ACTIVATE" => "Attivare", + "ACTIVATE" => "Attiva", "ACTIVE" => "Attivo", - "ADD" => "Aggiungere", + "ADD" => "Aggiungi", "CANCEL" => "Annulla", "CONFIRM" => "Conferma", - "CREATE" => "Creare", + "CREATE" => "Crea", "DELETE" => "Elimina", - "DELETE_CONFIRM" => "Sei sicuro di voler cancellare questo?", - "DELETE_CONFIRM_YES" => "Sì, elimini", + "DELETE_CONFIRM" => "Sei sicuro di volerlo eliminare?", + "DELETE_CONFIRM_YES" => "Sì, elimina", "DELETE_CONFIRM_NAMED" => "Sei sicuro di voler eliminare {{name}}?", - "DELETE_CONFIRM_YES_NAMED" => "Sì, eliminare {{name}}", + "DELETE_CONFIRM_YES_NAMED" => "Sì, elimina {{name}}", "DELETE_CANNOT_UNDONE" => "Questa azione non può essere annullata.", "DELETE_NAMED" => "Elimina {{name}}", - "DENY" => "Nega", - "DISABLE" => "Disattivare", + "DENY" => "Rifiuta", + "DISABLE" => "Disabilita", "DISABLED" => "Disabilitato", "EDIT" => "Modifica", - "ENABLE" => "Abilitare", + "ENABLE" => "Abilita", "ENABLED" => "Abilitato", - "OVERRIDE" => "Alterare", - "RESET" => "Azzerare", - "SAVE" => "Memorizzare", - "SEARCH" => "Cercare", - "SORT" => "Ordinare", - "SUBMIT" => "Inviare", + "OVERRIDE" => "Sovrascrivi", + "RESET" => "Azzera", + "SAVE" => "Salva", + "SEARCH" => "Cerca", + "SORT" => "Ordina", + "SUBMIT" => "Invia", "SUCCESS" => "Successo", - "PRINT" => "Stampare", - "REMOVE" => "Rimuovere", - "UNACTIVATED" => "Non attivato", - "UPDATE" => "Aggiornare", + "PRINT" => "Stampa", + "REMOVE" => "Rimuovi", + "UNACTIVATED" => "Disattivato", + "UPDATE" => "Aggiorna", "YES" => "Sì", "NO" => "No", "OPTIONAL" => "Opzionale", // Misc. - "BUILT_WITH_UF" => "Construito UserFrosting", - "ADMINLTE_THEME_BY" => "Tema da Almsaeed Studio. Tutti i diritti riservati", - "WELCOME_TO" => "Benvenuto a {{title}}!" + "BUILT_WITH_UF" => "Construito con UserFrosting", + "ADMINLTE_THEME_BY" => "Tema di Almsaeed Studio. Tutti i diritti riservati", + "WELCOME_TO" => "Benvenuto su {{title}}!" ]; diff --git a/app/sprinkles/core/locale/it_IT/validate.php b/app/sprinkles/core/locale/it_IT/validate.php index 99e4a579..16aa75ab 100644 --- a/app/sprinkles/core/locale/it_IT/validate.php +++ b/app/sprinkles/core/locale/it_IT/validate.php @@ -15,13 +15,13 @@ return [ "VALIDATE" => [ - "ARRAY" => "I valori per {{label}} devono essere in un vettore.", + "ARRAY" => "I valori per {{label}} devono essere in un array.", "BOOLEAN" => "Il valore per {{label}} deve essere '0' o '1'.", - "INTEGER" => "Il valore per {{label}} deve essere un intero.", - "INVALID_EMAIL" => "Indirizzo mail non valido", - "LENGTH_RANGE" => "{{label}} deve essere compreso tra i caratteri {{min}} e {{max}} in lunghezza.", - "NO_LEAD_WS" => "Il valore di {{label}} non può iniziare con spazi, tabulazioni o altri spazi vuoti.", - "NO_TRAIL_WS" => "Il valore di {{label}} non può terminare con spazi, tabulazioni o altri spazi vuoti.", + "INTEGER" => "Il valore per {{label}} deve essere un numero intero.", + "INVALID_EMAIL" => "Indirizzo email non valido", + "LENGTH_RANGE" => "{{label}} deve essere compreso tra {{min}} e {{max}} caratteri di lunghezza.", + "NO_LEAD_WS" => "Il valore di {{label}} non può iniziare con spazi, tab o altri spazi vuoti.", + "NO_TRAIL_WS" => "Il valore di {{label}} non può terminare con spazi, tab o altri spazi vuoti.", "REQUIRED" => "Il campo {{label}} deve essere specificato.", "SPRUNJE" => [ "BAD_FILTER" => "{{name}} non è un filtro valido per questo Sprunje.", From 959ccc97a74e479160c96f23fe0d48ef1961268f Mon Sep 17 00:00:00 2001 From: Christian Date: Mon, 9 Apr 2018 13:10:56 +0200 Subject: [PATCH 05/10] Fixed typo --- app/sprinkles/account/locale/it_IT/messages.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/sprinkles/account/locale/it_IT/messages.php b/app/sprinkles/account/locale/it_IT/messages.php index 189d4074..455a302c 100644 --- a/app/sprinkles/account/locale/it_IT/messages.php +++ b/app/sprinkles/account/locale/it_IT/messages.php @@ -17,7 +17,7 @@ "ACCOUNT" => [ "@TRANSLATION" => "Account", - "ACCESS_DENIED" => "Sembra tu non abbiamo il permesso per effettuare questa azione.", + "ACCESS_DENIED" => "Sembra tu non abbia il permesso per effettuare questa azione.", "DISABLED" => "Questo account è stato disattivato, contattaci per maggiori informazioni", From cc585d4488cbbc2d9a48a554c1ca66cebd140b64 Mon Sep 17 00:00:00 2001 From: alexweissman Date: Sun, 13 May 2018 19:53:07 -0400 Subject: [PATCH 06/10] update ISSUE_TEMPLATE.md --- .github/ISSUE_TEMPLATE.md | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index e46fc9f2..bf732619 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,2 +1,19 @@ - \ No newline at end of file +🛑 STOP! + +Before you open an issue: + +1. Make sure that your issue is a BUG or FEATURE REQUEST. General usage and troubleshooting questions should be directed to the [forums](https://forums.userfrosting.com), [chat](https://chat.userfrosting.com), or [Stack Overflow](https://stackoverflow.com/questions/tagged/userfrosting). You can also consult our chapter on [common problems](https://learn.userfrosting.com/troubleshooting/common-problems). Issues asking for general support WILL BE CLOSED automatically. +2. Search the forums and current issues, both open and closed, for a similar issue. If the bug is still present but the relevant issue has been closed, you may ask us to reopen the issue. Duplicate issues will be closed automatically. +3. Make sure that you are using the latest stable version of UserFrosting (see the [release history](https://github.com/userfrosting/UserFrosting/releases)). Support for UserFrosting 3.x or earlier may be limited. + +If you are CERTAIN that it is appropriate to open a new issue, you must: + +1. Format any code snippets or command-line output using Markdown [code fences](https://help.github.com/articles/creating-and-highlighting-code-blocks/), and make sure your code is properly indented. **This is extremely important** - poorly formatted code is difficult to read and reflects badly on you as a programmer. +2. Remember that courtesy and proper grammar go a long way. Please take the time to craft a precise, polite issue. We will do our best to help, but remember that this is an open-source project - none of us are getting paid a salary to develop this project, or act as your personal support hotline ;-) + 1. State the steps needed to reproduce the problem. + 2. Mention your version of UserFrosting, as well as the browser(s) and operating system(s) in which the problem occurs. + 3. Report any errors in detail. Vague issues like "it doesn't work when I do this" are not helpful. Show that you have put some effort into identifying the cause of the error. See the section on [debugging](https://learn.userfrosting.com/troubleshooting/debugging) for information on how to get more details about errors and other problems. +3. You should always test your code in a local development environment, to separate code-related issues from server issues. In general, we recommend that you install a local development server on your computer, rather than testing your code directly on the production server. This means you can test your code directly on your own computer, making development faster and without the risk of exposing sensitive information to the public. We recommend installing Vagrant and Homestead if you don't already have a local server set up. +4. If you are not conversationally proficient in English, do NOT just post a machine translation (e.g. Google Translate) to GitHub. Get help in crafting your question, either via the [forums](https://forums.userfrosting.com) or in [chat](https://chat.userfrosting.com). If all else fails, you may post your bug report or feature request in your native language, with a machine translation below that. We will tag it with `translation-needed` so that others who speak your language can find it. +5. Clear out this placeholder text. +6. Consider supporting this project by [making a donation to our Open Collective](https://opencollective.com/userfrosting/donate)! From 135535e3a143a0edc144911fade0cf7454415889 Mon Sep 17 00:00:00 2001 From: alexweissman Date: Sun, 13 May 2018 19:55:50 -0400 Subject: [PATCH 07/10] fix indent --- .github/ISSUE_TEMPLATE.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index bf732619..8e0d7621 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -10,9 +10,9 @@ If you are CERTAIN that it is appropriate to open a new issue, you must: 1. Format any code snippets or command-line output using Markdown [code fences](https://help.github.com/articles/creating-and-highlighting-code-blocks/), and make sure your code is properly indented. **This is extremely important** - poorly formatted code is difficult to read and reflects badly on you as a programmer. 2. Remember that courtesy and proper grammar go a long way. Please take the time to craft a precise, polite issue. We will do our best to help, but remember that this is an open-source project - none of us are getting paid a salary to develop this project, or act as your personal support hotline ;-) - 1. State the steps needed to reproduce the problem. - 2. Mention your version of UserFrosting, as well as the browser(s) and operating system(s) in which the problem occurs. - 3. Report any errors in detail. Vague issues like "it doesn't work when I do this" are not helpful. Show that you have put some effort into identifying the cause of the error. See the section on [debugging](https://learn.userfrosting.com/troubleshooting/debugging) for information on how to get more details about errors and other problems. + 1. State the steps needed to reproduce the problem. + 2. Mention your version of UserFrosting, as well as the browser(s) and operating system(s) in which the problem occurs. + 3. Report any errors in detail. Vague issues like "it doesn't work when I do this" are not helpful. Show that you have put some effort into identifying the cause of the error. See the section on [debugging](https://learn.userfrosting.com/troubleshooting/debugging) for information on how to get more details about errors and other problems. 3. You should always test your code in a local development environment, to separate code-related issues from server issues. In general, we recommend that you install a local development server on your computer, rather than testing your code directly on the production server. This means you can test your code directly on your own computer, making development faster and without the risk of exposing sensitive information to the public. We recommend installing Vagrant and Homestead if you don't already have a local server set up. 4. If you are not conversationally proficient in English, do NOT just post a machine translation (e.g. Google Translate) to GitHub. Get help in crafting your question, either via the [forums](https://forums.userfrosting.com) or in [chat](https://chat.userfrosting.com). If all else fails, you may post your bug report or feature request in your native language, with a machine translation below that. We will tag it with `translation-needed` so that others who speak your language can find it. 5. Clear out this placeholder text. From 3c4494e4120395c0983a02b38eae865d55d61735 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=84kwav?= Date: Sun, 1 Apr 2018 17:21:24 +0200 Subject: [PATCH 08/10] rowDelete event event fix The rowDelete event from the ufCollection widget didn't include the deleted row. But following the docs it should: https://learn.userfrosting.com/client-side-code/components/collections#deleterow --- app/sprinkles/core/assets/userfrosting/js/uf-collection.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/sprinkles/core/assets/userfrosting/js/uf-collection.js b/app/sprinkles/core/assets/userfrosting/js/uf-collection.js index a2afc6eb..c9831f74 100644 --- a/app/sprinkles/core/assets/userfrosting/js/uf-collection.js +++ b/app/sprinkles/core/assets/userfrosting/js/uf-collection.js @@ -239,7 +239,7 @@ */ _deleteRow: function(row) { row.remove(); - this.$element.trigger('rowDelete.ufCollection'); + this.$element.trigger('rowDelete.ufCollection',row); }, /** * Add delete and touch bindings for a row, increment the internal row counter, and fire the rowAdd event From 7a0a8f4a91a5e780af81dc582aae14748e7bd56e Mon Sep 17 00:00:00 2001 From: alexweissman Date: Tue, 15 May 2018 12:03:11 -0400 Subject: [PATCH 09/10] changelog --- CHANGELOG.md | 4 +++- .../core/assets/userfrosting/js/uf-collection.js | 8 ++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 379823e4..419aeb29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). ## v4.1.18 -- Bakery setup wizard for SMTP config + separate SMTP setup in it's own command (#874) +- Bakery setup wizard for SMTP config + separate SMTP setup in it's own command (https://github.com/userfrosting/UserFrosting/issues/874) +- Update Italian translations (https://github.com/userfrosting/UserFrosting/pull/875) +- Return deleted `row` in `ufCollection` event (https://github.com/userfrosting/UserFrosting/pull/873) ## v4.1.17-alpha - Lock `gulp-uf-bundle-assets` at v2.28.0 until userfrosting/gulp-uf-bundle-assets#5 is resolved (see #859) diff --git a/app/sprinkles/core/assets/userfrosting/js/uf-collection.js b/app/sprinkles/core/assets/userfrosting/js/uf-collection.js index c9831f74..94ea416b 100644 --- a/app/sprinkles/core/assets/userfrosting/js/uf-collection.js +++ b/app/sprinkles/core/assets/userfrosting/js/uf-collection.js @@ -237,10 +237,10 @@ /** * Delete a row from the collection. */ - _deleteRow: function(row) { - row.remove(); - this.$element.trigger('rowDelete.ufCollection',row); - }, + _deleteRow: function(row) { + row.remove(); + this.$element.trigger('rowDelete.ufCollection', row); + }, /** * Add delete and touch bindings for a row, increment the internal row counter, and fire the rowAdd event */ From 4dda14f611b6de5764e05d22538f5c179b0a18f7 Mon Sep 17 00:00:00 2001 From: alexweissman Date: Tue, 15 May 2018 12:35:20 -0400 Subject: [PATCH 10/10] update readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d136dc8a..bbd4e301 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,7 @@ This project exists thanks to all the people who contribute. If you're intereste - Louis Charette (@lcharette) - French - Karuhut Komol (@popiazaza) - Thai - Pietro Marangon (@Pe46dro) - Italian +- Christian la Forgia (@optiroot) - Italian - Abdullah Seba (@abdullahseba) - Arabic - Bruno Silva (@brunomnsilva) - Portuguese - @BruceGui - Chinese