commit
0e7971d835
@ -5,7 +5,7 @@ imports:
|
||||
|
||||
framework:
|
||||
#esi: ~
|
||||
#translator: { fallback: "%locale%" }
|
||||
translator: { fallback: "%locale%" }
|
||||
secret: "%secret%"
|
||||
router:
|
||||
resource: "%kernel.root_dir%/config/routing.yml"
|
||||
@ -103,4 +103,4 @@ fos_rest:
|
||||
routing_loader:
|
||||
default_format: json
|
||||
|
||||
nelmio_api_doc: ~
|
||||
nelmio_api_doc: ~
|
||||
|
@ -1,25 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* wallabag, self hostable application allowing you to not miss any content anymore
|
||||
*
|
||||
* @category wallabag
|
||||
* @author Nicolas Lœuillet <nicolas@loeuillet.org>
|
||||
* @copyright 2013
|
||||
* @license http://opensource.org/licenses/MIT see COPYING file
|
||||
*/
|
||||
|
||||
define('ROOT', dirname(__FILE__) . '/../..');
|
||||
|
||||
require_once ROOT . '/vendor/autoload.php';
|
||||
|
||||
# system configuration
|
||||
require_once __DIR__ . '/config.inc.php';
|
||||
require_once __DIR__ . '/config.inc.default.php';
|
||||
|
||||
if (!ini_get('date.timezone') || !@date_default_timezone_set(ini_get('date.timezone'))) {
|
||||
date_default_timezone_set('UTC');
|
||||
}
|
||||
|
||||
if (defined('ERROR_REPORTING')) {
|
||||
error_reporting(ERROR_REPORTING);
|
||||
}
|
@ -6,7 +6,7 @@ parameters:
|
||||
database_name: symfony
|
||||
database_user: root
|
||||
database_password: ~
|
||||
database_path: "%kernel.root_dir%/../data/db/poche.sqlite"
|
||||
database_path: "%kernel.root_dir%/../data/db/wallabag.sqlite"
|
||||
|
||||
mailer_transport: smtp
|
||||
mailer_host: 127.0.0.1
|
||||
@ -37,5 +37,7 @@ parameters:
|
||||
export_mobi: true
|
||||
export_pdf: true
|
||||
|
||||
# List view
|
||||
items_on_page: 12
|
||||
# default user config
|
||||
items_on_page: 12
|
||||
theme: baggy
|
||||
language: en_US
|
||||
|
@ -3,6 +3,7 @@
|
||||
parameters:
|
||||
security.authentication.provider.dao.class: Wallabag\CoreBundle\Security\Authentication\Provider\WallabagAuthenticationProvider
|
||||
security.encoder.digest.class: Wallabag\CoreBundle\Security\Authentication\Encoder\WallabagPasswordEncoder
|
||||
security.validator.user_password.class: Wallabag\CoreBundle\Security\Validator\WallabagUserPasswordValidator
|
||||
|
||||
services:
|
||||
# service_name:
|
||||
|
@ -4,162 +4,308 @@ namespace Wallabag\CoreBundle\Command;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Input\ArrayInput;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Output\NullOutput;
|
||||
use Wallabag\CoreBundle\Entity\User;
|
||||
use Wallabag\CoreBundle\Entity\UsersConfig;
|
||||
use Wallabag\CoreBundle\Entity\Config;
|
||||
|
||||
class InstallCommand extends ContainerAwareCommand
|
||||
{
|
||||
/**
|
||||
* @var InputInterface
|
||||
*/
|
||||
protected $defaultInput;
|
||||
|
||||
/**
|
||||
* @var OutputInterface
|
||||
*/
|
||||
protected $defaultOutput;
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName('wallabag:install')
|
||||
->setDescription('Wallabag installer.')
|
||||
->addOption(
|
||||
'reset',
|
||||
null,
|
||||
InputOption::VALUE_NONE,
|
||||
'Reset current database'
|
||||
)
|
||||
;
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$output->writeln('<info>Installing Wallabag.</info>');
|
||||
$this->defaultInput = $input;
|
||||
$this->defaultOutput = $output;
|
||||
|
||||
$output->writeln('<info>Installing Wallabag...</info>');
|
||||
$output->writeln('');
|
||||
|
||||
$this
|
||||
->checkStep($output)
|
||||
->setupStep($input, $output)
|
||||
->checkRequirements()
|
||||
->setupDatabase()
|
||||
->setupAdmin()
|
||||
->setupAsset()
|
||||
;
|
||||
|
||||
$output->writeln('<info>Wallabag has been successfully installed.</info>');
|
||||
$output->writeln('<comment>Just execute `php app/console server:run` for using wallabag: http://localhost:8000</comment>');
|
||||
}
|
||||
|
||||
protected function checkStep(OutputInterface $output)
|
||||
protected function checkRequirements()
|
||||
{
|
||||
$output->writeln('<info>Checking system requirements.</info>');
|
||||
$this->defaultOutput->writeln('<info><comment>Step 1 of 4.</comment> Checking system requirements.</info>');
|
||||
|
||||
$fulfilled = true;
|
||||
|
||||
// @TODO: find a better way to check requirements
|
||||
$output->writeln('<comment>Check PCRE</comment>');
|
||||
$label = '<comment>PCRE</comment>';
|
||||
if (extension_loaded('pcre')) {
|
||||
$output->writeln(' <info>OK</info>');
|
||||
$status = '<info>OK!</info>';
|
||||
$help = '';
|
||||
} else {
|
||||
$fulfilled = false;
|
||||
$output->writeln(' <error>ERROR</error>');
|
||||
$output->writeln('<comment>You should enabled PCRE extension</comment>');
|
||||
$status = '<error>ERROR!</error>';
|
||||
$help = 'You should enabled PCRE extension';
|
||||
}
|
||||
$rows[] = array($label, $status, $help);
|
||||
|
||||
$output->writeln('<comment>Check DOM</comment>');
|
||||
$label = '<comment>DOM</comment>';
|
||||
if (extension_loaded('DOM')) {
|
||||
$output->writeln(' <info>OK</info>');
|
||||
$status = '<info>OK!</info>';
|
||||
$help = '';
|
||||
} else {
|
||||
$fulfilled = false;
|
||||
$output->writeln(' <error>ERROR</error>');
|
||||
$output->writeln('<comment>You should enabled DOM extension</comment>');
|
||||
$status = '<error>ERROR!</error>';
|
||||
$help = 'You should enabled DOM extension';
|
||||
}
|
||||
$rows[] = array($label, $status, $help);
|
||||
|
||||
$this->getHelper('table')
|
||||
->setHeaders(array('Checked', 'Status', 'Recommendation'))
|
||||
->setRows($rows)
|
||||
->render($this->defaultOutput);
|
||||
|
||||
if (!$fulfilled) {
|
||||
throw new RuntimeException('Some system requirements are not fulfilled. Please check output messages and fix them.');
|
||||
}
|
||||
|
||||
$output->writeln('');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function setupStep(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$output->writeln('<info>Setting up database.</info>');
|
||||
|
||||
$this->setupDatabase($input, $output);
|
||||
|
||||
// if ($this->getHelperSet()->get('dialog')->askConfirmation($output, '<question>Load fixtures (Y/N)?</question>', false)) {
|
||||
// $this->setupFixtures($input, $output);
|
||||
// }
|
||||
|
||||
$output->writeln('');
|
||||
$output->writeln('<info>Administration setup.</info>');
|
||||
|
||||
$this->setupAdmin($output);
|
||||
|
||||
$output->writeln('');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function setupDatabase(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
if ($this->getHelperSet()->get('dialog')->askConfirmation($output, '<question>Drop current database (Y/N)?</question>', true)) {
|
||||
$connection = $this->getContainer()->get('doctrine')->getConnection();
|
||||
$params = $connection->getParams();
|
||||
|
||||
$name = isset($params['path']) ? $params['path'] : (isset($params['dbname']) ? $params['dbname'] : false);
|
||||
unset($params['dbname']);
|
||||
|
||||
if (!isset($params['path'])) {
|
||||
$name = $connection->getDatabasePlatform()->quoteSingleIdentifier($name);
|
||||
}
|
||||
|
||||
$connection->getSchemaManager()->dropDatabase($name);
|
||||
throw new \RuntimeException('Some system requirements are not fulfilled. Please check output messages and fix them.');
|
||||
} else {
|
||||
throw new \Exception("Install setup stopped, database need to be dropped. Please backup your current one and re-launch the install command.");
|
||||
$this->defaultOutput->writeln('<info>Success! Your system can run Wallabag properly.</info>');
|
||||
}
|
||||
|
||||
$this
|
||||
->runCommand('doctrine:database:create', $input, $output)
|
||||
->runCommand('doctrine:schema:create', $input, $output)
|
||||
->runCommand('cache:clear', $input, $output)
|
||||
->runCommand('assets:install', $input, $output)
|
||||
->runCommand('assetic:dump', $input, $output)
|
||||
;
|
||||
$this->defaultOutput->writeln('');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function setupFixtures(InputInterface $input, OutputInterface $output)
|
||||
protected function setupDatabase()
|
||||
{
|
||||
$doctrineConfig = $this->getContainer()->get('doctrine.orm.entity_manager')->getConnection()->getConfiguration();
|
||||
$logger = $doctrineConfig->getSQLLogger();
|
||||
// speed up fixture load
|
||||
$doctrineConfig->setSQLLogger(null);
|
||||
$this->runCommand('doctrine:fixtures:load', $input, $output);
|
||||
$doctrineConfig->setSQLLogger($logger);
|
||||
$this->defaultOutput->writeln('<info><comment>Step 2 of 4.</comment> Setting up database.</info>');
|
||||
|
||||
// user want to reset everything? Don't care about what is already here
|
||||
if (true === $this->defaultInput->getOption('reset')) {
|
||||
$this->defaultOutput->writeln('Droping database, creating database and schema');
|
||||
|
||||
$this
|
||||
->runCommand('doctrine:database:drop', array('--force' => true))
|
||||
->runCommand('doctrine:database:create')
|
||||
->runCommand('doctrine:schema:create')
|
||||
;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
if (!$this->isDatabasePresent()) {
|
||||
$this->defaultOutput->writeln('Creating database and schema, clearing the cache');
|
||||
|
||||
$this
|
||||
->runCommand('doctrine:database:create')
|
||||
->runCommand('doctrine:schema:create')
|
||||
->runCommand('cache:clear')
|
||||
;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
$dialog = $this->getHelper('dialog');
|
||||
|
||||
if ($dialog->askConfirmation($this->defaultOutput, '<question>It appears that your database already exists. Would you like to reset it? (y/N)</question> ', false)) {
|
||||
$this->defaultOutput->writeln('Droping database, creating database and schema');
|
||||
|
||||
$this
|
||||
->runCommand('doctrine:database:drop', array('--force' => true))
|
||||
->runCommand('doctrine:database:create')
|
||||
->runCommand('doctrine:schema:create')
|
||||
;
|
||||
} elseif ($this->isSchemaPresent()) {
|
||||
if ($dialog->askConfirmation($this->defaultOutput, '<question>Seems like your database contains schema. Do you want to reset it? (y/N)</question> ', false)) {
|
||||
$this->defaultOutput->writeln('Droping schema and creating schema');
|
||||
|
||||
$this
|
||||
->runCommand('doctrine:schema:drop', array('--force' => true))
|
||||
->runCommand('doctrine:schema:create')
|
||||
;
|
||||
}
|
||||
} else {
|
||||
$this->defaultOutput->writeln('Creating schema');
|
||||
|
||||
$this
|
||||
->runCommand('doctrine:schema:create')
|
||||
;
|
||||
}
|
||||
|
||||
$this->defaultOutput->writeln('Clearing the cache');
|
||||
$this->runCommand('cache:clear');
|
||||
|
||||
/*
|
||||
if ($this->getHelperSet()->get('dialog')->askConfirmation($this->defaultOutput, '<question>Load fixtures (Y/N)?</question>', false)) {
|
||||
$doctrineConfig = $this->getContainer()->get('doctrine.orm.entity_manager')->getConnection()->getConfiguration();
|
||||
$logger = $doctrineConfig->getSQLLogger();
|
||||
// speed up fixture load
|
||||
$doctrineConfig->setSQLLogger(null);
|
||||
$this->runCommand('doctrine:fixtures:load');
|
||||
$doctrineConfig->setSQLLogger($logger);
|
||||
}
|
||||
*/
|
||||
|
||||
$this->defaultOutput->writeln('');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function setupAdmin(OutputInterface $output)
|
||||
protected function setupAdmin()
|
||||
{
|
||||
$this->defaultOutput->writeln('<info><comment>Step 3 of 4.</comment> Administration setup.</info>');
|
||||
|
||||
$dialog = $this->getHelperSet()->get('dialog');
|
||||
|
||||
if (false === $dialog->askConfirmation($this->defaultOutput, '<question>Would you like to create a new user ? (y/N)</question>', true)) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$em = $this->getContainer()->get('doctrine.orm.entity_manager');
|
||||
|
||||
$user = new User();
|
||||
$user->setUsername($dialog->ask($output, '<question>Username</question> <comment>(default: wallabag)</comment> :', 'wallabag'));
|
||||
$user->setPassword($dialog->ask($output, '<question>Password</question> <comment>(default: wallabag)</comment> :', 'wallabag'));
|
||||
$user->setEmail($dialog->ask($output, '<question>Email:</question>', ''));
|
||||
$user->setUsername($dialog->ask($this->defaultOutput, '<question>Username</question> <comment>(default: wallabag)</comment> :', 'wallabag'));
|
||||
$user->setPassword($dialog->ask($this->defaultOutput, '<question>Password</question> <comment>(default: wallabag)</comment> :', 'wallabag'));
|
||||
$user->setEmail($dialog->ask($this->defaultOutput, '<question>Email:</question>', ''));
|
||||
|
||||
$em->persist($user);
|
||||
|
||||
$pagerConfig = new UsersConfig();
|
||||
$pagerConfig->setUserId($user->getId());
|
||||
$pagerConfig->setName('pager');
|
||||
$pagerConfig->setValue(10);
|
||||
$config = new Config($user);
|
||||
$config->setTheme($this->getContainer()->getParameter('theme'));
|
||||
$config->setItemsPerPage($this->getContainer()->getParameter('items_on_page'));
|
||||
$config->setLanguage($this->getContainer()->getParameter('language'));
|
||||
|
||||
$em->persist($pagerConfig);
|
||||
|
||||
// $languageConfig = new LanguageConfig();
|
||||
// $languageConfig->setUserId($user->getId());
|
||||
// $languageConfig->setName('language');
|
||||
// $languageConfig->setValue('en_EN.UTF8');
|
||||
|
||||
// $em->persist($languageConfig);
|
||||
$em->persist($config);
|
||||
|
||||
$em->flush();
|
||||
}
|
||||
|
||||
protected function runCommand($command, InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$this
|
||||
->getApplication()
|
||||
->find($command)
|
||||
->run($input, $output)
|
||||
;
|
||||
$this->defaultOutput->writeln('');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function setupAsset()
|
||||
{
|
||||
$this->defaultOutput->writeln('<info><comment>Step 4 of 4.</comment> Installing assets.</info>');
|
||||
|
||||
$this
|
||||
->runCommand('assets:install')
|
||||
->runCommand('assetic:dump')
|
||||
;
|
||||
|
||||
$this->defaultOutput->writeln('');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run a command
|
||||
*
|
||||
* @param string $command
|
||||
* @param array $parameters Parameters to this command (usually 'force' => true)
|
||||
*/
|
||||
protected function runCommand($command, $parameters = array())
|
||||
{
|
||||
$parameters = array_merge(
|
||||
array('command' => $command),
|
||||
$parameters,
|
||||
array(
|
||||
'--no-debug' => true,
|
||||
'--env' => $this->defaultInput->getOption('env') ?: 'dev',
|
||||
)
|
||||
);
|
||||
|
||||
if ($this->defaultInput->getOption('no-interaction')) {
|
||||
$parameters = array_merge($parameters, array('--no-interaction' => true));
|
||||
}
|
||||
|
||||
$this->getApplication()->setAutoExit(false);
|
||||
$exitCode = $this->getApplication()->run(new ArrayInput($parameters), new NullOutput());
|
||||
|
||||
if (0 !== $exitCode) {
|
||||
$this->getApplication()->setAutoExit(true);
|
||||
|
||||
$errorMessage = sprintf('The command "%s" terminated with an error code: %u.', $command, $exitCode);
|
||||
$this->defaultOutput->writeln("<error>$errorMessage</error>");
|
||||
$exception = new \Exception($errorMessage, $exitCode);
|
||||
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
// PDO does not always close the connection after Doctrine commands.
|
||||
// See https://github.com/symfony/symfony/issues/11750.
|
||||
$this->getContainer()->get('doctrine')->getManager()->getConnection()->close();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the database already exists
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
private function isDatabasePresent()
|
||||
{
|
||||
$databaseName = $this->getContainer()->getParameter('database_name');
|
||||
|
||||
try {
|
||||
$schemaManager = $this->getContainer()->get('doctrine')->getManager()->getConnection()->getSchemaManager();
|
||||
} catch (\Exception $exception) {
|
||||
if (false !== strpos($exception->getMessage(), sprintf("Unknown database '%s'", $databaseName))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
// custom verification for sqlite, since `getListDatabasesSQL` doesn't work for sqlite
|
||||
if ('sqlite' == $schemaManager->getDatabasePlatform()->getName()) {
|
||||
$params = $this->getContainer()->get('doctrine.dbal.default_connection')->getParams();
|
||||
|
||||
if (isset($params['path']) && file_exists($params['path'])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return in_array($databaseName, $schemaManager->listDatabases());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the schema is already created
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
private function isSchemaPresent()
|
||||
{
|
||||
$schemaManager = $this->getContainer()->get('doctrine')->getManager()->getConnection()->getSchemaManager();
|
||||
|
||||
return $schemaManager->tablesExist(array('entry'));
|
||||
}
|
||||
}
|
||||
|
128
src/Wallabag/CoreBundle/Controller/ConfigController.php
Normal file
128
src/Wallabag/CoreBundle/Controller/ConfigController.php
Normal file
@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
namespace Wallabag\CoreBundle\Controller;
|
||||
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Wallabag\CoreBundle\Entity\Config;
|
||||
use Wallabag\CoreBundle\Entity\User;
|
||||
use Wallabag\CoreBundle\Form\Type\ConfigType;
|
||||
use Wallabag\CoreBundle\Form\Type\ChangePasswordType;
|
||||
use Wallabag\CoreBundle\Form\Type\UserType;
|
||||
use Wallabag\CoreBundle\Form\Type\NewUserType;
|
||||
|
||||
class ConfigController extends Controller
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
*
|
||||
* @Route("/config", name="config")
|
||||
*/
|
||||
public function indexAction(Request $request)
|
||||
{
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
$config = $this->getConfig();
|
||||
$user = $this->getUser();
|
||||
|
||||
// handle basic config detail
|
||||
$configForm = $this->createForm(new ConfigType(), $config);
|
||||
$configForm->handleRequest($request);
|
||||
|
||||
if ($configForm->isValid()) {
|
||||
$em->persist($config);
|
||||
$em->flush();
|
||||
|
||||
$this->get('session')->getFlashBag()->add(
|
||||
'notice',
|
||||
'Config saved'
|
||||
);
|
||||
|
||||
return $this->redirect($this->generateUrl('config'));
|
||||
}
|
||||
|
||||
// handle changing password
|
||||
$pwdForm = $this->createForm(new ChangePasswordType());
|
||||
$pwdForm->handleRequest($request);
|
||||
|
||||
if ($pwdForm->isValid()) {
|
||||
$user->setPassword($pwdForm->get('new_password')->getData());
|
||||
$em->persist($user);
|
||||
$em->flush();
|
||||
|
||||
$this->get('session')->getFlashBag()->add(
|
||||
'notice',
|
||||
'Password updated'
|
||||
);
|
||||
|
||||
return $this->redirect($this->generateUrl('config'));
|
||||
}
|
||||
|
||||
// handle changing user information
|
||||
$userForm = $this->createForm(new UserType(), $user);
|
||||
$userForm->handleRequest($request);
|
||||
|
||||
if ($userForm->isValid()) {
|
||||
$em->persist($user);
|
||||
$em->flush();
|
||||
|
||||
$this->get('session')->getFlashBag()->add(
|
||||
'notice',
|
||||
'Information updated'
|
||||
);
|
||||
|
||||
return $this->redirect($this->generateUrl('config'));
|
||||
}
|
||||
|
||||
// handle adding new user
|
||||
$newUser = new User();
|
||||
$newUserForm = $this->createForm(new NewUserType(), $newUser);
|
||||
$newUserForm->handleRequest($request);
|
||||
|
||||
if ($newUserForm->isValid()) {
|
||||
$em->persist($newUser);
|
||||
|
||||
$config = new Config($newUser);
|
||||
$config->setTheme($this->container->getParameter('theme'));
|
||||
$config->setItemsPerPage($this->container->getParameter('items_on_page'));
|
||||
$config->setLanguage($this->container->getParameter('language'));
|
||||
|
||||
$em->persist($config);
|
||||
|
||||
$em->flush();
|
||||
|
||||
$this->get('session')->getFlashBag()->add(
|
||||
'notice',
|
||||
sprintf('User "%s" added', $newUser->getUsername())
|
||||
);
|
||||
|
||||
return $this->redirect($this->generateUrl('config'));
|
||||
}
|
||||
|
||||
return $this->render('WallabagCoreBundle:Config:index.html.twig', array(
|
||||
'configForm' => $configForm->createView(),
|
||||
'pwdForm' => $pwdForm->createView(),
|
||||
'userForm' => $userForm->createView(),
|
||||
'newUserForm' => $newUserForm->createView(),
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve config for the current user.
|
||||
* If no config were found, create a new one.
|
||||
*
|
||||
* @return Wallabag\CoreBundle\Entity\Config
|
||||
*/
|
||||
private function getConfig()
|
||||
{
|
||||
$config = $this->getDoctrine()
|
||||
->getRepository('WallabagCoreBundle:Config')
|
||||
->findOneByUser($this->getUser());
|
||||
|
||||
if (!$config) {
|
||||
$config = new Config($this->getUser());
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
}
|
@ -7,7 +7,7 @@ use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Wallabag\CoreBundle\Entity\Entry;
|
||||
use Wallabag\CoreBundle\Service\Extractor;
|
||||
use Wallabag\CoreBundle\Helper\Url;
|
||||
use Wallabag\CoreBundle\Form\Type\EntryType;
|
||||
|
||||
class EntryController extends Controller
|
||||
{
|
||||
@ -22,10 +22,7 @@ class EntryController extends Controller
|
||||
{
|
||||
$entry = new Entry($this->getUser());
|
||||
|
||||
$form = $this->createFormBuilder($entry)
|
||||
->add('url', 'url')
|
||||
->add('save', 'submit')
|
||||
->getForm();
|
||||
$form = $this->createForm(new EntryType(), $entry);
|
||||
|
||||
$form->handleRequest($request);
|
||||
|
||||
|
45
src/Wallabag/CoreBundle/DataFixtures/ORM/LoadConfigData.php
Normal file
45
src/Wallabag/CoreBundle/DataFixtures/ORM/LoadConfigData.php
Normal file
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace Wallabag\CoreBundle\DataFixtures\ORM;
|
||||
|
||||
use Doctrine\Common\DataFixtures\AbstractFixture;
|
||||
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
|
||||
use Doctrine\Common\Persistence\ObjectManager;
|
||||
use Wallabag\CoreBundle\Entity\Config;
|
||||
|
||||
class LoadConfigData extends AbstractFixture implements OrderedFixtureInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function load(ObjectManager $manager)
|
||||
{
|
||||
$adminConfig = new Config($this->getReference('admin-user'));
|
||||
$adminConfig->setTheme('baggy');
|
||||
$adminConfig->setItemsPerPage(30);
|
||||
$adminConfig->setLanguage('en_US');
|
||||
|
||||
$manager->persist($adminConfig);
|
||||
|
||||
$this->addReference('admin-config', $adminConfig);
|
||||
|
||||
$bobConfig = new Config($this->getReference('bob-user'));
|
||||
$bobConfig->setTheme('default');
|
||||
$bobConfig->setItemsPerPage(10);
|
||||
$bobConfig->setLanguage('fr_FR');
|
||||
|
||||
$manager->persist($bobConfig);
|
||||
|
||||
$this->addReference('bob-config', $bobConfig);
|
||||
|
||||
$manager->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getOrder()
|
||||
{
|
||||
return 20;
|
||||
}
|
||||
}
|
@ -49,6 +49,6 @@ class LoadEntryData extends AbstractFixture implements OrderedFixtureInterface
|
||||
*/
|
||||
public function getOrder()
|
||||
{
|
||||
return 20;
|
||||
return 30;
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ class LoadUserData extends AbstractFixture implements OrderedFixtureInterface
|
||||
$userAdmin->setName('Big boss');
|
||||
$userAdmin->setEmail('bigboss@wallabag.org');
|
||||
$userAdmin->setUsername('admin');
|
||||
$userAdmin->setPassword('test');
|
||||
$userAdmin->setPassword('mypassword');
|
||||
|
||||
$manager->persist($userAdmin);
|
||||
|
||||
@ -28,7 +28,7 @@ class LoadUserData extends AbstractFixture implements OrderedFixtureInterface
|
||||
$bobUser->setName('Bobby');
|
||||
$bobUser->setEmail('bobby@wallabag.org');
|
||||
$bobUser->setUsername('bob');
|
||||
$bobUser->setPassword('test');
|
||||
$bobUser->setPassword('mypassword');
|
||||
|
||||
$manager->persist($bobUser);
|
||||
|
||||
|
@ -3,10 +3,12 @@
|
||||
namespace Wallabag\CoreBundle\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
/**
|
||||
* Config
|
||||
*
|
||||
* @ORM\Entity(repositoryClass="Wallabag\CoreBundle\Repository\ConfigRepository")
|
||||
* @ORM\Table(name="config")
|
||||
* @ORM\Entity
|
||||
*/
|
||||
@ -15,25 +17,50 @@ class Config
|
||||
/**
|
||||
* @var integer
|
||||
*
|
||||
* @ORM\Column(name="id", type="integer", nullable=false)
|
||||
* @ORM\Column(name="id", type="integer")
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue(strategy="IDENTITY")
|
||||
* @ORM\GeneratedValue(strategy="AUTO")
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="name", type="string", nullable=true)
|
||||
* @Assert\NotBlank()
|
||||
* @ORM\Column(name="theme", type="string", nullable=false)
|
||||
*/
|
||||
private $name;
|
||||
private $theme;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="value", type="blob", nullable=true)
|
||||
* @Assert\NotBlank()
|
||||
* @ORM\Column(name="items_per_page", type="integer", nullable=false)
|
||||
*/
|
||||
private $value;
|
||||
private $items_per_page;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @Assert\NotBlank()
|
||||
* @ORM\Column(name="language", type="string", nullable=false)
|
||||
*/
|
||||
private $language;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity="User", inversedBy="config")
|
||||
*/
|
||||
private $user;
|
||||
|
||||
/*
|
||||
* @param User $user
|
||||
*/
|
||||
public function __construct(User $user)
|
||||
{
|
||||
$this->user = $user;
|
||||
$this->items_per_page = 12;
|
||||
$this->language = 'en_US';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get id
|
||||
@ -46,48 +73,94 @@ class Config
|
||||
}
|
||||
|
||||
/**
|
||||
* Set name
|
||||
* Set theme
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $theme
|
||||
* @return Config
|
||||
*/
|
||||
public function setName($name)
|
||||
public function setTheme($theme)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->theme = $theme;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name
|
||||
* Get theme
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
public function getTheme()
|
||||
{
|
||||
return $this->name;
|
||||
return $this->theme;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set value
|
||||
* Set items_per_page
|
||||
*
|
||||
* @param string $value
|
||||
* @param integer $itemsPerPage
|
||||
* @return Config
|
||||
*/
|
||||
public function setValue($value)
|
||||
public function setItemsPerPage($itemsPerPage)
|
||||
{
|
||||
$this->value = $value;
|
||||
$this->items_per_page = $itemsPerPage;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get value
|
||||
* Get items_per_page
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getItemsPerPage()
|
||||
{
|
||||
return $this->items_per_page;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set language
|
||||
*
|
||||
* @param string $language
|
||||
* @return Config
|
||||
*/
|
||||
public function setLanguage($language)
|
||||
{
|
||||
$this->language = $language;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get language
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getValue()
|
||||
public function getLanguage()
|
||||
{
|
||||
return $this->value;
|
||||
return $this->language;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set user
|
||||
*
|
||||
* @param \Wallabag\CoreBundle\Entity\User $user
|
||||
* @return Config
|
||||
*/
|
||||
public function setUser(\Wallabag\CoreBundle\Entity\User $user = null)
|
||||
{
|
||||
$this->user = $user;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user
|
||||
*
|
||||
* @return \Wallabag\CoreBundle\Entity\User
|
||||
*/
|
||||
public function getUser()
|
||||
{
|
||||
return $this->user;
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Security\Core\User\UserInterface;
|
||||
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
/**
|
||||
* User
|
||||
@ -29,6 +30,11 @@ class User implements AdvancedUserInterface, \Serializable
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="username", type="text")
|
||||
* @Assert\NotBlank()
|
||||
* @Assert\Length(
|
||||
* min = "3",
|
||||
* max = "255"
|
||||
* )
|
||||
*/
|
||||
private $username;
|
||||
|
||||
@ -56,14 +62,16 @@ class User implements AdvancedUserInterface, \Serializable
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="email", type="text", nullable=true)
|
||||
* @ORM\Column(name="email", type="text", nullable=false)
|
||||
* @Assert\Email()
|
||||
* @Assert\NotBlank()
|
||||
*/
|
||||
private $email;
|
||||
|
||||
/**
|
||||
* @ORM\Column(name="is_active", type="boolean")
|
||||
* @ORM\Column(name="is_active", type="boolean", nullable=false)
|
||||
*/
|
||||
private $isActive;
|
||||
private $isActive = true;
|
||||
|
||||
/**
|
||||
* @var date
|
||||
@ -86,9 +94,8 @@ class User implements AdvancedUserInterface, \Serializable
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->isActive = true;
|
||||
$this->salt = md5(uniqid(null, true));
|
||||
$this->entries = new ArrayCollection();
|
||||
$this->salt = md5(uniqid(null, true));
|
||||
$this->entries = new ArrayCollection();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,123 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Wallabag\CoreBundle\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* UsersConfig
|
||||
*
|
||||
* @ORM\Table(name="users_config")
|
||||
* @ORM\Entity
|
||||
*/
|
||||
class UsersConfig
|
||||
{
|
||||
/**
|
||||
* @var integer
|
||||
*
|
||||
* @ORM\Column(name="id", type="integer", nullable=true)
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue(strategy="IDENTITY")
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="user_id", type="decimal", precision=10, scale=0, nullable=true)
|
||||
*/
|
||||
private $userId;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="name", type="text", nullable=true)
|
||||
*/
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="value", type="text", nullable=true)
|
||||
*/
|
||||
private $value;
|
||||
|
||||
/**
|
||||
* Get id
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set userId
|
||||
*
|
||||
* @param string $userId
|
||||
* @return UsersConfig
|
||||
*/
|
||||
public function setUserId($userId)
|
||||
{
|
||||
$this->userId = $userId;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get userId
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUserId()
|
||||
{
|
||||
return $this->userId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set name
|
||||
*
|
||||
* @param string $name
|
||||
* @return UsersConfig
|
||||
*/
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set value
|
||||
*
|
||||
* @param string $value
|
||||
* @return UsersConfig
|
||||
*/
|
||||
public function setValue($value)
|
||||
{
|
||||
$this->value = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getValue()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
}
|
39
src/Wallabag/CoreBundle/Form/Type/ChangePasswordType.php
Normal file
39
src/Wallabag/CoreBundle/Form/Type/ChangePasswordType.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
namespace Wallabag\CoreBundle\Form\Type;
|
||||
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Security\Core\Validator\Constraints\UserPassword;
|
||||
use Symfony\Component\Validator\Constraints;
|
||||
|
||||
class ChangePasswordType extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$builder
|
||||
->add('old_password', 'password', array(
|
||||
'constraints' => new UserPassword(array('message' => 'Wrong value for your current password')),
|
||||
))
|
||||
->add('new_password', 'repeated', array(
|
||||
'type' => 'password',
|
||||
'invalid_message' => 'The password fields must match.',
|
||||
'required' => true,
|
||||
'first_options' => array('label' => 'New password'),
|
||||
'second_options' => array('label' => 'Repeat new password'),
|
||||
'constraints' => array(
|
||||
new Constraints\Length(array(
|
||||
'min' => 8,
|
||||
'minMessage' => 'Password should by at least 8 chars long',
|
||||
)),
|
||||
new Constraints\NotBlank(),
|
||||
),
|
||||
))
|
||||
->add('save', 'submit')
|
||||
;
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return 'change_passwd';
|
||||
}
|
||||
}
|
41
src/Wallabag/CoreBundle/Form/Type/ConfigType.php
Normal file
41
src/Wallabag/CoreBundle/Form/Type/ConfigType.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
namespace Wallabag\CoreBundle\Form\Type;
|
||||
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
|
||||
|
||||
class ConfigType extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$builder
|
||||
->add('theme', 'choice', array(
|
||||
'choices' => array(
|
||||
'baggy' => 'Baggy',
|
||||
'courgette' => 'Courgette',
|
||||
'dark' => 'Dark',
|
||||
'default' => 'Default',
|
||||
'dmagenta' => 'Dmagenta',
|
||||
'solarized' => 'Solarized',
|
||||
'solarized_dark' => 'Solarized Dark',
|
||||
),
|
||||
))
|
||||
->add('items_per_page', 'text')
|
||||
->add('language')
|
||||
->add('save', 'submit')
|
||||
;
|
||||
}
|
||||
|
||||
public function setDefaultOptions(OptionsResolverInterface $resolver)
|
||||
{
|
||||
$resolver->setDefaults(array(
|
||||
'data_class' => 'Wallabag\CoreBundle\Entity\Config',
|
||||
));
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return 'config';
|
||||
}
|
||||
}
|
29
src/Wallabag/CoreBundle/Form/Type/EntryType.php
Normal file
29
src/Wallabag/CoreBundle/Form/Type/EntryType.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
namespace Wallabag\CoreBundle\Form\Type;
|
||||
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
|
||||
|
||||
class EntryType extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$builder
|
||||
->add('url', 'url')
|
||||
->add('save', 'submit')
|
||||
;
|
||||
}
|
||||
|
||||
public function setDefaultOptions(OptionsResolverInterface $resolver)
|
||||
{
|
||||
$resolver->setDefaults(array(
|
||||
'data_class' => 'Wallabag\CoreBundle\Entity\Entry',
|
||||
));
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return 'entry';
|
||||
}
|
||||
}
|
40
src/Wallabag/CoreBundle/Form/Type/NewUserType.php
Normal file
40
src/Wallabag/CoreBundle/Form/Type/NewUserType.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
namespace Wallabag\CoreBundle\Form\Type;
|
||||
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
|
||||
use Symfony\Component\Validator\Constraints;
|
||||
|
||||
class NewUserType extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$builder
|
||||
->add('username', 'text')
|
||||
->add('password', 'password', array(
|
||||
'constraints' => array(
|
||||
new Constraints\Length(array(
|
||||
'min' => 8,
|
||||
'minMessage' => 'Password should by at least 8 chars long',
|
||||
)),
|
||||
new Constraints\NotBlank(),
|
||||
),
|
||||
))
|
||||
->add('email', 'text')
|
||||
->add('save', 'submit')
|
||||
;
|
||||
}
|
||||
|
||||
public function setDefaultOptions(OptionsResolverInterface $resolver)
|
||||
{
|
||||
$resolver->setDefaults(array(
|
||||
'data_class' => 'Wallabag\CoreBundle\Entity\User',
|
||||
));
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return 'new_user';
|
||||
}
|
||||
}
|
31
src/Wallabag/CoreBundle/Form/Type/UserType.php
Normal file
31
src/Wallabag/CoreBundle/Form/Type/UserType.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
namespace Wallabag\CoreBundle\Form\Type;
|
||||
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
|
||||
|
||||
class UserType extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$builder
|
||||
->add('username', 'text')
|
||||
->add('name', 'text')
|
||||
->add('email', 'text')
|
||||
->add('save', 'submit')
|
||||
;
|
||||
}
|
||||
|
||||
public function setDefaultOptions(OptionsResolverInterface $resolver)
|
||||
{
|
||||
$resolver->setDefaults(array(
|
||||
'data_class' => 'Wallabag\CoreBundle\Entity\User',
|
||||
));
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return 'user';
|
||||
}
|
||||
}
|
9
src/Wallabag/CoreBundle/Repository/ConfigRepository.php
Normal file
9
src/Wallabag/CoreBundle/Repository/ConfigRepository.php
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Wallabag\CoreBundle\Repository;
|
||||
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
|
||||
class ConfigRepository extends EntityRepository
|
||||
{
|
||||
}
|
@ -1,3 +1,7 @@
|
||||
_wllbg:
|
||||
entry:
|
||||
resource: "@WallabagCoreBundle/Controller/EntryController.php"
|
||||
type: annotation
|
||||
|
||||
config:
|
||||
resource: "@WallabagCoreBundle/Controller/ConfigController.php"
|
||||
type: annotation
|
||||
|
137
src/Wallabag/CoreBundle/Resources/views/Config/index.html.twig
Normal file
137
src/Wallabag/CoreBundle/Resources/views/Config/index.html.twig
Normal file
@ -0,0 +1,137 @@
|
||||
{% extends "WallabagCoreBundle::layout.html.twig" %}
|
||||
|
||||
{% block title %}{% trans %}Config{% endtrans %}{% endblock %}
|
||||
|
||||
{% block menu %}
|
||||
{% include "WallabagCoreBundle::_menu.html.twig" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h2>{% trans %}Wallabag configuration{% endtrans %}</h2>
|
||||
|
||||
<form action="{{ path('config') }}" method="post" {{ form_enctype(configForm) }}>
|
||||
{{ form_errors(configForm) }}
|
||||
|
||||
<fieldset class="w500p inline">
|
||||
<div class="row">
|
||||
{{ form_label(configForm.theme) }}
|
||||
{{ form_errors(configForm.theme) }}
|
||||
{{ form_widget(configForm.theme) }}
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="w500p inline">
|
||||
<div class="row">
|
||||
{{ form_label(configForm.items_per_page) }}
|
||||
{{ form_errors(configForm.items_per_page) }}
|
||||
{{ form_widget(configForm.items_per_page) }}
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="w500p inline">
|
||||
<div class="row">
|
||||
{{ form_label(configForm.language) }}
|
||||
{{ form_errors(configForm.language) }}
|
||||
{{ form_widget(configForm.language) }}
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
{{ form_rest(configForm) }}
|
||||
</form>
|
||||
|
||||
<h2>{% trans %}User information{% endtrans %}</h2>
|
||||
|
||||
<form action="{{ path('config') }}" method="post" {{ form_enctype(userForm) }}>
|
||||
{{ form_errors(userForm) }}
|
||||
|
||||
<fieldset class="w500p inline">
|
||||
<div class="row">
|
||||
{{ form_label(userForm.username) }}
|
||||
{{ form_errors(userForm.username) }}
|
||||
{{ form_widget(userForm.username) }}
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="w500p inline">
|
||||
<div class="row">
|
||||
{{ form_label(userForm.name) }}
|
||||
{{ form_errors(userForm.name) }}
|
||||
{{ form_widget(userForm.name) }}
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="w500p inline">
|
||||
<div class="row">
|
||||
{{ form_label(userForm.email) }}
|
||||
{{ form_errors(userForm.email) }}
|
||||
{{ form_widget(userForm.email) }}
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
{{ form_rest(userForm) }}
|
||||
</form>
|
||||
|
||||
<h2>{% trans %}Change your password{% endtrans %}</h2>
|
||||
|
||||
<form action="{{ path('config') }}" method="post" {{ form_enctype(pwdForm) }}>
|
||||
{{ form_errors(pwdForm) }}
|
||||
|
||||
<fieldset class="w500p inline">
|
||||
<div class="row">
|
||||
{{ form_label(pwdForm.old_password) }}
|
||||
{{ form_errors(pwdForm.old_password) }}
|
||||
{{ form_widget(pwdForm.old_password) }}
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="w500p inline">
|
||||
<div class="row">
|
||||
{{ form_label(pwdForm.new_password.first) }}
|
||||
{{ form_errors(pwdForm.new_password.first) }}
|
||||
{{ form_widget(pwdForm.new_password.first) }}
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="w500p inline">
|
||||
<div class="row">
|
||||
{{ form_label(pwdForm.new_password.second) }}
|
||||
{{ form_errors(pwdForm.new_password.second) }}
|
||||
{{ form_widget(pwdForm.new_password.second) }}
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
{{ form_rest(pwdForm) }}
|
||||
</form>
|
||||
|
||||
<h2>{% trans %}Add a user{% endtrans %}</h2>
|
||||
|
||||
<form action="{{ path('config') }}" method="post" {{ form_enctype(newUserForm) }}>
|
||||
{{ form_errors(newUserForm) }}
|
||||
|
||||
<fieldset class="w500p inline">
|
||||
<div class="row">
|
||||
{{ form_label(newUserForm.username) }}
|
||||
{{ form_errors(newUserForm.username) }}
|
||||
{{ form_widget(newUserForm.username) }}
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="w500p inline">
|
||||
<div class="row">
|
||||
{{ form_label(newUserForm.password) }}
|
||||
{{ form_errors(newUserForm.password) }}
|
||||
{{ form_widget(newUserForm.password) }}
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="w500p inline">
|
||||
<div class="row">
|
||||
{{ form_label(newUserForm.email) }}
|
||||
{{ form_errors(newUserForm.email) }}
|
||||
{{ form_widget(newUserForm.email) }}
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
{{ form_rest(newUserForm) }}
|
||||
</form>
|
||||
{% endblock %}
|
@ -1,3 +1,3 @@
|
||||
<footer class="w600p center mt3 mb3 smaller txtright">
|
||||
<p>{% trans %}powered by{% endtrans %} <a href="http://wallabag.org">wallabag</a></p>
|
||||
</footer>
|
||||
<footer class="w600p center mt3 mb3 smaller txtright">
|
||||
<p>{% trans %}powered by{% endtrans %} <a href="http://wallabag.org">wallabag</a></p>
|
||||
</footer>
|
||||
|
@ -1,40 +1,40 @@
|
||||
<link rel="apple-touch-icon" type="image/png" href="{{ asset('themes/_global/img/appicon/apple-touch-icon-152.png') }}" sizes="152x152">
|
||||
<link rel="icon" type="image/png" href="{{ asset('themes/_global/img/appicon/apple-touch-icon-152.png') }}" sizes="152x152">
|
||||
<link rel="apple-touch-icon" type="image/png" href="{{ asset('themes/_global/img/appicon/apple-touch-icon-152.png') }}" sizes="152x152">
|
||||
<link rel="icon" type="image/png" href="{{ asset('themes/_global/img/appicon/apple-touch-icon-152.png') }}" sizes="152x152">
|
||||
|
||||
<link rel="apple-touch-icon" type="image/png" href="{{ asset('themes/_global/img/appicon/apple-touch-icon-144.png') }}" sizes="144x144">
|
||||
<link rel="icon" type="image/png" href="{{ asset('themes/_global/img/appicon/apple-touch-icon-144.png') }}" sizes="144x144">
|
||||
<link rel="apple-touch-icon" type="image/png" href="{{ asset('themes/_global/img/appicon/apple-touch-icon-144.png') }}" sizes="144x144">
|
||||
<link rel="icon" type="image/png" href="{{ asset('themes/_global/img/appicon/apple-touch-icon-144.png') }}" sizes="144x144">
|
||||
|
||||
<link rel="apple-touch-icon" type="image/png" href="{{ asset('themes/_global/img/appicon/apple-touch-icon-120.png') }}" sizes="120x120">
|
||||
<link rel="icon" type="image/png" href="{{ asset('themes/_global/img/appicon/apple-touch-icon-120.png') }}" sizes="120x120">
|
||||
<link rel="apple-touch-icon" type="image/png" href="{{ asset('themes/_global/img/appicon/apple-touch-icon-120.png') }}" sizes="120x120">
|
||||
<link rel="icon" type="image/png" href="{{ asset('themes/_global/img/appicon/apple-touch-icon-120.png') }}" sizes="120x120">
|
||||
|
||||
<link rel="apple-touch-icon" type="image/png" href="{{ asset('themes/_global/img/appicon/apple-touch-icon-114.png') }}" sizes="114x114">
|
||||
<link rel="icon" type="image/png" href="{{ asset('themes/_global/img/appicon/apple-touch-icon-114.png') }}" sizes="114x114">
|
||||
<link rel="apple-touch-icon" type="image/png" href="{{ asset('themes/_global/img/appicon/apple-touch-icon-114.png') }}" sizes="114x114">
|
||||
<link rel="icon" type="image/png" href="{{ asset('themes/_global/img/appicon/apple-touch-icon-114.png') }}" sizes="114x114">
|
||||
|
||||
<link rel="apple-touch-icon" type="image/png" href="{{ asset('themes/_global/img/appicon/apple-touch-icon-76.png') }}" sizes="76x76">
|
||||
<link rel="icon" type="image/png" href="{{ asset('themes/_global/img/appicon/apple-touch-icon-76.png') }}" sizes="76x76">
|
||||
<link rel="apple-touch-icon" type="image/png" href="{{ asset('themes/_global/img/appicon/apple-touch-icon-76.png') }}" sizes="76x76">
|
||||
<link rel="icon" type="image/png" href="{{ asset('themes/_global/img/appicon/apple-touch-icon-76.png') }}" sizes="76x76">
|
||||
|
||||
<link rel="apple-touch-icon" type="image/png" href="{{ asset('themes/_global/img/appicon/apple-touch-icon-72.png') }}" sizes="72x72">
|
||||
<link rel="icon" type="image/png" href="{{ asset('themes/_global/img/appicon/apple-touch-icon-72.png') }}" sizes="72x72">
|
||||
<link rel="apple-touch-icon" type="image/png" href="{{ asset('themes/_global/img/appicon/apple-touch-icon-72.png') }}" sizes="72x72">
|
||||
<link rel="icon" type="image/png" href="{{ asset('themes/_global/img/appicon/apple-touch-icon-72.png') }}" sizes="72x72">
|
||||
|
||||
<link rel="apple-touch-icon" type="image/png" href="{{ asset('themes/_global/img/appicon/apple-touch-icon-57.png') }}" sizes="57x57">
|
||||
<link rel="icon" type="image/png" href="{{ asset('themes/_global/img/appicon/apple-touch-icon-57.png') }}" sizes="57x57">
|
||||
<link rel="apple-touch-icon" type="image/png" href="{{ asset('themes/_global/img/appicon/apple-touch-icon-57.png') }}" sizes="57x57">
|
||||
<link rel="icon" type="image/png" href="{{ asset('themes/_global/img/appicon/apple-touch-icon-57.png') }}" sizes="57x57">
|
||||
|
||||
<link rel="apple-touch-icon" type="image/png" href="{{ asset('themes/_global/img/appicon/apple-touch-icon.png') }}">
|
||||
<link rel="icon" type="image/png" href="{{ asset('themes/_global/img/appicon/apple-touch-icon.png') }}">
|
||||
<link rel="apple-touch-icon" type="image/png" href="{{ asset('themes/_global/img/appicon/apple-touch-icon.png') }}">
|
||||
<link rel="icon" type="image/png" href="{{ asset('themes/_global/img/appicon/apple-touch-icon.png') }}">
|
||||
|
||||
<link rel="shortcut icon" type="image/x-icon" href="{{ asset('themes/_global/img/appicon/favicon.ico') }}">
|
||||
<link rel="shortcut icon" type="image/x-icon" href="{{ asset('themes/_global/img/appicon/favicon.ico') }}">
|
||||
|
||||
<link rel="stylesheet" href="{{ asset('themes/baggy/css/ratatouille.css') }}" media="all">
|
||||
<link rel="stylesheet" href="{{ asset('themes/baggy/css/font.css') }}" media="all">
|
||||
<link rel="stylesheet" href="{{ asset('themes/baggy/css/main.css') }}" media="all">
|
||||
<link rel="stylesheet" href="{{ asset('themes/baggy/css/messages.css') }}" media="all">
|
||||
<link rel="stylesheet" href="{{ asset('themes/baggy/css/print.css') }}" media="print">
|
||||
<link rel="stylesheet" href="{{ asset('themes/baggy/css/ratatouille.css') }}" media="all">
|
||||
<link rel="stylesheet" href="{{ asset('themes/baggy/css/font.css') }}" media="all">
|
||||
<link rel="stylesheet" href="{{ asset('themes/baggy/css/main.css') }}" media="all">
|
||||
<link rel="stylesheet" href="{{ asset('themes/baggy/css/messages.css') }}" media="all">
|
||||
<link rel="stylesheet" href="{{ asset('themes/baggy/css/print.css') }}" media="print">
|
||||
|
||||
<script src="{{ asset('themes/_global/js/jquery-2.0.3.min.js') }}"></script>
|
||||
<script src="{{ asset('themes/_global/js/autoClose.js') }}"></script>
|
||||
<script src="{{ asset('themes/baggy/js/jquery.cookie.js') }}"></script>
|
||||
<script src="{{ asset('themes/baggy/js/init.js') }}"></script>
|
||||
<script src="{{ asset('themes/_global/js/saveLink.js') }}"></script>
|
||||
<script src="{{ asset('themes/_global/js/popupForm.js') }}"></script>
|
||||
<script src="{{ asset('themes/baggy/js/closeMessage.js') }}"></script>
|
||||
<script src="{{ asset('bundles/wallabagcore/js/bookmarklet.js') }}"></script>
|
||||
<script src="{{ asset('themes/_global/js/jquery-2.0.3.min.js') }}"></script>
|
||||
<script src="{{ asset('themes/_global/js/autoClose.js') }}"></script>
|
||||
<script src="{{ asset('themes/baggy/js/jquery.cookie.js') }}"></script>
|
||||
<script src="{{ asset('themes/baggy/js/init.js') }}"></script>
|
||||
<script src="{{ asset('themes/_global/js/saveLink.js') }}"></script>
|
||||
<script src="{{ asset('themes/_global/js/popupForm.js') }}"></script>
|
||||
<script src="{{ asset('themes/baggy/js/closeMessage.js') }}"></script>
|
||||
<script src="{{ asset('bundles/wallabagcore/js/bookmarklet.js') }}"></script>
|
||||
|
@ -1,14 +1,14 @@
|
||||
<button id="menu" class="icon icon-menu desktopHide"><span>Menu</span></button>
|
||||
<ul id="links" class="links">
|
||||
<li><a href="{{ path('unread') }}">{% trans %}unread{% endtrans %}</a></li>
|
||||
<li><a href="{{ path('starred') }}">{% trans %}favorites{% endtrans %}</a></li>
|
||||
<li><a href="{{ path('archive') }}"}>{% trans %}archive{% endtrans %}</a></li>
|
||||
<li><a href="?view=tags">{% trans %}tags{% endtrans %}</a></li>
|
||||
<li><a href="{{ path('new_entry') }}">{% trans %}save a link{% endtrans %}</a></li>
|
||||
<li style="position: relative;"><a href="javascript: void(null);" id="search">{% trans %}search{% endtrans %}</a>
|
||||
{% include "WallabagCoreBundle::_search_form.html.twig" %}
|
||||
</li>
|
||||
<li><a href="?view=config">{% trans %}config{% endtrans %}</a></li>
|
||||
<li><a href={{ path('about') }}>{% trans %}about{% endtrans %}</a></li>
|
||||
<li><a class="icon icon-power" href="{{ path('logout') }}" title="{% trans %}logout{% endtrans %}">{% trans %}logout{% endtrans %}</a></li>
|
||||
</ul>
|
||||
<button id="menu" class="icon icon-menu desktopHide"><span>Menu</span></button>
|
||||
<ul id="links" class="links">
|
||||
<li><a href="{{ path('unread') }}">{% trans %}unread{% endtrans %}</a></li>
|
||||
<li><a href="{{ path('starred') }}">{% trans %}favorites{% endtrans %}</a></li>
|
||||
<li><a href="{{ path('archive') }}"}>{% trans %}archive{% endtrans %}</a></li>
|
||||
<li><a href="?view=tags">{% trans %}tags{% endtrans %}</a></li>
|
||||
<li><a href="{{ path('new_entry') }}">{% trans %}save a link{% endtrans %}</a></li>
|
||||
<li style="position: relative;"><a href="javascript: void(null);" id="search">{% trans %}search{% endtrans %}</a>
|
||||
{% include "WallabagCoreBundle::_search_form.html.twig" %}
|
||||
</li>
|
||||
<li><a href="{{ path('config') }}">{% trans %}config{% endtrans %}</a></li>
|
||||
<li><a href="{{ path('about') }}">{% trans %}about{% endtrans %}</a></li>
|
||||
<li><a class="icon icon-power" href="{{ path('logout') }}" title="{% trans %}logout{% endtrans %}">{% trans %}logout{% endtrans %}</a></li>
|
||||
</ul>
|
||||
|
@ -1,9 +1,9 @@
|
||||
<div id="search-form" class="messages info popup-form">
|
||||
<form method="get" action="index.php">
|
||||
<h2>{% trans %}Search{% endtrans %}</h2>
|
||||
<form method="get" action="index.php">
|
||||
<h2>{% trans %}Search{% endtrans %}</h2>
|
||||
<a href="javascript: void(null);" id="search-form-close" class="close-button--popup close-button">×</a>
|
||||
<input type="hidden" name="view" value="search"></input>
|
||||
<input required placeholder="{% trans %}Enter your search here{% endtrans %}" type="text" name="search" id="searchfield"><br>
|
||||
<input id="submit-search" type="submit" value="{% trans %}Search{% endtrans %}"></input>
|
||||
</form>
|
||||
</form>
|
||||
</div>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<header class="w600p center mbm">
|
||||
<h1>
|
||||
{% block logo %}<img width="100" height="100" src="{{ asset('themes/baggy/img/logo-w.png') }}" alt="wallabag logo" />{% endblock %}
|
||||
</h1>
|
||||
</header>
|
||||
<header class="w600p center mbm">
|
||||
<h1>
|
||||
{% block logo %}<img width="100" height="100" src="{{ asset('themes/baggy/img/logo-w.png') }}" alt="wallabag logo" />{% endblock %}
|
||||
</h1>
|
||||
</header>
|
||||
|
@ -41,10 +41,6 @@ class WallabagPasswordEncoder extends BasePasswordEncoder
|
||||
*/
|
||||
public function encodePassword($raw, $salt)
|
||||
{
|
||||
if (null === $this->username) {
|
||||
throw new \LogicException('We can not check the password without a username.');
|
||||
}
|
||||
|
||||
if ($this->isPasswordTooLong($raw)) {
|
||||
throw new BadCredentialsException('Invalid password.');
|
||||
}
|
||||
@ -71,6 +67,10 @@ class WallabagPasswordEncoder extends BasePasswordEncoder
|
||||
*/
|
||||
protected function mergePasswordAndSalt($password, $salt)
|
||||
{
|
||||
if (null === $this->username) {
|
||||
throw new \LogicException('We can not check the password without a username.');
|
||||
}
|
||||
|
||||
if (empty($salt)) {
|
||||
return $password;
|
||||
}
|
||||
|
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace Wallabag\CoreBundle\Security\Validator;
|
||||
|
||||
use Symfony\Component\Security\Core\User\UserInterface;
|
||||
use Symfony\Component\Security\Core\SecurityContextInterface;
|
||||
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
use Symfony\Component\Validator\ConstraintValidator;
|
||||
use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
|
||||
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
|
||||
use Symfony\Component\Security\Core\Validator\Constraints\UserPassword;
|
||||
|
||||
class WallabagUserPasswordValidator extends ConstraintValidator
|
||||
{
|
||||
private $securityContext;
|
||||
private $encoderFactory;
|
||||
|
||||
public function __construct(SecurityContextInterface $securityContext, EncoderFactoryInterface $encoderFactory)
|
||||
{
|
||||
$this->securityContext = $securityContext;
|
||||
$this->encoderFactory = $encoderFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validate($password, Constraint $constraint)
|
||||
{
|
||||
if (!$constraint instanceof UserPassword) {
|
||||
throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\UserPassword');
|
||||
}
|
||||
|
||||
$user = $this->securityContext->getToken()->getUser();
|
||||
|
||||
if (!$user instanceof UserInterface) {
|
||||
throw new ConstraintDefinitionException('The User object must implement the UserInterface interface.');
|
||||
}
|
||||
|
||||
// give username, it's used to hash the password
|
||||
$encoder = $this->encoderFactory->getEncoder($user);
|
||||
$encoder->setUsername($user->getUsername());
|
||||
|
||||
if (!$encoder->isPasswordValid($user->getPassword(), $password, $user->getSalt())) {
|
||||
$this->context->addViolation($constraint->message);
|
||||
}
|
||||
}
|
||||
}
|
274
src/Wallabag/CoreBundle/Tests/Command/InstallCommandTest.php
Normal file
274
src/Wallabag/CoreBundle/Tests/Command/InstallCommandTest.php
Normal file
@ -0,0 +1,274 @@
|
||||
<?php
|
||||
|
||||
namespace Wallabag\CoreBundle\Tests\Command;
|
||||
|
||||
use Wallabag\CoreBundle\Tests\WallabagTestCase;
|
||||
use Wallabag\CoreBundle\Command\InstallCommand;
|
||||
use Symfony\Bundle\FrameworkBundle\Console\Application;
|
||||
use Symfony\Component\Console\Tester\CommandTester;
|
||||
use Symfony\Component\Console\Input\ArrayInput;
|
||||
use Symfony\Component\Console\Output\NullOutput;
|
||||
use Doctrine\Bundle\DoctrineBundle\Command\DropDatabaseDoctrineCommand;
|
||||
use Doctrine\Bundle\DoctrineBundle\Command\CreateDatabaseDoctrineCommand;
|
||||
|
||||
class InstallCommandTest extends WallabagTestCase
|
||||
{
|
||||
public static function tearDownAfterClass()
|
||||
{
|
||||
$application = new Application(static::$kernel);
|
||||
$application->setAutoExit(false);
|
||||
|
||||
$code = $application->run(new ArrayInput(array(
|
||||
'command' => 'doctrine:fixtures:load',
|
||||
'--no-interaction' => true,
|
||||
'--env' => 'test',
|
||||
)), new NullOutput());
|
||||
}
|
||||
|
||||
public function testRunInstallCommand()
|
||||
{
|
||||
$this->container = static::$kernel->getContainer();
|
||||
|
||||
$application = new Application(static::$kernel);
|
||||
$application->add(new InstallCommand());
|
||||
|
||||
$command = $application->find('wallabag:install');
|
||||
|
||||
// We mock the DialogHelper
|
||||
$dialog = $this->getMockBuilder('Symfony\Component\Console\Helper\DialogHelper')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$dialog->expects($this->any())
|
||||
->method('ask')
|
||||
->will($this->returnValue('test'));
|
||||
$dialog->expects($this->any())
|
||||
->method('askConfirmation')
|
||||
->will($this->returnValue(true));
|
||||
|
||||
// We override the standard helper with our mock
|
||||
$command->getHelperSet()->set($dialog, 'dialog');
|
||||
|
||||
$tester = new CommandTester($command);
|
||||
$tester->execute(array(
|
||||
'command' => $command->getName(),
|
||||
));
|
||||
|
||||
$this->assertContains('Step 1 of 4. Checking system requirements.', $tester->getDisplay());
|
||||
$this->assertContains('Step 2 of 4. Setting up database.', $tester->getDisplay());
|
||||
$this->assertContains('Step 3 of 4. Administration setup.', $tester->getDisplay());
|
||||
$this->assertContains('Step 4 of 4. Installing assets.', $tester->getDisplay());
|
||||
}
|
||||
|
||||
public function testRunInstallCommandWithReset()
|
||||
{
|
||||
$this->container = static::$kernel->getContainer();
|
||||
|
||||
$application = new Application(static::$kernel);
|
||||
$application->add(new InstallCommand());
|
||||
|
||||
$command = $application->find('wallabag:install');
|
||||
|
||||
// We mock the DialogHelper
|
||||
$dialog = $this->getMockBuilder('Symfony\Component\Console\Helper\DialogHelper')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$dialog->expects($this->any())
|
||||
->method('ask')
|
||||
->will($this->returnValue('test'));
|
||||
$dialog->expects($this->any())
|
||||
->method('askConfirmation')
|
||||
->will($this->returnValue(true));
|
||||
|
||||
// We override the standard helper with our mock
|
||||
$command->getHelperSet()->set($dialog, 'dialog');
|
||||
|
||||
$tester = new CommandTester($command);
|
||||
$tester->execute(array(
|
||||
'command' => $command->getName(),
|
||||
'--reset' => true,
|
||||
));
|
||||
|
||||
$this->assertContains('Step 1 of 4. Checking system requirements.', $tester->getDisplay());
|
||||
$this->assertContains('Step 2 of 4. Setting up database.', $tester->getDisplay());
|
||||
$this->assertContains('Step 3 of 4. Administration setup.', $tester->getDisplay());
|
||||
$this->assertContains('Step 4 of 4. Installing assets.', $tester->getDisplay());
|
||||
|
||||
// we force to reset everything
|
||||
$this->assertContains('Droping database, creating database and schema', $tester->getDisplay());
|
||||
}
|
||||
|
||||
public function testRunInstallCommandWithDatabaseRemoved()
|
||||
{
|
||||
$this->container = static::$kernel->getContainer();
|
||||
|
||||
$application = new Application(static::$kernel);
|
||||
$application->add(new InstallCommand());
|
||||
$application->add(new DropDatabaseDoctrineCommand());
|
||||
|
||||
// drop database first, so the install command won't ask to reset things
|
||||
$command = new DropDatabaseDoctrineCommand();
|
||||
$command->setApplication($application);
|
||||
$command->run(new ArrayInput(array(
|
||||
'command' => 'doctrine:database:drop',
|
||||
'--force' => true,
|
||||
)), new NullOutput());
|
||||
|
||||
$command = $application->find('wallabag:install');
|
||||
|
||||
// We mock the DialogHelper
|
||||
$dialog = $this->getMockBuilder('Symfony\Component\Console\Helper\DialogHelper')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$dialog->expects($this->any())
|
||||
->method('ask')
|
||||
->will($this->returnValue('test'));
|
||||
$dialog->expects($this->any())
|
||||
->method('askConfirmation')
|
||||
->will($this->returnValue(true));
|
||||
|
||||
// We override the standard helper with our mock
|
||||
$command->getHelperSet()->set($dialog, 'dialog');
|
||||
|
||||
$tester = new CommandTester($command);
|
||||
$tester->execute(array(
|
||||
'command' => $command->getName(),
|
||||
));
|
||||
|
||||
$this->assertContains('Step 1 of 4. Checking system requirements.', $tester->getDisplay());
|
||||
$this->assertContains('Step 2 of 4. Setting up database.', $tester->getDisplay());
|
||||
$this->assertContains('Step 3 of 4. Administration setup.', $tester->getDisplay());
|
||||
$this->assertContains('Step 4 of 4. Installing assets.', $tester->getDisplay());
|
||||
|
||||
// the current database doesn't already exist
|
||||
$this->assertContains('Creating database and schema, clearing the cache', $tester->getDisplay());
|
||||
}
|
||||
|
||||
public function testRunInstallCommandChooseResetSchema()
|
||||
{
|
||||
$this->container = static::$kernel->getContainer();
|
||||
|
||||
$application = new Application(static::$kernel);
|
||||
$application->add(new InstallCommand());
|
||||
|
||||
$command = $application->find('wallabag:install');
|
||||
|
||||
// We mock the DialogHelper
|
||||
$dialog = $this->getMockBuilder('Symfony\Component\Console\Helper\DialogHelper')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$dialog->expects($this->exactly(3))
|
||||
->method('askConfirmation')
|
||||
->will($this->onConsecutiveCalls(
|
||||
false, // don't want to reset the entire database
|
||||
true, // do want to reset the schema
|
||||
false // don't want to create a new user
|
||||
));
|
||||
|
||||
// We override the standard helper with our mock
|
||||
$command->getHelperSet()->set($dialog, 'dialog');
|
||||
|
||||
$tester = new CommandTester($command);
|
||||
$tester->execute(array(
|
||||
'command' => $command->getName(),
|
||||
));
|
||||
|
||||
$this->assertContains('Step 1 of 4. Checking system requirements.', $tester->getDisplay());
|
||||
$this->assertContains('Step 2 of 4. Setting up database.', $tester->getDisplay());
|
||||
$this->assertContains('Step 3 of 4. Administration setup.', $tester->getDisplay());
|
||||
$this->assertContains('Step 4 of 4. Installing assets.', $tester->getDisplay());
|
||||
|
||||
$this->assertContains('Droping schema and creating schema', $tester->getDisplay());
|
||||
}
|
||||
|
||||
public function testRunInstallCommandChooseNothing()
|
||||
{
|
||||
$this->container = static::$kernel->getContainer();
|
||||
|
||||
$application = new Application(static::$kernel);
|
||||
$application->add(new InstallCommand());
|
||||
$application->add(new DropDatabaseDoctrineCommand());
|
||||
$application->add(new CreateDatabaseDoctrineCommand());
|
||||
|
||||
// drop database first, so the install command won't ask to reset things
|
||||
$command = new DropDatabaseDoctrineCommand();
|
||||
$command->setApplication($application);
|
||||
$command->run(new ArrayInput(array(
|
||||
'command' => 'doctrine:database:drop',
|
||||
'--force' => true,
|
||||
)), new NullOutput());
|
||||
|
||||
$this->container->get('doctrine')->getManager()->getConnection()->close();
|
||||
|
||||
$command = new CreateDatabaseDoctrineCommand();
|
||||
$command->setApplication($application);
|
||||
$command->run(new ArrayInput(array(
|
||||
'command' => 'doctrine:database:create',
|
||||
'--env' => 'test',
|
||||
)), new NullOutput());
|
||||
|
||||
$command = $application->find('wallabag:install');
|
||||
|
||||
// We mock the DialogHelper
|
||||
$dialog = $this->getMockBuilder('Symfony\Component\Console\Helper\DialogHelper')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$dialog->expects($this->exactly(2))
|
||||
->method('askConfirmation')
|
||||
->will($this->onConsecutiveCalls(
|
||||
false, // don't want to reset the entire database
|
||||
false // don't want to create a new user
|
||||
));
|
||||
|
||||
// We override the standard helper with our mock
|
||||
$command->getHelperSet()->set($dialog, 'dialog');
|
||||
|
||||
$tester = new CommandTester($command);
|
||||
$tester->execute(array(
|
||||
'command' => $command->getName(),
|
||||
));
|
||||
|
||||
$this->assertContains('Step 1 of 4. Checking system requirements.', $tester->getDisplay());
|
||||
$this->assertContains('Step 2 of 4. Setting up database.', $tester->getDisplay());
|
||||
$this->assertContains('Step 3 of 4. Administration setup.', $tester->getDisplay());
|
||||
$this->assertContains('Step 4 of 4. Installing assets.', $tester->getDisplay());
|
||||
|
||||
$this->assertContains('Creating schema', $tester->getDisplay());
|
||||
}
|
||||
|
||||
public function testRunInstallCommandNoInteraction()
|
||||
{
|
||||
$this->container = static::$kernel->getContainer();
|
||||
|
||||
$application = new Application(static::$kernel);
|
||||
$application->add(new InstallCommand());
|
||||
|
||||
$command = $application->find('wallabag:install');
|
||||
|
||||
// We mock the DialogHelper
|
||||
$dialog = $this->getMockBuilder('Symfony\Component\Console\Helper\DialogHelper')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$dialog->expects($this->any())
|
||||
->method('ask')
|
||||
->will($this->returnValue('test'));
|
||||
$dialog->expects($this->any())
|
||||
->method('askConfirmation')
|
||||
->will($this->returnValue(true));
|
||||
|
||||
// We override the standard helper with our mock
|
||||
$command->getHelperSet()->set($dialog, 'dialog');
|
||||
|
||||
$tester = new CommandTester($command);
|
||||
$tester->execute(array(
|
||||
'command' => $command->getName(),
|
||||
'--no-interaction' => true,
|
||||
));
|
||||
|
||||
$this->assertContains('Step 1 of 4. Checking system requirements.', $tester->getDisplay());
|
||||
$this->assertContains('Step 2 of 4. Setting up database.', $tester->getDisplay());
|
||||
$this->assertContains('Step 3 of 4. Administration setup.', $tester->getDisplay());
|
||||
$this->assertContains('Step 4 of 4. Installing assets.', $tester->getDisplay());
|
||||
}
|
||||
}
|
@ -0,0 +1,350 @@
|
||||
<?php
|
||||
|
||||
namespace Wallabag\CoreBundle\Tests\Controller;
|
||||
|
||||
use Wallabag\CoreBundle\Tests\WallabagTestCase;
|
||||
|
||||
class ConfigControllerTest extends WallabagTestCase
|
||||
{
|
||||
public function testLogin()
|
||||
{
|
||||
$client = $this->getClient();
|
||||
|
||||
$client->request('GET', '/new');
|
||||
|
||||
$this->assertEquals(302, $client->getResponse()->getStatusCode());
|
||||
$this->assertContains('login', $client->getResponse()->headers->get('location'));
|
||||
}
|
||||
|
||||
public function testIndex()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getClient();
|
||||
|
||||
$crawler = $client->request('GET', '/config');
|
||||
|
||||
$this->assertEquals(200, $client->getResponse()->getStatusCode());
|
||||
|
||||
$this->assertCount(1, $crawler->filter('button[id=config_save]'));
|
||||
$this->assertCount(1, $crawler->filter('button[id=change_passwd_save]'));
|
||||
$this->assertCount(1, $crawler->filter('button[id=user_save]'));
|
||||
}
|
||||
|
||||
public function testUpdate()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getClient();
|
||||
|
||||
$crawler = $client->request('GET', '/config');
|
||||
|
||||
$this->assertEquals(200, $client->getResponse()->getStatusCode());
|
||||
|
||||
$form = $crawler->filter('button[id=config_save]')->form();
|
||||
|
||||
$data = array(
|
||||
'config[theme]' => 'baggy',
|
||||
'config[items_per_page]' => '30',
|
||||
'config[language]' => 'fr_FR',
|
||||
);
|
||||
|
||||
$client->submit($form, $data);
|
||||
|
||||
$this->assertEquals(302, $client->getResponse()->getStatusCode());
|
||||
|
||||
$crawler = $client->followRedirect();
|
||||
|
||||
$this->assertGreaterThan(1, $alert = $crawler->filter('div.flash-notice')->extract(array('_text')));
|
||||
$this->assertContains('Config saved', $alert[0]);
|
||||
}
|
||||
|
||||
public function dataForUpdateFailed()
|
||||
{
|
||||
return array(
|
||||
array(array(
|
||||
'config[theme]' => 'baggy',
|
||||
'config[items_per_page]' => '',
|
||||
'config[language]' => 'fr_FR',
|
||||
)),
|
||||
array(array(
|
||||
'config[theme]' => 'baggy',
|
||||
'config[items_per_page]' => '12',
|
||||
'config[language]' => '',
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataForUpdateFailed
|
||||
*/
|
||||
public function testUpdateFailed($data)
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getClient();
|
||||
|
||||
$crawler = $client->request('GET', '/config');
|
||||
|
||||
$this->assertEquals(200, $client->getResponse()->getStatusCode());
|
||||
|
||||
$form = $crawler->filter('button[id=config_save]')->form();
|
||||
|
||||
$crawler = $client->submit($form, $data);
|
||||
|
||||
$this->assertEquals(200, $client->getResponse()->getStatusCode());
|
||||
|
||||
$this->assertGreaterThan(1, $alert = $crawler->filter('body')->extract(array('_text')));
|
||||
$this->assertContains('This value should not be blank', $alert[0]);
|
||||
}
|
||||
|
||||
public function dataForChangePasswordFailed()
|
||||
{
|
||||
return array(
|
||||
array(
|
||||
array(
|
||||
'change_passwd[old_password]' => 'baggy',
|
||||
'change_passwd[new_password][first]' => '',
|
||||
'change_passwd[new_password][second]' => '',
|
||||
),
|
||||
'Wrong value for your current password',
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'change_passwd[old_password]' => 'mypassword',
|
||||
'change_passwd[new_password][first]' => '',
|
||||
'change_passwd[new_password][second]' => '',
|
||||
),
|
||||
'This value should not be blank',
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'change_passwd[old_password]' => 'mypassword',
|
||||
'change_passwd[new_password][first]' => 'hop',
|
||||
'change_passwd[new_password][second]' => '',
|
||||
),
|
||||
'The password fields must match',
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'change_passwd[old_password]' => 'mypassword',
|
||||
'change_passwd[new_password][first]' => 'hop',
|
||||
'change_passwd[new_password][second]' => 'hop',
|
||||
),
|
||||
'Password should by at least',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataForChangePasswordFailed
|
||||
*/
|
||||
public function testChangePasswordFailed($data, $expectedMessage)
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getClient();
|
||||
|
||||
$crawler = $client->request('GET', '/config');
|
||||
|
||||
$this->assertEquals(200, $client->getResponse()->getStatusCode());
|
||||
|
||||
$form = $crawler->filter('button[id=change_passwd_save]')->form();
|
||||
|
||||
$crawler = $client->submit($form, $data);
|
||||
|
||||
$this->assertEquals(200, $client->getResponse()->getStatusCode());
|
||||
|
||||
$this->assertGreaterThan(1, $alert = $crawler->filter('body')->extract(array('_text')));
|
||||
$this->assertContains($expectedMessage, $alert[0]);
|
||||
}
|
||||
|
||||
public function testChangePassword()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getClient();
|
||||
|
||||
$crawler = $client->request('GET', '/config');
|
||||
|
||||
$this->assertEquals(200, $client->getResponse()->getStatusCode());
|
||||
|
||||
$form = $crawler->filter('button[id=change_passwd_save]')->form();
|
||||
|
||||
$data = array(
|
||||
'change_passwd[old_password]' => 'mypassword',
|
||||
'change_passwd[new_password][first]' => 'mypassword',
|
||||
'change_passwd[new_password][second]' => 'mypassword',
|
||||
);
|
||||
|
||||
$client->submit($form, $data);
|
||||
|
||||
$this->assertEquals(302, $client->getResponse()->getStatusCode());
|
||||
|
||||
$crawler = $client->followRedirect();
|
||||
|
||||
$this->assertGreaterThan(1, $alert = $crawler->filter('div.flash-notice')->extract(array('_text')));
|
||||
$this->assertContains('Password updated', $alert[0]);
|
||||
}
|
||||
|
||||
public function dataForUserFailed()
|
||||
{
|
||||
return array(
|
||||
array(
|
||||
array(
|
||||
'user[username]' => '',
|
||||
'user[name]' => '',
|
||||
'user[email]' => '',
|
||||
),
|
||||
'This value should not be blank.',
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'user[username]' => 'ad',
|
||||
'user[name]' => '',
|
||||
'user[email]' => '',
|
||||
),
|
||||
'This value is too short.',
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'user[username]' => 'admin',
|
||||
'user[name]' => '',
|
||||
'user[email]' => 'test',
|
||||
),
|
||||
'This value is not a valid email address.',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataForUserFailed
|
||||
*/
|
||||
public function testUserFailed($data, $expectedMessage)
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getClient();
|
||||
|
||||
$crawler = $client->request('GET', '/config');
|
||||
|
||||
$this->assertEquals(200, $client->getResponse()->getStatusCode());
|
||||
|
||||
$form = $crawler->filter('button[id=user_save]')->form();
|
||||
|
||||
$crawler = $client->submit($form, $data);
|
||||
|
||||
$this->assertEquals(200, $client->getResponse()->getStatusCode());
|
||||
|
||||
$this->assertGreaterThan(1, $alert = $crawler->filter('body')->extract(array('_text')));
|
||||
$this->assertContains($expectedMessage, $alert[0]);
|
||||
}
|
||||
|
||||
public function testUserUpdate()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getClient();
|
||||
|
||||
$crawler = $client->request('GET', '/config');
|
||||
|
||||
$this->assertEquals(200, $client->getResponse()->getStatusCode());
|
||||
|
||||
$form = $crawler->filter('button[id=user_save]')->form();
|
||||
|
||||
$data = array(
|
||||
'user[username]' => 'admin',
|
||||
'user[name]' => 'new name',
|
||||
'user[email]' => 'admin@wallabag.io',
|
||||
);
|
||||
|
||||
$client->submit($form, $data);
|
||||
|
||||
$this->assertEquals(302, $client->getResponse()->getStatusCode());
|
||||
|
||||
$crawler = $client->followRedirect();
|
||||
|
||||
$this->assertGreaterThan(1, $alert = $crawler->filter('div.flash-notice')->extract(array('_text')));
|
||||
$this->assertContains('Information updated', $alert[0]);
|
||||
}
|
||||
|
||||
public function dataForNewUserFailed()
|
||||
{
|
||||
return array(
|
||||
array(
|
||||
array(
|
||||
'new_user[username]' => '',
|
||||
'new_user[password]' => '',
|
||||
'new_user[email]' => '',
|
||||
),
|
||||
'This value should not be blank.',
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'new_user[username]' => 'ad',
|
||||
'new_user[password]' => '',
|
||||
'new_user[email]' => '',
|
||||
),
|
||||
'This value is too short.',
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'new_user[username]' => 'wallace',
|
||||
'new_user[password]' => '',
|
||||
'new_user[email]' => 'test',
|
||||
),
|
||||
'This value is not a valid email address.',
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'new_user[username]' => 'wallace',
|
||||
'new_user[password]' => 'admin',
|
||||
'new_user[email]' => 'wallace@wallace.me',
|
||||
),
|
||||
'Password should by at least',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataForNewUserFailed
|
||||
*/
|
||||
public function testNewUserFailed($data, $expectedMessage)
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getClient();
|
||||
|
||||
$crawler = $client->request('GET', '/config');
|
||||
|
||||
$this->assertEquals(200, $client->getResponse()->getStatusCode());
|
||||
|
||||
$form = $crawler->filter('button[id=new_user_save]')->form();
|
||||
|
||||
$crawler = $client->submit($form, $data);
|
||||
|
||||
$this->assertEquals(200, $client->getResponse()->getStatusCode());
|
||||
|
||||
$this->assertGreaterThan(1, $alert = $crawler->filter('body')->extract(array('_text')));
|
||||
$this->assertContains($expectedMessage, $alert[0]);
|
||||
}
|
||||
|
||||
public function testNewUserCreated()
|
||||
{
|
||||
$this->logInAs('admin');
|
||||
$client = $this->getClient();
|
||||
|
||||
$crawler = $client->request('GET', '/config');
|
||||
|
||||
$this->assertEquals(200, $client->getResponse()->getStatusCode());
|
||||
|
||||
$form = $crawler->filter('button[id=new_user_save]')->form();
|
||||
|
||||
$data = array(
|
||||
'new_user[username]' => 'wallace',
|
||||
'new_user[password]' => 'wallace1',
|
||||
'new_user[email]' => 'wallace@wallace.me',
|
||||
);
|
||||
|
||||
$client->submit($form, $data);
|
||||
|
||||
$this->assertEquals(302, $client->getResponse()->getStatusCode());
|
||||
|
||||
$crawler = $client->followRedirect();
|
||||
|
||||
$this->assertGreaterThan(1, $alert = $crawler->filter('div.flash-notice')->extract(array('_text')));
|
||||
$this->assertContains('User "wallace" added', $alert[0]);
|
||||
}
|
||||
}
|
@ -60,7 +60,7 @@ class EntryControllerTest extends WallabagTestCase
|
||||
$form = $crawler->filter('button[type=submit]')->form();
|
||||
|
||||
$data = array(
|
||||
'form[url]' => 'https://www.mailjet.com/blog/mailjet-zapier-integrations-made-easy/',
|
||||
'entry[url]' => 'https://www.mailjet.com/blog/mailjet-zapier-integrations-made-easy/',
|
||||
);
|
||||
|
||||
$client->submit($form, $data);
|
||||
|
@ -47,7 +47,7 @@ class WallabagRestControllerTest extends WallabagTestCase
|
||||
$client->request('GET', '/api/salts/admin.json');
|
||||
$salt = json_decode($client->getResponse()->getContent());
|
||||
|
||||
$headers = $this->generateHeaders('admin', 'test', $salt[0]);
|
||||
$headers = $this->generateHeaders('admin', 'mypassword', $salt[0]);
|
||||
|
||||
$entry = $client->getContainer()
|
||||
->get('doctrine.orm.entity_manager')
|
||||
@ -73,7 +73,7 @@ class WallabagRestControllerTest extends WallabagTestCase
|
||||
$client->request('GET', '/api/salts/admin.json');
|
||||
$salt = json_decode($client->getResponse()->getContent());
|
||||
|
||||
$headers = $this->generateHeaders('admin', 'test', $salt[0]);
|
||||
$headers = $this->generateHeaders('admin', 'mypassword', $salt[0]);
|
||||
|
||||
$entry = $client->getContainer()
|
||||
->get('doctrine.orm.entity_manager')
|
||||
@ -101,7 +101,7 @@ class WallabagRestControllerTest extends WallabagTestCase
|
||||
$client->request('GET', '/api/salts/admin.json');
|
||||
$salt = json_decode($client->getResponse()->getContent());
|
||||
|
||||
$headers = $this->generateHeaders('admin', 'test', $salt[0]);
|
||||
$headers = $this->generateHeaders('admin', 'mypassword', $salt[0]);
|
||||
|
||||
$client->request('GET', '/api/entries', array(), array(), $headers);
|
||||
|
||||
@ -125,7 +125,7 @@ class WallabagRestControllerTest extends WallabagTestCase
|
||||
$client->request('GET', '/api/salts/admin.json');
|
||||
$salt = json_decode($client->getResponse()->getContent());
|
||||
|
||||
$headers = $this->generateHeaders('admin', 'test', $salt[0]);
|
||||
$headers = $this->generateHeaders('admin', 'mypassword', $salt[0]);
|
||||
|
||||
$entry = $client->getContainer()
|
||||
->get('doctrine.orm.entity_manager')
|
||||
|
@ -4,7 +4,7 @@ namespace Wallabag\CoreBundle\Tests;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
||||
|
||||
class WallabagTestCase extends WebTestCase
|
||||
abstract class WallabagTestCase extends WebTestCase
|
||||
{
|
||||
private $client = null;
|
||||
|
||||
@ -24,7 +24,7 @@ class WallabagTestCase extends WebTestCase
|
||||
$form = $crawler->filter('button[type=submit]')->form();
|
||||
$data = array(
|
||||
'_username' => $username,
|
||||
'_password' => 'test',
|
||||
'_password' => 'mypassword',
|
||||
);
|
||||
|
||||
$this->client->submit($form, $data);
|
||||
|
Loading…
x
Reference in New Issue
Block a user