run: ## Run the wallabag built-in server
@php bin/console server:run --env=$(ENV)
-build: ## Run grunt
- @grunt
+build: ## Run webpack
+ @npm run build:$(ENV)
test: ## Launch wallabag testsuite
@ant prepare && bin/simple-phpunit -v
[![Gitter](https://badges.gitter.im/gitterHQ/gitter.svg)](https://gitter.im/wallabag/wallabag)
# What is wallabag?
-wallabag is a self hostable application allowing you to not miss any content anymore.
+wallabag is a self-hostable PHP application allowing you to not miss any content anymore.
Click, save and read it when you can. It extracts content so that you can read it when you have time.
More information on our website: [wallabag.org](https://wallabag.org).
export_json: Activar l'expòrt JSON
export_txt: Activar l'expòrt TXT
export_xml: Activar l'expòrt XML
-import_with_rabbitmq: Activar Enable RabbitMQ per importar de donadas de manièra asincròna
+import_with_rabbitmq: Activar RabbitMQ per importar de donadas de manièra asincròna
import_with_redis: Activar Redis per importar de donadas de manièra asincròna
shaarli_url: URL de Shaarli, se lo servici Shaarli es activat
share_diaspora: Activar lo partatge cap a Diaspora
share_public: Autorizar una URL publica pels articles
download_images_enabled: Telecargar los imatges en local
restricted_access: Activar l'autenticacion pels sites amb peatge
-# api_user_registration: Enable user to be registered using the API
+api_user_registration: Autorizar los utilizaires a se marcar amb l'API
namespace Wallabag\AnnotationBundle\Repository;
use Doctrine\ORM\EntityRepository;
+use Doctrine\ORM\QueryBuilder;
+use Wallabag\AnnotationBundle\Entity\Annotation;
/**
* AnnotationRepository.
use Nelmio\ApiDocBundle\Annotation\ApiDoc;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Wallabag\CoreBundle\Entity\Entry;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
use Wallabag\CoreBundle\Entity\Entry;
use Wallabag\UserBundle\Entity\User;
class CleanDuplicatesCommand extends ContainerAwareCommand
{
- /** @var OutputInterface */
- protected $output;
+ /** @var SymfonyStyle */
+ protected $io;
protected $duplicates = 0;
protected function execute(InputInterface $input, OutputInterface $output)
{
- $this->output = $output;
+ $this->io = new SymfonyStyle($input, $output);
$username = $input->getArgument('username');
$user = $this->getUser($username);
$this->cleanDuplicates($user);
} catch (NoResultException $e) {
- $output->writeln(sprintf('<error>User "%s" not found.</error>', $username));
+ $this->io->error(sprintf('User "%s" not found.', $username));
return 1;
}
+
+ $this->io->success('Finished cleaning.');
} else {
$users = $this->getContainer()->get('wallabag_user.user_repository')->findAll();
- $output->writeln(sprintf('Cleaning through %d user accounts', count($users)));
+ $this->io->text(sprintf('Cleaning through <info>%d</info> user accounts', count($users)));
foreach ($users as $user) {
- $output->writeln(sprintf('Processing user %s', $user->getUsername()));
+ $this->io->text(sprintf('Processing user <info>%s</info>', $user->getUsername()));
$this->cleanDuplicates($user);
}
- $output->writeln(sprintf('Finished cleaning. %d duplicates found in total', $this->duplicates));
+ $this->io->success(sprintf('Finished cleaning. %d duplicates found in total', $this->duplicates));
}
return 0;
$em = $this->getContainer()->get('doctrine.orm.entity_manager');
$repo = $this->getContainer()->get('wallabag_core.entry_repository');
- $entries = $repo->getAllEntriesIdAndUrl($user->getId());
+ $entries = $repo->findAllEntriesIdAndUrlByUserId($user->getId());
$duplicatesCount = 0;
$urls = [];
$this->duplicates += $duplicatesCount;
- $this->output->writeln(sprintf('Cleaned %d duplicates for user %s', $duplicatesCount, $user->getUserName()));
+ $this->io->text(sprintf('Cleaned <info>%d</info> duplicates for user <info>%s</info>', $duplicatesCount, $user->getUserName()));
}
private function similarUrl($url)
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
class ExportCommand extends ContainerAwareCommand
{
protected function execute(InputInterface $input, OutputInterface $output)
{
+ $io = new SymfonyStyle($input, $output);
+
try {
$user = $this->getContainer()->get('wallabag_user.user_repository')->findOneByUserName($input->getArgument('username'));
} catch (NoResultException $e) {
- $output->writeln(sprintf('<error>User "%s" not found.</error>', $input->getArgument('username')));
+ $io->error(sprintf('User "%s" not found.', $input->getArgument('username')));
return 1;
}
->getQuery()
->getResult();
- $output->write(sprintf('Exporting %d entrie(s) for user « <comment>%s</comment> »... ', count($entries), $user->getUserName()));
+ $io->text(sprintf('Exporting <info>%d</info> entrie(s) for user <info>%s</info>...', count($entries), $user->getUserName()));
$filePath = $input->getArgument('filepath');
->exportJsonData();
file_put_contents($filePath, $data);
} catch (\InvalidArgumentException $e) {
- $output->writeln(sprintf('<error>Error: "%s"</error>', $e->getMessage()));
+ $io->error(sprintf('Error: "%s"', $e->getMessage()));
return 1;
}
- $output->writeln('<info>Done.</info>');
+ $io->success('Done.');
return 0;
}
use FOS\UserBundle\Event\UserEvent;
use FOS\UserBundle\FOSUserEvents;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
-use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\BufferedOutput;
use Symfony\Component\Console\Output\OutputInterface;
-use Symfony\Component\Console\Question\ConfirmationQuestion;
use Symfony\Component\Console\Question\Question;
+use Symfony\Component\Console\Style\SymfonyStyle;
class InstallCommand extends ContainerAwareCommand
{
protected $defaultInput;
/**
- * @var OutputInterface
+ * @var SymfonyStyle
*/
- protected $defaultOutput;
+ protected $io;
/**
* @var array
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->defaultInput = $input;
- $this->defaultOutput = $output;
- $output->writeln('<info>Installing wallabag...</info>');
- $output->writeln('');
+ $this->io = new SymfonyStyle($input, $output);
+
+ $this->io->title('Wallabag installer');
$this
->checkRequirements()
->runMigrations()
;
- $output->writeln('<info>wallabag has been successfully installed.</info>');
- $output->writeln('<comment>Just execute `php bin/console server:run --env=prod` for using wallabag: http://localhost:8000</comment>');
+ $this->io->success('Wallabag has been successfully installed.');
+ $this->io->note('Just execute `php bin/console server:run --env=prod` for using wallabag: http://localhost:8000');
}
protected function checkRequirements()
{
- $this->defaultOutput->writeln('<info><comment>Step 1 of 5.</comment> Checking system requirements.</info>');
+ $this->io->section('Step 1 of 5: Checking system requirements.');
+
$doctrineManager = $this->getContainer()->get('doctrine')->getManager();
$rows = [];
$rows[] = [$label, $status, $help];
}
- $table = new Table($this->defaultOutput);
- $table
- ->setHeaders(['Checked', 'Status', 'Recommendation'])
- ->setRows($rows)
- ->render();
+ $this->io->table(['Checked', 'Status', 'Recommendation'], $rows);
if (!$fulfilled) {
throw new \RuntimeException('Some system requirements are not fulfilled. Please check output messages and fix them.');
}
- $this->defaultOutput->writeln('<info>Success! Your system can run wallabag properly.</info>');
-
- $this->defaultOutput->writeln('');
+ $this->io->success('Success! Your system can run wallabag properly.');
return $this;
}
protected function setupDatabase()
{
- $this->defaultOutput->writeln('<info><comment>Step 2 of 5.</comment> Setting up database.</info>');
+ $this->io->section('Step 2 of 5: Setting up database.');
// user want to reset everything? Don't care about what is already here
if (true === $this->defaultInput->getOption('reset')) {
- $this->defaultOutput->writeln('Dropping database, creating database and schema, clearing the cache');
+ $this->io->text('Dropping database, creating database and schema, clearing the cache');
$this
->runCommand('doctrine:database:drop', ['--force' => true])
->runCommand('cache:clear')
;
- $this->defaultOutput->writeln('');
+ $this->io->newLine();
return $this;
}
if (!$this->isDatabasePresent()) {
- $this->defaultOutput->writeln('Creating database and schema, clearing the cache');
+ $this->io->text('Creating database and schema, clearing the cache');
$this
->runCommand('doctrine:database:create')
->runCommand('cache:clear')
;
- $this->defaultOutput->writeln('');
+ $this->io->newLine();
return $this;
}
- $questionHelper = $this->getHelper('question');
- $question = new ConfirmationQuestion('It appears that your database already exists. Would you like to reset it? (y/N)', false);
-
- if ($questionHelper->ask($this->defaultInput, $this->defaultOutput, $question)) {
- $this->defaultOutput->writeln('Dropping database, creating database and schema');
+ if ($this->io->confirm('It appears that your database already exists. Would you like to reset it?', false)) {
+ $this->io->text('Dropping database, creating database and schema...');
$this
->runCommand('doctrine:database:drop', ['--force' => true])
->runCommand('doctrine:schema:create')
;
} elseif ($this->isSchemaPresent()) {
- $question = new ConfirmationQuestion('Seems like your database contains schema. Do you want to reset it? (y/N)', false);
- if ($questionHelper->ask($this->defaultInput, $this->defaultOutput, $question)) {
- $this->defaultOutput->writeln('Dropping schema and creating schema');
+ if ($this->io->confirm('Seems like your database contains schema. Do you want to reset it?', false)) {
+ $this->io->text('Dropping schema and creating schema...');
$this
->runCommand('doctrine:schema:drop', ['--force' => true])
;
}
} else {
- $this->defaultOutput->writeln('Creating schema');
+ $this->io->text('Creating schema...');
$this
->runCommand('doctrine:schema:create')
;
}
- $this->defaultOutput->writeln('Clearing the cache');
+ $this->io->text('Clearing the cache...');
$this->runCommand('cache:clear');
- $this->defaultOutput->writeln('');
+ $this->io->newLine();
+ $this->io->text('<info>Database successfully setup.</info>');
return $this;
}
protected function setupAdmin()
{
- $this->defaultOutput->writeln('<info><comment>Step 3 of 5.</comment> Administration setup.</info>');
-
- $questionHelper = $this->getHelperSet()->get('question');
- $question = new ConfirmationQuestion('Would you like to create a new admin user (recommended) ? (Y/n)', true);
+ $this->io->section('Step 3 of 5: Administration setup.');
- if (!$questionHelper->ask($this->defaultInput, $this->defaultOutput, $question)) {
+ if (!$this->io->confirm('Would you like to create a new admin user (recommended)?', true)) {
return $this;
}
$userManager = $this->getContainer()->get('fos_user.user_manager');
$user = $userManager->createUser();
- $question = new Question('Username (default: wallabag) :', 'wallabag');
- $user->setUsername($questionHelper->ask($this->defaultInput, $this->defaultOutput, $question));
+ $user->setUsername($this->io->ask('Username', 'wallabag'));
- $question = new Question('Password (default: wallabag) :', 'wallabag');
- $user->setPlainPassword($questionHelper->ask($this->defaultInput, $this->defaultOutput, $question));
+ $question = new Question('Password', 'wallabag');
+ $question->setHidden(true);
+ $user->setPlainPassword($this->io->askQuestion($question));
- $question = new Question('Email:', '');
- $user->setEmail($questionHelper->ask($this->defaultInput, $this->defaultOutput, $question));
+ $user->setEmail($this->io->ask('Email', ''));
$user->setEnabled(true);
$user->addRole('ROLE_SUPER_ADMIN');
$event = new UserEvent($user);
$this->getContainer()->get('event_dispatcher')->dispatch(FOSUserEvents::USER_CREATED, $event);
- $this->defaultOutput->writeln('');
+ $this->io->text('<info>Administration successfully setup.</info>');
return $this;
}
protected function setupConfig()
{
- $this->defaultOutput->writeln('<info><comment>Step 4 of 5.</comment> Config setup.</info>');
+ $this->io->section('Step 4 of 5: Config setup.');
$em = $this->getContainer()->get('doctrine.orm.entity_manager');
// cleanup before insert new stuff
$em->flush();
- $this->defaultOutput->writeln('');
+ $this->io->text('<info>Config successfully setup.</info>');
return $this;
}
protected function runMigrations()
{
- $this->defaultOutput->writeln('<info><comment>Step 5 of 5.</comment> Run migrations.</info>');
+ $this->io->section('Step 5 of 5: Run migrations.');
$this
->runCommand('doctrine:migrations:migrate', ['--no-interaction' => true]);
+ $this->io->text('<info>Migrations successfully executed.</info>');
+
return $this;
}
--- /dev/null
+<?php
+
+namespace Wallabag\CoreBundle\Command;
+
+use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
+
+class ListUserCommand extends ContainerAwareCommand
+{
+ protected function configure()
+ {
+ $this
+ ->setName('wallabag:user:list')
+ ->setDescription('List all users')
+ ->setHelp('This command list all existing users')
+ ->addArgument('search', InputArgument::OPTIONAL, 'Filter list by given search term')
+ ->addOption('limit', 'l', InputOption::VALUE_REQUIRED, 'Max number of displayed users', 100)
+ ;
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $io = new SymfonyStyle($input, $output);
+
+ $users = $this->getContainer()->get('wallabag_user.user_repository')
+ ->getQueryBuilderForSearch($input->getArgument('search'))
+ ->setMaxResults($input->getOption('limit'))
+ ->getQuery()
+ ->getResult();
+
+ $nbUsers = $this->getContainer()->get('wallabag_user.user_repository')
+ ->getSumUsers();
+
+ $rows = [];
+ foreach ($users as $user) {
+ $rows[] = [
+ $user->getUsername(),
+ $user->getEmail(),
+ $user->isEnabled() ? 'yes' : 'no',
+ $user->hasRole('ROLE_SUPER_ADMIN') || $user->hasRole('ROLE_ADMIN') ? 'yes' : 'no',
+ ];
+ }
+
+ $io->table(['username', 'email', 'is enabled?', 'is admin?'], $rows);
+
+ $io->success(
+ sprintf(
+ '%s/%s%s user(s) displayed.',
+ count($users),
+ $nbUsers,
+ $input->getArgument('search') === null ? '' : ' (filtered)'
+ )
+ );
+
+ return 0;
+ }
+}
--- /dev/null
+<?php
+
+namespace Wallabag\CoreBundle\Command;
+
+use Doctrine\ORM\NoResultException;
+use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
+use Wallabag\CoreBundle\Event\EntrySavedEvent;
+
+class ReloadEntryCommand extends ContainerAwareCommand
+{
+ protected function configure()
+ {
+ $this
+ ->setName('wallabag:entry:reload')
+ ->setDescription('Reload entries')
+ ->setHelp('This command reload entries')
+ ->addArgument('username', InputArgument::OPTIONAL, 'Reload entries only for the given user')
+ ;
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $io = new SymfonyStyle($input, $output);
+
+ $userId = null;
+ if ($username = $input->getArgument('username')) {
+ try {
+ $userId = $this->getContainer()
+ ->get('wallabag_user.user_repository')
+ ->findOneByUserName($username)
+ ->getId();
+ } catch (NoResultException $e) {
+ $io->error(sprintf('User "%s" not found.', $username));
+
+ return 1;
+ }
+ }
+
+ $entryRepository = $this->getContainer()->get('wallabag_core.entry_repository');
+ $entryIds = $entryRepository->findAllEntriesIdByUserId($userId);
+
+ $nbEntries = count($entryIds);
+ if (!$nbEntries) {
+ $io->success('No entry to reload.');
+
+ return 0;
+ }
+
+ $io->note(
+ sprintf(
+ "You're going to reload %s entries. Depending on the number of entry to reload, this could be a very long process.",
+ $nbEntries
+ )
+ );
+
+ if (!$io->confirm('Are you sure you want to proceed?')) {
+ return 0;
+ }
+
+ $progressBar = $io->createProgressBar($nbEntries);
+
+ $contentProxy = $this->getContainer()->get('wallabag_core.content_proxy');
+ $em = $this->getContainer()->get('doctrine')->getManager();
+ $dispatcher = $this->getContainer()->get('event_dispatcher');
+
+ $progressBar->start();
+ foreach ($entryIds as $entryId) {
+ $entry = $entryRepository->find($entryId);
+
+ $contentProxy->updateEntry($entry, $entry->getUrl());
+ $em->persist($entry);
+ $em->flush();
+
+ $dispatcher->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry));
+ $progressBar->advance();
+
+ $em->detach($entry);
+ }
+ $progressBar->finish();
+
+ $io->newLine(2);
+ $io->success('Done.');
+
+ return 0;
+ }
+}
private function showUser(User $user)
{
$this->io->listing([
- sprintf('Username : %s', $user->getUsername()),
- sprintf('Email : %s', $user->getEmail()),
- sprintf('Display name : %s', $user->getName()),
- sprintf('Creation date : %s', $user->getCreatedAt()->format('Y-m-d H:i:s')),
- sprintf('Last login : %s', $user->getLastLogin() !== null ? $user->getLastLogin()->format('Y-m-d H:i:s') : 'never'),
+ sprintf('Username: %s', $user->getUsername()),
+ sprintf('Email: %s', $user->getEmail()),
+ sprintf('Display name: %s', $user->getName()),
+ sprintf('Creation date: %s', $user->getCreatedAt()->format('Y-m-d H:i:s')),
+ sprintf('Last login: %s', $user->getLastLogin() !== null ? $user->getLastLogin()->format('Y-m-d H:i:s') : 'never'),
sprintf('2FA activated: %s', $user->isTwoFactorAuthentication() ? 'yes' : 'no'),
]);
}
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
class TagAllCommand extends ContainerAwareCommand
{
protected function execute(InputInterface $input, OutputInterface $output)
{
+ $io = new SymfonyStyle($input, $output);
+
try {
$user = $this->getUser($input->getArgument('username'));
} catch (NoResultException $e) {
- $output->writeln(sprintf('<error>User "%s" not found.</error>', $input->getArgument('username')));
+ $io->error(sprintf('User "%s" not found.', $input->getArgument('username')));
return 1;
}
$tagger = $this->getContainer()->get('wallabag_core.rule_based_tagger');
- $output->write(sprintf('Tagging entries for user « <comment>%s</comment> »... ', $user->getUserName()));
+ $io->text(sprintf('Tagging entries for user <info>%s</info>...', $user->getUserName()));
$entries = $tagger->tagAllForUser($user);
- $output->writeln('<info>Done.</info>');
- $output->write(sprintf('Persist entries ... ', $user->getUserName()));
+ $io->text('Persist entries... ');
$em = $this->getDoctrine()->getManager();
foreach ($entries as $entry) {
}
$em->flush();
- $output->writeln('<info>Done.</info>');
+ $io->success('Done.');
+
+ return 0;
}
/**
'entries' => $entries,
'currentPage' => $page,
'searchTerm' => $searchTerm,
+ 'isFiltered' => $form->isSubmitted(),
]
);
}
*/
public function showTagAction()
{
- $repository = $this->get('wallabag_core.entry_repository');
$tags = $this->get('wallabag_core.tag_repository')
- ->findAllTags($this->getUser()->getId());
-
- $flatTags = [];
-
- foreach ($tags as $tag) {
- $nbEntries = $repository->countAllEntriesByUserIdAndTagId(
- $this->getUser()->getId(),
- $tag->getId()
- );
-
- $flatTags[] = [
- 'id' => $tag->getId(),
- 'label' => $tag->getLabel(),
- 'slug' => $tag->getSlug(),
- 'nbEntries' => $nbEntries,
- ];
- }
+ ->findAllFlatTagsWithNbEntries($this->getUser()->getId());
return $this->render('WallabagCoreBundle:Tag:tags.html.twig', [
- 'tags' => $flatTags,
+ 'tags' => $tags,
]);
}
use Psr\Log\LoggerInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
use Wallabag\CoreBundle\Repository\SiteCredentialRepository;
+use Wallabag\UserBundle\Entity\User;
class GrabySiteConfigBuilder implements SiteConfigBuilder
{
private $logger;
/**
- * @var Wallabag\UserBundle\Entity\User|null
+ * @var User|null
*/
private $currentUser;
namespace Wallabag\CoreBundle\Helper;
-use JMS\Serializer;
use JMS\Serializer\SerializationContext;
use JMS\Serializer\SerializerBuilder;
use PHPePub\Core\EPub;
use PHPePub\Core\Structure\OPF\DublinCore;
use Symfony\Component\HttpFoundation\Response;
+use Wallabag\CoreBundle\Entity\Entry;
/**
* This class doesn't have unit test BUT it's fully covered by a functional test with ExportControllerTest.
*
* @param string $format
*
- * @return Serializer
+ * @return string
*/
private function prepareSerializingContent($format)
{
namespace Wallabag\CoreBundle\Repository;
use Doctrine\ORM\EntityRepository;
-use Doctrine\ORM\Query;
+use Doctrine\ORM\QueryBuilder;
use Pagerfanta\Adapter\DoctrineORMAdapter;
use Pagerfanta\Pagerfanta;
+use Wallabag\CoreBundle\Entity\Entry;
use Wallabag\CoreBundle\Entity\Tag;
class EntryRepository extends EntityRepository
*
* @param int $userId
* @param string $term
- * @param strint $currentRoute
+ * @param string $currentRoute
*
* @return QueryBuilder
*/
* @param int $since
* @param string $tags
*
- * @return array
+ * @return Pagerfanta
*/
public function findEntries($userId, $isArchived = null, $isStarred = null, $isPublic = null, $sort = 'created', $order = 'ASC', $since = 0, $tags = '')
{
*
* @param int $userId
*
- * @return Entry
+ * @return array
*/
public function findOneWithTags($userId)
{
return (int) $qb->getQuery()->getSingleScalarResult();
}
- /**
- * Count all entries for a tag and a user.
- *
- * @param int $userId
- * @param int $tagId
- *
- * @return int
- */
- public function countAllEntriesByUserIdAndTagId($userId, $tagId)
- {
- $qb = $this->createQueryBuilder('e')
- ->select('count(e.id)')
- ->leftJoin('e.tags', 't')
- ->where('e.user=:userId')->setParameter('userId', $userId)
- ->andWhere('t.id=:tagId')->setParameter('tagId', $tagId)
- ;
-
- return (int) $qb->getQuery()->getSingleScalarResult();
- }
-
/**
* Remove all entries for a user id.
* Used when a user want to reset all informations.
* Get id and url from all entries
* Used for the clean-duplicates command.
*/
- public function getAllEntriesIdAndUrl($userId)
+ public function findAllEntriesIdAndUrlByUserId($userId)
{
$qb = $this->createQueryBuilder('e')
->select('e.id, e.url')
return $qb->getQuery()->getArrayResult();
}
+ /**
+ * @param int $userId
+ *
+ * @return array
+ */
+ public function findAllEntriesIdByUserId($userId = null)
+ {
+ $qb = $this->createQueryBuilder('e')
+ ->select('e.id');
+
+ if (null !== $userId) {
+ $qb->where('e.user = :userid')->setParameter(':userid', $userId);
+ }
+
+ return $qb->getQuery()->getArrayResult();
+ }
+
/**
* Find all entries by url and owner.
*
namespace Wallabag\CoreBundle\Repository;
use Doctrine\ORM\EntityRepository;
+use Wallabag\CoreBundle\Entity\Tag;
class TagRepository extends EntityRepository
{
return $tags;
}
+ /**
+ * Find all tags (flat) per user with nb entries.
+ *
+ * @param int $userId
+ *
+ * @return array
+ */
+ public function findAllFlatTagsWithNbEntries($userId)
+ {
+ return $this->createQueryBuilder('t')
+ ->select('t.id, t.label, t.slug, count(e.id) as nbEntries')
+ ->distinct(true)
+ ->leftJoin('t.entries', 'e')
+ ->where('e.user = :userId')
+ ->groupBy('t.id')
+ ->orderBy('t.slug')
+ ->setParameter('userId', $userId)
+ ->getQuery()
+ ->getArrayResult();
+ }
+
/**
* Used only in test case to get a tag for our entry.
*
# filtered_tags: 'Filtered by tags:'
# filtered_search: 'Filtered by search:'
# untagged: 'Untagged entries'
+ # all: 'All entries'
list:
# number_on_the_page: '{0} There is no entry.|{1} There is one entry.|]1,Inf[ There are %count% entries.'
reading_time: 'estimeret læsetid'
filtered_tags: 'Gefiltert nach Tags:'
filtered_search: 'Gefiltert nach Suche:'
untagged: 'Nicht getaggte Einträge'
+ all: 'Alle Einträge'
list:
number_on_the_page: '{0} Es gibt keine Einträge.|{1} Es gibt einen Eintrag.|]1,Inf[ Es gibt %count% Einträge.'
reading_time: 'geschätzte Lesezeit'
filtered_tags: 'Filtered by tags:'
filtered_search: 'Filtered by search:'
untagged: 'Untagged entries'
+ all: 'All entries'
list:
number_on_the_page: '{0} There are no entries.|{1} There is one entry.|]1,Inf[ There are %count% entries.'
reading_time: 'estimated reading time'
filtered_tags: 'Filtrado por etiquetas:'
filtered_search: 'Filtrado por búsqueda:'
untagged: 'Artículos sin etiquetas'
+ all: "Todos los artículos"
list:
number_on_the_page: '{0} No hay artículos.|{1} Hay un artículo.|]1,Inf[ Hay %count% artículos.'
reading_time: 'tiempo estimado de lectura'
# filtered_tags: 'Filtered by tags:'
# filtered_search: 'Filtered by search:'
# untagged: 'Untagged entries'
+ # all: 'All entries'
list:
number_on_the_page: '{0} هیج مقالهای نیست.|{1} یک مقاله هست.|]1,Inf[ %count% مقاله هست.'
reading_time: 'زمان تخمینی برای خواندن'
filtered_tags: "Articles filtrés par tags :"
filtered_search: "Articles filtrés par recherche :"
untagged: "Article sans tag"
+ all: "Tous les articles"
list:
number_on_the_page: "{0} Il n’y a pas d’article.|{1} Il y a un article.|]1,Inf[ Il y a %count% articles."
reading_time: "durée de lecture"
filtered_tags: 'Filtrati per etichetta:'
filtered_search: 'Filtrati per ricerca:'
untagged: 'Articoli non etichettati'
+ all: 'Tutti gli articoli'
list:
number_on_the_page: "{0} Non ci sono contenuti.|{1} C'è un contenuto.|]1,Inf[ Ci sono %count% contenuti."
reading_time: 'tempo di lettura stimato'
login:
page_title: 'Benvenguda sus wallabag !'
keep_logged_in: 'Demorar connectat'
- forgot_password: 'Senhal doblidat ?'
+ forgot_password: 'Senhal oblidat ?'
submit: 'Se connectar'
register: 'Crear un compte'
username: "Nom d'utilizaire"
description: "Picatz vòstra adreça de corrièl çai-jos, vos mandarem las instruccions per reïnicializar vòstre senhal."
register:
page_title: 'Se crear un compte'
- go_to_account: 'Anar sus vòstre compte'
+ go_to_account: 'Anar a vòstre compte'
menu:
left:
all_articles: 'Totes los articles'
config: 'Configuracion'
tags: 'Etiquetas'
- internal_settings: 'Configuracion interna'
+ internal_settings: 'Configuracion intèrna'
import: 'Importar'
howto: 'Ajuda'
developer: 'Gestion dels clients API'
save_link: 'Enregistrar un novèl article'
back_to_unread: 'Tornar als articles pas legits'
users_management: 'Gestion dels utilizaires'
- # site_credentials: 'Site credentials'
+ site_credentials: 'Identificants del site'
top:
add_new_entry: 'Enregistrar un novèl article'
search: 'Cercar'
redirect_current_page: 'A la pagina actuala'
pocket_consumer_key_label: Clau d'autentificacion Pocket per importar las donadas
android_configuration: Configuratz vòstra aplicacion Android
- # android_instruction: "Touch here to prefill your Android application"
+ android_instruction: "Tocatz aquí per garnir las informacions de l'aplicacion Android"
help_theme: "wallabag es personalizable. Podètz causir vòstre tèma preferit aquí."
help_items_per_page: "Podètz cambiar lo nombre d'articles afichats per pagina."
help_reading_speed: "wallabag calcula lo temps de lectura per cada article. Podètz lo definir aquí, gràcias a aquesta lista, se sètz un legeire rapid o lent. wallabag tornarà calcular lo temps de lectura per cada article."
unread: 'Pas legits'
starred: 'Favorits'
archive: 'Legits'
- # all: 'All'
+ all: 'Totes'
rss_limit: "Nombre d'articles dins un flux RSS"
form_user:
- two_factor_description: "Activar l'autentificacion doble-factor vòl dire que recebretz un còdi per corrièl per cada novèla connexion pas aprovada."
+ two_factor_description: "Activar l'autentificacion en dos temps vòl dire que recebretz un còdi per corrièl per cada novèla connexion pas aprovada."
name_label: 'Nom'
email_label: 'Adreça de corrièl'
twoFactorAuthentication_label: 'Dobla autentificacion'
- help_twoFactorAuthentication: "S'avètz activat 2FA, cada còp que volètz vos connectar a wallabag, recebretz un còdi per corrièl."
+ help_twoFactorAuthentication: "S'avètz activat l'autentificacion en dos temps, cada còp que volètz vos connectar a wallabag, recebretz un còdi per corrièl."
delete:
title: Suprimir mon compte (Mèfi zòna perilhosa)
description: Se confirmatz la supression de vòstre compte, TOTES vòstres articles, TOTAS vòstras etiquetas, TOTAS vòstras anotacions e vòstre compte seràn suprimits per totjorn. E aquò es IRREVERSIBLE. Puèi seretz desconnectat.
filtered_tags: 'Articles filtrats per etiquetas :'
filtered_search: 'Articles filtrats per recèrca :'
untagged: 'Articles sens etiqueta'
+ all: 'Totes los articles'
list:
number_on_the_page: "{0} I a pas cap d'article.|{1} I a un article.|]1,Inf[ I a %count% articles."
reading_time: 'durada de lectura'
unread_label: 'Pas legits'
preview_picture_label: 'A un imatge'
preview_picture_help: 'Imatge'
- # is_public_label: 'Has a public link'
- # is_public_help: 'Public link'
+ is_public_label: 'Ten un ligam public'
+ is_public_help: 'Ligam public'
language_label: 'Lenga'
http_status_label: 'Estatut HTTP'
reading_time:
back_to_homepage: 'Tornar'
set_as_read: 'Marcar coma legit'
set_as_unread: 'Marcar coma pas legit'
- set_as_starred: 'Metre en favori'
+ set_as_starred: 'Metre en favorit'
view_original_article: 'Article original'
re_fetch_content: 'Tornar cargar lo contengut'
delete: 'Suprimir'
public:
shared_by_wallabag: "Aqueste article es estat partejat per <a href='%wallabag_instance%'>wallabag</a>"
confirm:
- # delete: "Are you sure you want to remove that article?"
- # delete_tag: "Are you sure you want to remove that tag from that article?"
+ delete: "Sètz segur de voler suprimir aqueste article ?"
+ delete_tag: "Sètz segur de voler levar aquesta etiqueta de l'article ?"
about:
page_title: 'A prepaus'
more: 'Mai…'
intro:
title: 'Benvenguda sus wallabag !'
- paragraph_1: "Anem vos guidar per far lo torn de la proprietat e vos presentar unas fonccionalitats que vos poirián interessar per vos apropriar aquesta aisina."
+ paragraph_1: "Anem vos guidar per far lo torn de la proprietat e vos presentar unas foncionalitats que vos poirián interessar per vos apropriar aquesta aisina."
paragraph_2: 'Seguètz-nos !'
configure:
title: "Configuratz l'aplicacion"
title: 'Primièrs passes'
description: "Ara wallabag es ben configurat, es lo moment d'archivar lo web. Podètz clicar sul signe + a man drecha amont per ajustar un ligam."
new_article: 'Ajustatz vòstre primièr article'
- unread_articles: 'E racaptatz-lo !'
+ unread_articles: 'E recaptatz-lo !'
migrate:
title: 'Migrar dempuèi un servici existent'
description: "Sètz un ancian utilizaire d'un servici existent ? Vos ajudarem a trapar vòstras donadas sus wallabag."
use_docker: 'Utilizar Docker per installar wallabag'
docs:
title: 'Documentacion complèta'
- description: "I a un fum de fonccionalitats dins wallabag. Esitetz pas a legir lo manual per las conéisser e aprendre a las utilizar."
+ description: "I a un fum de foncionalitats dins wallabag. Esitetz pas a legir lo manual per las conéisser e aprendre a las utilizar."
annotate: 'Anotar vòstre article'
export: 'Convertissètz vòstres articles en ePub o en PDF'
search_filters: "Aprenètz a utilizar lo motor de recèrca e los filtres per retrobar l'article que vos interèssa"
connect_to_pocket: 'Se connectar a Pocket e importar las donadas'
wallabag_v1:
page_title: 'Importar > Wallabag v1'
- description: 'Aquesta aisina importarà totas vòstras donadas de wallabag v1. Sus vòstre pagina de configuracion de wallabag v1, clicatz sus \"Export JSON\" dins la seccion \"Exportar vòstras donadas de wallabag\". Traparatz un fichièr \"wallabag-export-1-xxxx-xx-xx.json\".'
+ description: 'Aquesta aisina importarà totas vòstras donadas de wallabag v1. Sus vòstre pagina de configuracion de wallabag v1, clicatz sus \"Export JSON\" dins la seccion \"Exportar vòstras donadas de wallabag\". Traparetz un fichièr \"wallabag-export-1-xxxx-xx-xx.json\".'
how_to: "Causissètz lo fichièr de vòstra exportacion wallabag v1 e clicatz sul boton çai-jos per l'importar."
wallabag_v2:
page_title: 'Importar > Wallabag v2'
- description: "Aquesta aisina importarà totas vòstras donadas d'una instància mai de wallabag v2. Anatz dins totes vòstres articles, puèi, sus la barra laterala, clicatz sus \"JSON\". Traparatz un fichièr \"All articles.json\"."
+ description: "Aquesta aisina importarà totas vòstras donadas d'una instància mai de wallabag v2. Anatz dins totes vòstres articles, puèi, sus la barra laterala, clicatz sus \"JSON\". Traparetz un fichièr \"All articles.json\"."
readability:
page_title: 'Importar > Readability'
description: "Aquesta aisina importarà totas vòstres articles de Readability. Sus la pagina de l'aisina (https://www.readability.com/tools/), clicatz sus \"Export your data\" dins la seccion \"Data Export\". Recebretz un corrièl per telecargar un json (qu'acaba pas amb un .json de fach)."
download_images_warning: "Avètz activat lo telecargament de los imatges de vòstres articles. Combinat amb l'importacion classica, aquò pòt tardar un long moment (o benlèu fracassar). <strong>Recomandem fòrtament</strong> l'activacion de l'importacion asincròna per evitar las errors."
firefox:
page_title: 'Importar > Firefox'
- description: "Aquesta aisina importarà totas vòstres favorits de Firefox. Just go to your bookmarks (Ctrl+Maj+O), then into \"Import and backup\", choose \"Backup...\". You will obtain a .json file."
+ description: "Aquesta aisina importarà totas vòstres favorits de Firefox. Anatz simplament dins vòstres marcapaginas (Ctrl+Maj+O), puèi dins \"Impòrt e salvagarda\", causissètz \"Salvagardar...\". Auretz un fichièr .json."
how_to: "Mercés de causir lo fichièr de salvagarda e de clicar sul boton dejós per l'importar. Notatz que lo tractament pòt durar un moment ja que totes los articles an d'èsser recuperats."
chrome:
page_title: 'Importar > Chrome'
existing_clients:
title: 'Los clients existents'
field_id: 'ID Client'
- field_secret: 'Clé secreta'
+ field_secret: 'Clau secrèta'
field_uris: 'URLs de redireccion'
field_grant_types: 'Tipe de privilègi acordat'
no_client: 'Pas cap de client pel moment.'
remove:
- warn_message_1: 'Avètz la possibilitat de supriimr un client. Aquesta accion es IRREVERSIBLA !'
+ warn_message_1: 'Avètz la possibilitat de suprimir un client. Aquesta accion es IRREVERSIBLA !'
warn_message_2: "Se suprimissètz un client, totas las aplicacions que l'emplegan foncionaràn pas mai amb vòstre compte wallabag."
action: 'Suprimir aqueste client'
client:
placeholder: "Filtrar per nom d'utilizaire o corrièl"
site_credential:
- # page_title: Site credentials management
- # new_site_credential: Create a credential
- # edit_site_credential: Edit an existing credential
- # description: "Here you can manage all credentials for sites which required them (create, edit and delete), like a paywall, an authentication, etc."
+ page_title: Gestion dels identificants
+ new_site_credential: Crear un identificant
+ edit_site_credential: Modificar un identificant
+ description: "Aquí podètz gerir vòstres identificants pels sites que los demandan (ne crear, ne modifiar, ne suprimir) coma los sites a peatge, etc."
list:
actions: 'Accions'
edit_action: 'Modificar'
yes: 'Òc'
no: 'Non'
- # create_new_one: Create a new credential
+ create_new_one: Crear un novèl identificant
form:
- # username_label: 'Username'
- # host_label: 'Host'
- # password_label: 'Password'
+ username_label: "Nom d'utilizaire"
+ host_label: 'Òste'
+ password_label: 'Senhal'
save: 'Enregistrar'
delete: 'Suprimir'
delete_confirm: 'Sètz segur ?'
notice:
config_saved: 'Los paramètres son ben estats meses a jorn.'
password_updated: 'Vòstre senhal es ben estat mes a jorn'
- password_not_updated_demo: "En demostration, podètz pas cambiar lo senhal d'aqueste utilizaire."
+ password_not_updated_demo: "En demostracion, podètz pas cambiar lo senhal d'aqueste utilizaire."
user_updated: 'Vòstres informacions personnelas son ben estadas mesas a jorn'
rss_updated: 'La configuracion dels fluxes RSS es ben estada mesa a jorn'
tagging_rules_updated: 'Règlas misa a jorn'
archived_reset: Articles archivat suprimits
entry:
notice:
- entry_already_saved: 'Article ja salvargardat lo %date%'
+ entry_already_saved: 'Article ja salvagardat lo %date%'
entry_saved: 'Article enregistrat'
entry_saved_failed: 'Article salvat mai fracàs de la recuperacion del contengut'
entry_updated: 'Article mes a jorn'
import:
notice:
failed: "L'importacion a fracassat, mercés de tornar ensajar."
- failed_on_file: "Errorr pendent du tractament de l'import. Mercés de verificar vòstre fichièr."
- summary: "Rapòrt d'import: %imported% importats, %skipped% ja presents."
- summary_with_queue: "Rapòrt d'import : %queued% en espèra de tractament."
+ failed_on_file: "Error en tractar l'impòrt. Mercés de verificar vòstre fichièr."
+ summary: "Rapòrt d'impòrt: %imported% importats, %skipped% ja presents."
+ summary_with_queue: "Rapòrt d'impòrt : %queued% en espèra de tractament."
error:
redis_enabled_not_installed: "Redis es capable d'importar de manièra asincròna mai sembla que <u>podèm pas nos conectar amb el</u>. Mercés de verificar la configuracion de Redis."
rabbit_enabled_not_installed: "RabbitMQ es capable d'importar de manièra asincròna mai sembla que <u>podèm pas nos conectar amb el</u>. Mercés de verificar la configuracion de RabbitMQ."
deleted: 'Utilizaire "%username%" suprimit'
site_credential:
notice:
- # added: 'Site credential for "%host%" added'
- # updated: 'Site credential for "%host%" updated'
- # deleted: 'Site credential for "%host%" deleted'
+ added: 'Identificant per "%host%" ajustat'
+ updated: 'Identificant per "%host%" mes a jorn'
+ deleted: 'Identificant per "%host%" suprimit'
save_link: 'Zapisz link'
back_to_unread: 'Powrót do nieprzeczytanych artykułów'
users_management: 'Zarządzanie użytkownikami'
- # site_credentials: 'Site credentials'
+ site_credentials: 'Poświadczenia strony'
top:
add_new_entry: 'Dodaj nowy wpis'
search: 'Szukaj'
unread: 'Nieprzeczytane'
starred: 'Oznaczone gwiazdką'
archive: 'Archiwum'
- # all: 'All'
+ all: 'Wszystkie'
rss_limit: 'Link do RSS'
form_user:
two_factor_description: "Włączenie autoryzacji dwuetapowej oznacza, że będziesz otrzymywał maile z kodem przy każdym nowym, niezaufanym połączeniu"
filtered_tags: 'Filtrowane po tagach:'
filtered_search: 'Filtrowanie po wyszukiwaniu:'
untagged: 'Odtaguj wpisy'
+ all: 'Wszystkie przedmioty'
list:
number_on_the_page: '{0} Nie ma wpisów.|{1} Jest jeden wpis.|]1,Inf[ Są %count% wpisy.'
reading_time: 'szacunkowy czas czytania'
placeholder: Filtruj po nazwie użytkownika lub adresie e-mail
site_credential:
- # page_title: Site credentials management
- # new_site_credential: Create a credential
- # edit_site_credential: Edit an existing credential
- # description: "Here you can manage all credentials for sites which required them (create, edit and delete), like a paywall, an authentication, etc."
+ page_title: Zarządzanie poświadczeniami strony
+ new_site_credential: Stwórz nowe poświadczenie
+ edit_site_credential: Edytuj istniejące poświadczenie
+ description: "Tutaj możesz zarządzać wszystkim poświadczeniami wymaganymi przez strony (stwórz, edytuj i usuń ), takie jak paywall, autentykacja, itp."
list:
actions: Akcje
edit_action: Edytuj
yes: Tak
no: Nie
- # create_new_one: Create a new credential
+ create_new_one: Stwórz nowe poświadczenie
form:
- # username_label: 'Username'
- # host_label: 'Host'
- # password_label: 'Password'
+ username_label: 'Nazwa użytkownika'
+ host_label: 'Host'
+ password_label: 'Hasło'
save: Zapisz
delete: Usuń
delete_confirm: Jesteś pewien?
deleted: 'Użytkownik "%username%" usunięty'
site_credential:
notice:
- # added: 'Site credential for "%host%" added'
- # updated: 'Site credential for "%host%" updated'
- # deleted: 'Site credential for "%host%" deleted'
+ added: 'Poświadczenie dla "%host%" dodane'
+ updated: 'Poświadczenie dla "%host%" zaktualizowane'
+ deleted: 'Poświadczenie dla "%host%" usuniętę'
filtered_tags: 'Filtrar por tags:'
# filtered_search: 'Filtered by search:'
untagged: 'Entradas sem tags'
+ # all: 'All entries'
list:
number_on_the_page: '{0} Não existem entradas.|{1} Existe uma entrada.|]1,Inf[ Existem %count% entradas.'
reading_time: 'tempo estimado de leitura'
# filtered_tags: 'Filtered by tags:'
# filtered_search: 'Filtered by search:'
# untagged: 'Untagged entries'
+ # all: 'All entries'
list:
# number_on_the_page: '{0} There is no entry.|{1} There is one entry.|]1,Inf[ There are %count% entries.'
reading_time: 'timp estimat de citire'
# filtered_tags: 'Filtered by tags:'
# filtered_search: 'Filtered by search:'
# untagged: 'Untagged entries'
+ # all: 'All entries'
list:
number_on_the_page: '{0} Herhangi bir makale yok.|{1} Burada bir adet makale var.|]1,Inf[ Burada %count% adet makale var.'
reading_time: 'tahmini okuma süresi'
{% if craue_setting('share_unmark') %}<li><a href="{{ craue_setting('unmark_url') }}/mark/add?url={{ entry.url|url_encode }}&title={{entry.title|url_encode}}&v=6" target="_blank" class="tool unmark icon-image icon-image--unmark" title="unmark"><span>unmark.it</span></a></li>{% endif %}
{% if craue_setting('carrot') %}<li><a href="https://secure.carrot.org/GiveAndGetBack.do?url={{ entry.url|url_encode }}&title={{ entry.title|url_encode }}" class="tool carrot icon-image icon-image--carrot" target="_blank" title="carrot"><span>Carrot</span></a></li>{% endif %}
{% if craue_setting('show_printlink') %}<li><a title="{{ 'entry.view.left_menu.print'|trans }}" class="tool icon icon-print" href="javascript: window.print();"><span>{{ 'entry.view.left_menu.print'|trans }}</span></a></li>{% endif %}
- {% if craue_setting('export_epub') %}<li><a href="?epub&method=id&value={{ entry.id }}" title="Generate ePub file">EPUB</a></li>{% endif %}
- {% if craue_setting('export_mobi') %}<li><a href="?mobi&method=id&value={{ entry.id }}" title="Generate Mobi file">MOBI</a></li>{% endif %}
- {% if craue_setting('export_pdf') %}<li><a href="?pdf&method=id&value={{ entry.id }}" title="Generate PDF file">PDF</a></li>{% endif %}
+ {% if craue_setting('export_epub') %}<li><a href="{{ path('export_entry', { 'id': entry.id, 'format': 'epub' }) }}" title="Generate ePub file">EPUB</a></li>{% endif %}
+ {% if craue_setting('export_mobi') %}<li><a href="{{ path('export_entry', { 'id': entry.id, 'format': 'mobi' }) }}" title="Generate Mobi file">MOBI</a></li>{% endif %}
+ {% if craue_setting('export_pdf') %}<li><a href="{{ path('export_entry', { 'id': entry.id, 'format': 'pdf' }) }}" title="Generate PDF file">PDF</a></li>{% endif %}
<li><a href="mailto:hello@wallabag.org?subject=Wrong%20display%20in%20wallabag&body={{ entry.url|url_encode }}" title="{{ 'entry.view.left_menu.problem.label'|trans }}" class="tool bad-display icon icon-delete"><span>{{ 'entry.view.left_menu.problem.label'|trans }}</span></a></li>
</ul>
</div>
{% elseif currentRoute == 'archive' %}
{{ 'entry.page_titles.archived'|trans }}
{% elseif currentRoute == 'all' %}
- {{ 'entry.page_titles.filtered'|trans }}
+ {{ isFiltered ? 'entry.page_titles.filtered'|trans : 'entry.page_titles.all'|trans }}
{% elseif currentRoute == 'search' %}
{{ 'entry.page_titles.filtered_search'|trans }} {{ filter }}
{% elseif currentRoute == 'tag_entries' %}
namespace Wallabag\ImportBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
+use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
use Wallabag\ImportBundle\Form\Type\UploadImportType;
/**
use Wallabag\CoreBundle\Entity\Entry;
use Wallabag\CoreBundle\Event\EntrySavedEvent;
-use Wallabag\UserBundle\Entity\User;
abstract class BrowserImport extends AbstractImport
{
return $importedEntry;
}
+
+ abstract protected function prepareEntry(array $entry = []);
}
namespace Wallabag\UserBundle\Repository;
use Doctrine\ORM\EntityRepository;
+use Doctrine\ORM\QueryBuilder;
+use Wallabag\UserBundle\Entity\User;
class UserRepository extends EntityRepository
{
->getSingleScalarResult();
}
+ /**
+ * Count how many users are existing.
+ *
+ * @return int
+ */
+ public function getSumUsers()
+ {
+ return $this->createQueryBuilder('u')
+ ->select('count(u)')
+ ->getQuery()
+ ->getSingleScalarResult();
+ }
+
/**
* Retrieves users filtered with a search term.
*
subject: "Còdi d'autentificacion wallabag"
body:
hello: "Bonjorn %user%,"
- first_para: "Estant qu'avètz activat la dobla autentificacion sus vòtre compte wallabag e que venètz de vos conectar dempuèi un novèl aparelh (ordinador, mobil, etc.) vos mandem un còdi per validar la connexion."
- second_para: "Vaquí lo còdi a dintrar :"
- support: "S'avètz un problèma de connexion, dobtetz pas a contacter l'assisténcia : "
+ first_para: "Estant qu'avètz activat l'autentificacion en dos temps sus vòstre compte wallabag e que venètz de vos connectar dempuèi un novèl periferic (ordinador, mobil, etc.) vos mandem un còdi per validar la connexion."
+ second_para: "Vaquí lo còdi per dintrar :"
+ support: "S'avètz un problèma de connexion, dobtetz pas a contactar l'assisténcia : "
signature: "La còla de wallabag"
'username' => 'admin',
]);
- $this->assertContains('Exporting 5 entrie(s) for user « admin »... Done', $tester->getDisplay());
+ $this->assertContains('Exporting 5 entrie(s) for user admin...', $tester->getDisplay());
+ $this->assertContains('Done', $tester->getDisplay());
$this->assertFileExists('admin-export.json');
}
--- /dev/null
+<?php
+
+namespace Tests\Wallabag\CoreBundle\Command;
+
+use Symfony\Bundle\FrameworkBundle\Console\Application;
+use Symfony\Component\Console\Tester\CommandTester;
+use Tests\Wallabag\CoreBundle\WallabagCoreTestCase;
+use Wallabag\CoreBundle\Command\ListUserCommand;
+
+class ListUserCommandTest extends WallabagCoreTestCase
+{
+ public function testRunListUserCommand()
+ {
+ $application = new Application($this->getClient()->getKernel());
+ $application->add(new ListUserCommand());
+
+ $command = $application->find('wallabag:user:list');
+
+ $tester = new CommandTester($command);
+ $tester->execute([
+ 'command' => $command->getName(),
+ ]);
+
+ $this->assertContains('3/3 user(s) displayed.', $tester->getDisplay());
+ }
+
+ public function testRunListUserCommandWithLimit()
+ {
+ $application = new Application($this->getClient()->getKernel());
+ $application->add(new ListUserCommand());
+
+ $command = $application->find('wallabag:user:list');
+
+ $tester = new CommandTester($command);
+ $tester->execute([
+ 'command' => $command->getName(),
+ '--limit' => 2,
+ ]);
+
+ $this->assertContains('2/3 user(s) displayed.', $tester->getDisplay());
+ }
+
+ public function testRunListUserCommandWithSearch()
+ {
+ $application = new Application($this->getClient()->getKernel());
+ $application->add(new ListUserCommand());
+
+ $command = $application->find('wallabag:user:list');
+
+ $tester = new CommandTester($command);
+ $tester->execute([
+ 'command' => $command->getName(),
+ 'search' => 'boss',
+ ]);
+
+ $this->assertContains('1/3 (filtered) user(s) displayed.', $tester->getDisplay());
+ }
+
+ public function testRunListUserCommandWithSearchAndLimit()
+ {
+ $application = new Application($this->getClient()->getKernel());
+ $application->add(new ListUserCommand());
+
+ $command = $application->find('wallabag:user:list');
+
+ $tester = new CommandTester($command);
+ $tester->execute([
+ 'command' => $command->getName(),
+ 'search' => 'bo',
+ '--limit' => 1,
+ ]);
+
+ $this->assertContains('1/3 (filtered) user(s) displayed.', $tester->getDisplay());
+ }
+}
--- /dev/null
+<?php
+
+namespace Tests\Wallabag\CoreBundle\Command;
+
+use Symfony\Bundle\FrameworkBundle\Console\Application;
+use Symfony\Component\Console\Tester\CommandTester;
+use Tests\Wallabag\CoreBundle\WallabagCoreTestCase;
+use Wallabag\CoreBundle\Command\ReloadEntryCommand;
+use Wallabag\CoreBundle\Entity\Entry;
+
+class ReloadEntryCommandTest extends WallabagCoreTestCase
+{
+ public $url = 'http://www.lemonde.fr/pixels/article/2015/03/28/plongee-dans-l-univers-d-ingress-le-jeu-de-google-aux-frontieres-du-reel_4601155_4408996.html';
+
+ /**
+ * @var entry
+ */
+ public $adminEntry;
+
+ /**
+ * @var Entry
+ */
+ public $bobEntry;
+
+ public function setUp()
+ {
+ parent::setUp();
+
+ $userRepository = $this->getClient()->getContainer()->get('wallabag_user.user_repository');
+
+ $user = $userRepository->findOneByUserName('admin');
+ $this->adminEntry = new Entry($user);
+ $this->adminEntry->setUrl($this->url);
+ $this->adminEntry->setTitle('title foo');
+ $this->adminEntry->setContent('');
+ $this->getEntityManager()->persist($this->adminEntry);
+
+ $user = $userRepository->findOneByUserName('bob');
+ $this->bobEntry = new Entry($user);
+ $this->bobEntry->setUrl($this->url);
+ $this->bobEntry->setTitle('title foo');
+ $this->bobEntry->setContent('');
+ $this->getEntityManager()->persist($this->bobEntry);
+
+ $this->getEntityManager()->flush();
+ }
+
+ public function testRunReloadEntryCommand()
+ {
+ $application = new Application($this->getClient()->getKernel());
+ $application->add(new ReloadEntryCommand());
+
+ $command = $application->find('wallabag:entry:reload');
+ $tester = new CommandTester($command);
+ $tester->execute([
+ 'command' => $command->getName(),
+ ], [
+ 'interactive' => false,
+ ]);
+
+ $reloadedEntries = $this->getClient()
+ ->getContainer()
+ ->get('wallabag_core.entry_repository')
+ ->findById([$this->adminEntry->getId(), $this->bobEntry->getId()]);
+
+ foreach ($reloadedEntries as $reloadedEntry) {
+ $this->assertNotEmpty($reloadedEntry->getContent());
+ }
+
+ $this->assertContains('Done', $tester->getDisplay());
+ }
+
+ public function testRunReloadEntryWithUsernameCommand()
+ {
+ $application = new Application($this->getClient()->getKernel());
+ $application->add(new ReloadEntryCommand());
+
+ $command = $application->find('wallabag:entry:reload');
+ $tester = new CommandTester($command);
+ $tester->execute([
+ 'command' => $command->getName(),
+ 'username' => 'admin',
+ ], [
+ 'interactive' => false,
+ ]);
+
+ $entryRepository = $this->getClient()->getContainer()->get('wallabag_core.entry_repository');
+
+ $reloadedAdminEntry = $entryRepository->find($this->adminEntry->getId());
+ $this->assertNotEmpty($reloadedAdminEntry->getContent());
+
+ $reloadedBobEntry = $entryRepository->find($this->bobEntry->getId());
+ $this->assertEmpty($reloadedBobEntry->getContent());
+
+ $this->assertContains('Done', $tester->getDisplay());
+ }
+
+ public function testRunReloadEntryWithoutEntryCommand()
+ {
+ $application = new Application($this->getClient()->getKernel());
+ $application->add(new ReloadEntryCommand());
+
+ $command = $application->find('wallabag:entry:reload');
+ $tester = new CommandTester($command);
+ $tester->execute([
+ 'command' => $command->getName(),
+ 'username' => 'empty',
+ ], [
+ 'interactive' => false,
+ ]);
+
+ $this->assertContains('No entry to reload', $tester->getDisplay());
+ $this->assertNotContains('Done', $tester->getDisplay());
+ }
+}
'username' => 'admin',
]);
- $this->assertContains('Username : admin', $tester->getDisplay());
- $this->assertContains('Email : bigboss@wallabag.org', $tester->getDisplay());
- $this->assertContains('Display name : Big boss', $tester->getDisplay());
+ $this->assertContains('Username: admin', $tester->getDisplay());
+ $this->assertContains('Email: bigboss@wallabag.org', $tester->getDisplay());
+ $this->assertContains('Display name: Big boss', $tester->getDisplay());
$this->assertContains('2FA activated: no', $tester->getDisplay());
}
'username' => 'admin',
]);
- $this->assertContains('Display name : Bug boss', $tester->getDisplay());
+ $this->assertContains('Display name: Bug boss', $tester->getDisplay());
}
}
'username' => 'admin',
]);
- $this->assertContains('Tagging entries for user « admin »... Done', $tester->getDisplay());
+ $this->assertContains('Tagging entries for user admin...', $tester->getDisplay());
+ $this->assertContains('Done', $tester->getDisplay());
}
}