Merge branch 'master' into feat_referer_to_session_redirect

This commit is contained in:
Michael Ciociola 2023-08-06 20:14:44 +00:00 committed by GitHub
commit ced2ea4015
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
362 changed files with 8665 additions and 6104 deletions

View file

@ -45,3 +45,17 @@ Note : If you have large portions of text, use [Github's Gist service](https://g
## You want to fix a bug or to add a feature ## You want to fix a bug or to add a feature
Please fork wallabag and work with **the master branch**. Please fork wallabag and work with **the master branch**.
## Run Tests and PHP formatter
All pull requests need to pass the tests and the code needs match the style guide.
To run the tests locally run:
- when testing using Docker: `docker-compose run --rm php make test`
- otherwise: `make test`
To run the PHP formatter:
- when testing using Docker: `docker-compose run --rm php bin/php-cs-fixer fix`
- otherwise: `php bin/php-cs-fixer fix`

View file

@ -22,15 +22,10 @@ updates:
- j0k3r - j0k3r
- tcitworld - tcitworld
- Kdecherf - Kdecherf
labels:
- Ready for review
ignore: ignore:
- dependency-name: doctrine/doctrine-migrations-bundle - dependency-name: lcobucci/jwt
versions: versions:
- "> 1.3.2" - ">= 4.2.0"
- dependency-name: friendsofsymfony/user-bundle
versions:
- "> 2.0.2"
- package-ecosystem: github-actions - package-ecosystem: github-actions
directory: "/" directory: "/"
schedule: schedule:

View file

@ -49,3 +49,6 @@ jobs:
- name: "Run TwigCS" - name: "Run TwigCS"
run: "php bin/twigcs --severity=error --display=blocking --reporter checkstyle app/ src/ | cs2pr" run: "php bin/twigcs --severity=error --display=blocking --reporter checkstyle app/ src/ | cs2pr"
- name: "Run ergebnis/composer-normalize"
run: "composer normalize --dry-run --no-check-lock"

View file

@ -32,6 +32,7 @@ jobs:
- "7.4" - "7.4"
- "8.0" - "8.0"
- "8.1" - "8.1"
- "8.2"
database: database:
- "sqlite" - "sqlite"
- "mysql" - "mysql"
@ -79,3 +80,74 @@ jobs:
- name: "Run PHPUnit" - name: "Run PHPUnit"
run: "php bin/simple-phpunit -v" run: "php bin/simple-phpunit -v"
phpunit_no_prefix:
name: "PHP ${{ matrix.php }} using ${{ matrix.database }} without prefix"
runs-on: "ubuntu-20.04"
services:
rabbitmq:
image: rabbitmq:3-alpine
ports:
- 5672:5672
redis:
image: redis:6-alpine
ports:
- 6379:6379
strategy:
fail-fast: true
matrix:
php:
- "8.2"
database:
- "sqlite"
- "mysql"
- "pgsql"
steps:
- name: "Checkout"
uses: "actions/checkout@v3"
with:
fetch-depth: 2
- name: "Install PHP"
uses: "shivammathur/setup-php@v2"
with:
php-version: "${{ matrix.php }}"
coverage: none
tools: pecl
extensions: json, pdo, pdo_mysql, pdo_sqlite, pdo_pgsql, curl, imagick, pgsql, gd, tidy
ini-values: "date.timezone=Europe/Paris"
- name: "Remove database prefix"
run: |
pip install --user yq
yq -Y --in-place '.parameters.database_table_prefix = ""' app/config/parameters.yml.dist
- name: "Setup MySQL"
if: "${{ matrix.database == 'mysql' }}"
run: |
sudo systemctl start mysql.service
sudo mysql -u root -proot -h 127.0.0.1 -e "CREATE DATABASE wallabag_test"
- name: "Setup PostgreSQL"
if: "${{ matrix.database == 'pgsql' }}"
run: |
sudo systemctl start postgresql
sudo -u postgres psql -d template1 -c "CREATE USER wallabag WITH PASSWORD 'wallabagrocks' CREATEDB"
createdb -h localhost -p 5432 -U wallabag wallabag_test
pg_isready -d wallabag_test -h localhost -p 5432 -U wallabag
- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v2"
with:
composer-options: "--optimize-autoloader --prefer-dist"
- name: "Prepare database"
run: "make prepare DB=${{ matrix.database }}"
- name: "Prepare fixtures"
run: "make fixtures"
- name: "Run PHPUnit"
run: "php bin/simple-phpunit -v"

View file

@ -12,7 +12,7 @@ jobs:
steps: steps:
- name: Dependabot metadata - name: Dependabot metadata
id: metadata id: metadata
uses: dependabot/fetch-metadata@v1.3.5 uses: dependabot/fetch-metadata@v1.6.0
with: with:
github-token: '${{ secrets.GITHUB_TOKEN }}' github-token: '${{ secrets.GITHUB_TOKEN }}'
- name: Approve and merge minor updates - name: Approve and merge minor updates

View file

@ -40,11 +40,5 @@ jobs:
with: with:
composer-options: "--optimize-autoloader --prefer-dist" composer-options: "--optimize-autoloader --prefer-dist"
- name: "Validate Core translations" - name: "Validate translations"
run: "php bin/console lint:yaml src/Wallabag/CoreBundle/Resources/translations -v" run: "php bin/console lint:yaml translations -v"
- name: "Validate CraueConfig translations"
run: "php bin/console lint:yaml app/Resources/CraueConfigBundle/translations -v"
- name: "Validate User translations"
run: "php bin/console lint:yaml src/Wallabag/UserBundle/Resources/translations -v"

View file

@ -1,5 +1,131 @@
# Changelog # Changelog
## [2.6.2](https://github.com/wallabag/wallabag/tree/2.6.2)
[Full Changelog](https://github.com/wallabag/wallabag/compare/2.6.1...2.6.2)
### Fixes
* Fix mass action input on dark theme by @simounet https://github.com/wallabag/wallabag/pull/6673
* Fix undefined variable by @nicosomb https://github.com/wallabag/wallabag/pull/6672
* Fix table name in migration by @nicosomb https://github.com/wallabag/wallabag/pull/6653
### Technical stuff
* Add a new build to test when no database table prefix are defined by @j0k3r https://github.com/wallabag/wallabag/pull/6731
* Keep escaped table name while migrating by @Glandos https://github.com/wallabag/wallabag/pull/6710
* Remove twofactor_auth parameter by @nicosomb https://github.com/wallabag/wallabag/pull/6723
* ApiDoc: Add response description to UserRestController by @caspermeijn https://github.com/wallabag/wallabag/pull/6684
* ApiDoc: Add response description to WallabagRestController by @caspermeijn https://github.com/wallabag/wallabag/pull/6102
* Skip migration if the table was already renamed by @gramakri https://github.com/wallabag/wallabag/pull/6678
### Meta
* Document how to run tests and formatter for new contributors by @caspermeijn https://github.com/wallabag/wallabag/pull/6685
* Add link to wallabag ecosystem resources by @nicosomb https://github.com/wallabag/wallabag/pull/6700
## [2.6.1](https://github.com/wallabag/wallabag/tree/2.6.1)
[Full Changelog](https://github.com/wallabag/wallabag/compare/2.6.0...2.6.1)
### Fixes
* Do not autoload fixtures by @j0k3r https://github.com/wallabag/wallabag/pull/6648
* Add confirmation alert when deleting articles from list view by @nicosomb https://github.com/wallabag/wallabag/pull/6644
## [2.6.0](https://github.com/wallabag/wallabag/tree/2.6.0)
[Full Changelog](https://github.com/wallabag/wallabag/compare/2.5.4...2.6.0)
### Features
* Add tag deletion from tags list by @nicosomb https://github.com/wallabag/wallabag/pull/5861
* Add support of mass action to tag entries by @kdecherf https://github.com/wallabag/wallabag/pull/5838
* Mass action interface by @Simounet https://github.com/wallabag/wallabag/pull/6547
* Empty space on the top bar used for more add url toggle clickable target by @Simounet https://github.com/wallabag/wallabag/pull/6612
* Add new setting to show / hide articles thumbnails by @nicosomb https://github.com/wallabag/wallabag/pull/6609
### Fixes
* Add prefix for tag slugs by @kdecherf https://github.com/wallabag/wallabag/pull/6226
* Fix open all external links in new tab in Config by @wyntonfranklin https://github.com/wallabag/wallabag/pull/6256
* Fix dark theme for pre HTML tags by @Simounet https://github.com/wallabag/wallabag/pull/6495
* Fix dark mode top bar contrast by @Simounet https://github.com/wallabag/wallabag/pull/6510
* Dark mode contrast improved by @Simounet https://github.com/wallabag/wallabag/pull/6512
* Fix dark mode URL add input color by @Simounet https://github.com/wallabag/wallabag/pull/6525
* Fix round reading time in export by @mart-e https://github.com/wallabag/wallabag/pull/6545
* Fix images downloading with numeric HTML entity by @Simounet https://github.com/wallabag/wallabag/pull/6563
* Fix DownloadImages not following redirections by @Simounet https://github.com/wallabag/wallabag/pull/6562
* Fix auto dark theme detection flickering by @Simounet https://github.com/wallabag/wallabag/pull/6584
* Fix RSS feed_route not set by @Simounet https://github.com/wallabag/wallabag/pull/6606
* Add flash message when we try to add too much tags by @nicosomb https://github.com/wallabag/wallabag/pull/6607
* Changed default value for domain_name parameter by @nicosomb https://github.com/wallabag/wallabag/pull/6616
* Improved tags display by @Simounet https://github.com/wallabag/wallabag/pull/6613
* Fix mousetrap enter issue by @Simounet https://github.com/wallabag/wallabag/pull/6624
* Fix duplicate tags creation when assigning search results to tag by @nicosomb https://github.com/wallabag/wallabag/pull/6629
### Meta
* Removed Carrot & Scuttle share by @nicosomb https://github.com/wallabag/wallabag/pull/6047
* Remove old, not so maintained and buggy baggy theme by @nicosomb https://github.com/wallabag/wallabag/pull/4332
* Remove Scrutinizer badge by @j0k3r https://github.com/wallabag/wallabag/pull/6179
* Add mention to unofficial linux client by @imhemish https://github.com/wallabag/wallabag/pull/6203
### Technical stuff
* Remove SensioDistributionBundle by @yguedidi https://github.com/wallabag/wallabag/pull/5761
* Back to latest composer version by @yguedidi https://github.com/wallabag/wallabag/pull/5810
* Clean composer.lock after SensioDistributionBundle removal by @yguedidi https://github.com/wallabag/wallabag/pull/5839
* Remove transitive dependencies by @yguedidi https://github.com/wallabag/wallabag/pull/5784
* Register missed commands by @yguedidi https://github.com/wallabag/wallabag/pull/5928
* Extend right FOSRestBundle controller class by @yguedidi https://github.com/wallabag/wallabag/pull/5929
* Remove PHP-CS-Fixer deprecations by @yguedidi https://github.com/wallabag/wallabag/pull/5914
* Upgrade FOSUserBundle to 2.1 by @yguedidi https://github.com/wallabag/wallabag/pull/5782
* Add TwigCS by @yguedidi https://github.com/wallabag/wallabag/pull/5759
* Use FQCN as service name by @yguedidi https://github.com/wallabag/wallabag/pull/5748
* Migrate to new template reference notation by @yguedidi https://github.com/wallabag/wallabag/pull/5758
* Migrate from old colon notation to FQCN by @yguedidi https://github.com/wallabag/wallabag/pull/5943
* Use autowiring by @yguedidi https://github.com/wallabag/wallabag/pull/5946
* Use FQCN to fetch services by @yguedidi https://github.com/wallabag/wallabag/pull/5951
* Run tests without memory limit by @yguedidi https://github.com/wallabag/wallabag/pull/5953
* Import used classes by @yguedidi https://github.com/wallabag/wallabag/pull/5952
* Rework command tests by @yguedidi https://github.com/wallabag/wallabag/pull/5954
* Switch to Swagger for api documentation by @caspermeijn https://github.com/wallabag/wallabag/pull/6062
* Remove some deprecation by @j0k3r https://github.com/wallabag/wallabag/pull/6085
* Remove deprecated options from FOSRest by @j0k3r https://github.com/wallabag/wallabag/pull/6095
* Remove LiipThemeBundle by @j0k3r https://github.com/wallabag/wallabag/pull/6097
* Upgrade PHPStan and move to level 2 with baseline by @j0k3r https://github.com/wallabag/wallabag/pull/6098
* Upgrade to Symfony 4.4 by @j0k3r https://github.com/wallabag/wallabag/pull/6099
* Update to FOSUserBundle 3.1 by @j0k3r https://github.com/wallabag/wallabag/pull/6136
* Update to scheb/2fa-bundle by @j0k3r https://github.com/wallabag/wallabag/pull/6144
* Upgrade to Twig 3 by @j0k3r https://github.com/wallabag/wallabag/pull/6151
* Move translations files to /translations by @j0k3r https://github.com/wallabag/wallabag/pull/6153
* Fix EventDispatcher & events by @j0k3r https://github.com/wallabag/wallabag/pull/6154
* Replace SwiftMailer by Symfony Mailer by @j0k3r https://github.com/wallabag/wallabag/pull/6150
* Remove ContainerAwareCommand from commands by @j0k3r https://github.com/wallabag/wallabag/pull/6152
* Update all Doctrine deps by @j0k3r https://github.com/wallabag/wallabag/pull/6143
* Update PagerFanta by @j0k3r https://github.com/wallabag/wallabag/pull/6145
* Move to controller as a service by @j0k3r https://github.com/wallabag/wallabag/pull/6159
* Add RabbitMQConsumerTotalProxy to lazy RabbitMQ services for messages by @j0k3r https://github.com/wallabag/wallabag/pull/6166
* Properly handle json_array type removal by @j0k3r https://github.com/wallabag/wallabag/pull/6171
* Fix database_path in Docker env by @j0k3r https://github.com/wallabag/wallabag/pull/6174
* Docker: database_table_prefix may be configured from environment by @fcatt https://github.com/wallabag/wallabag/pull/6196
* Update annotations to OpenApi 3 by @caspermeijn https://github.com/wallabag/wallabag/pull/6182
* Fix public folder for Symfony 4+ by @kdecherf https://github.com/wallabag/wallabag/pull/6217
* Fix API allowed_registration by @caspermeijn https://github.com/wallabag/wallabag/pull/6315
* Enable PHP 8.2 in CI by @j0k3r https://github.com/wallabag/wallabag/pull/6469
* Fix/build stylelint error by @Simounet https://github.com/wallabag/wallabag/pull/6586
## [2.5.4](https://github.com/wallabag/wallabag/tree/2.5.4)
[Full Changelog](https://github.com/wallabag/wallabag/compare/2.5.3...2.5.4)
### Security fixes
* Fix adding tag to entries from other people by @j0k3r in https://github.com/wallabag/wallabag/pull/6290
* Fix XSS on username on share page by @j0k3r in https://github.com/wallabag/wallabag/pull/6288
* Fix CSRF on user deletion by @j0k3r in https://github.com/wallabag/wallabag/pull/6289
### Meta
* Fix release script by @j0k3r in https://github.com/wallabag/wallabag/pull/6275
## [2.5.3](https://github.com/wallabag/wallabag/tree/2.5.3)
[Full Changelog](https://github.com/wallabag/wallabag/compare/2.5.2...2.5.3)
### Security fixes
* Fix GHSA-qwx8-mxxx-mg96 https://github.com/wallabag/wallabag/commit/0f7460dbab9e29f4f7d2944aca20210f828b6abb by @Kdecherf, thanks to @bAuh0lz
* Fix GHSA-mrqx-mjc4-vfh3 https://github.com/wallabag/wallabag/commit/5ac6b6bff9e2e3a87fd88c2904ff3c6aac40722e by @Kdecherf, thanks to @bAuh0lz
### Meta
* Update deps before 2.5.3 by @j0k3r in https://github.com/wallabag/wallabag/pull/6241
## [2.5.2](https://github.com/wallabag/wallabag/tree/2.5.2) ## [2.5.2](https://github.com/wallabag/wallabag/tree/2.5.2)
[Full Changelog](https://github.com/wallabag/wallabag/compare/2.5.1...2.5.2) [Full Changelog](https://github.com/wallabag/wallabag/compare/2.5.1...2.5.2)

View file

@ -40,7 +40,7 @@ ifdef DB
endif endif
-php bin/console doctrine:database:drop --force --env=test -php bin/console doctrine:database:drop --force --env=test
php bin/console doctrine:database:create --env=test php bin/console doctrine:database:create --env=test
php bin/console doctrine:migrations:migrate --no-interaction --env=test php bin/console doctrine:migrations:migrate --no-interaction --env=test -vv
fixtures: ## Load fixtures into database fixtures: ## Load fixtures into database
php bin/console doctrine:fixtures:load --no-interaction --env=test php bin/console doctrine:fixtures:load --no-interaction --env=test

View file

@ -1,7 +1,6 @@
# wallabag # wallabag
![CI](https://github.com/wallabag/wallabag/workflows/CI/badge.svg) ![CI](https://github.com/wallabag/wallabag/workflows/CI/badge.svg)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/wallabag/wallabag/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/wallabag/wallabag/?branch=master)
[![Gitter](https://badges.gitter.im/gitterHQ/gitter.svg)](https://gitter.im/wallabag/wallabag) [![Gitter](https://badges.gitter.im/gitterHQ/gitter.svg)](https://gitter.im/wallabag/wallabag)
[![Donation Status](https://img.shields.io/liberapay/goal/wallabag.svg?logo=liberapay)](https://liberapay.com/wallabag/donate) [![Donation Status](https://img.shields.io/liberapay/goal/wallabag.svg?logo=liberapay)](https://liberapay.com/wallabag/donate)
[![Translation status](https://hosted.weblate.org/widgets/wallabag/-/svg-badge.svg)](https://hosted.weblate.org/engage/wallabag/?utm_source=widget) [![Translation status](https://hosted.weblate.org/widgets/wallabag/-/svg-badge.svg)](https://hosted.weblate.org/engage/wallabag/?utm_source=widget)
@ -18,6 +17,8 @@ You can install it on your own server, or you can create an account on [wallabag
* Android app: [wallabag/android-app](https://github.com/wallabag/android-app) * Android app: [wallabag/android-app](https://github.com/wallabag/android-app)
* iOS app: [wallabag/ios-app](https://github.com/wallabag/ios-app) * iOS app: [wallabag/ios-app](https://github.com/wallabag/ios-app)
* Browser extension: [wallabag/wallabagger](https://github.com/wallabag/wallabagger) * Browser extension: [wallabag/wallabagger](https://github.com/wallabag/wallabagger)
* GNOME (Linux) app: [read-it-later](https://gitlab.gnome.org/World/read-it-later) (not maintained by this project)
* All resources about wallabag ecosystem are listed here: https://github.com/wallabag/wallabag/wiki/wallabag-ecosystem
## Documentation ## Documentation

View file

@ -17,9 +17,8 @@ During this documentation, we assume the release is `$LAST_WALLABAG_RELEASE` (li
#### Create a new release on GitHub #### Create a new release on GitHub
- [Create the new release on GitHub](https://github.com/wallabag/wallabag/releases/new) by targetting the `master` branch or any appropriate branch (for instance backports). - [Create the new release on GitHub](https://github.com/wallabag/wallabag/releases/new) by targetting the `master` branch or any appropriate branch (for instance backports).
- Update nginx config to change the redirect rule for `https://wllbg.org/latest-v2-package` & `http://wllbg.org/latest-v2` (they both redirect to the asset of the GitHub release) - Update [website](https://github.com/wallabag/website) to change MD5 sum and create the release blog post (based on the changelog).
- Update Dockerfile https://github.com/wallabag/docker (and create a new tag) - Update Dockerfile https://github.com/wallabag/docker (and create a new tag)
- Update wallabag.org website (downloads, MD5 sum, releases and new blog post)
- Put the next patch version suffixed with `-dev` in `app/config/wallabag.yml` (`wallabag_core.version`) - Put the next patch version suffixed with `-dev` in `app/config/wallabag.yml` (`wallabag_core.version`)
- Drink a :beer:! - Drink a :beer:!

View file

@ -13,7 +13,6 @@ class AppKernel extends Kernel
new Symfony\Bundle\SecurityBundle\SecurityBundle(), new Symfony\Bundle\SecurityBundle\SecurityBundle(),
new Symfony\Bundle\TwigBundle\TwigBundle(), new Symfony\Bundle\TwigBundle\TwigBundle(),
new Symfony\Bundle\MonologBundle\MonologBundle(), new Symfony\Bundle\MonologBundle\MonologBundle(),
new Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle(),
new Doctrine\Bundle\DoctrineBundle\DoctrineBundle(), new Doctrine\Bundle\DoctrineBundle\DoctrineBundle(),
new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(), new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(),
new FOS\RestBundle\FOSRestBundle(), new FOS\RestBundle\FOSRestBundle(),
@ -35,6 +34,7 @@ class AppKernel extends Kernel
new OldSound\RabbitMqBundle\OldSoundRabbitMqBundle(), new OldSound\RabbitMqBundle\OldSoundRabbitMqBundle(),
new Http\HttplugBundle\HttplugBundle(), new Http\HttplugBundle\HttplugBundle(),
new Sentry\SentryBundle\SentryBundle(), new Sentry\SentryBundle\SentryBundle(),
new Twig\Extra\TwigExtraBundle\TwigExtraBundle(),
// wallabag bundles // wallabag bundles
new Wallabag\CoreBundle\WallabagCoreBundle(), new Wallabag\CoreBundle\WallabagCoreBundle(),

View file

@ -10,7 +10,7 @@ use Wallabag\CoreBundle\Doctrine\WallabagMigration;
*/ */
class Version20160401000000 extends WallabagMigration class Version20160401000000 extends WallabagMigration
{ {
public function up(Schema $schema) public function up(Schema $schema): void
{ {
$this->skipIf($schema->hasTable($this->getTable('entry')), 'Database already initialized'); $this->skipIf($schema->hasTable($this->getTable('entry')), 'Database already initialized');
@ -164,7 +164,7 @@ SQL
} }
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
$this->addSql("DROP TABLE {$this->getTable('craue_config_setting')}"); $this->addSql("DROP TABLE {$this->getTable('craue_config_setting')}");
$this->addSql("DROP TABLE {$this->getTable('tagging_rule')}"); $this->addSql("DROP TABLE {$this->getTable('tagging_rule')}");

View file

@ -10,7 +10,7 @@ use Wallabag\CoreBundle\Doctrine\WallabagMigration;
*/ */
class Version20160410190541 extends WallabagMigration class Version20160410190541 extends WallabagMigration
{ {
public function up(Schema $schema) public function up(Schema $schema): void
{ {
$entryTable = $schema->getTable($this->getTable('entry')); $entryTable = $schema->getTable($this->getTable('entry'));
@ -24,14 +24,14 @@ class Version20160410190541 extends WallabagMigration
$sharePublic = $this->container $sharePublic = $this->container
->get('doctrine.orm.default_entity_manager') ->get('doctrine.orm.default_entity_manager')
->getConnection() ->getConnection()
->fetchArray('SELECT * FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'share_public'"); ->fetchOne('SELECT * FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'share_public'");
if (false === $sharePublic) { if (false === $sharePublic) {
$this->addSql('INSERT INTO ' . $this->getTable('craue_config_setting') . " (name, value, section) VALUES ('share_public', '1', 'entry')"); $this->addSql('INSERT INTO ' . $this->getTable('craue_config_setting') . " (name, value, section) VALUES ('share_public', '1', 'entry')");
} }
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
$entryTable = $schema->getTable($this->getTable('entry')); $entryTable = $schema->getTable($this->getTable('entry'));
$entryTable->dropColumn('uid'); $entryTable->dropColumn('uid');

View file

@ -10,7 +10,7 @@ use Wallabag\CoreBundle\Doctrine\WallabagMigration;
*/ */
class Version20160812120952 extends WallabagMigration class Version20160812120952 extends WallabagMigration
{ {
public function up(Schema $schema) public function up(Schema $schema): void
{ {
$clientsTable = $schema->getTable($this->getTable('oauth2_clients')); $clientsTable = $schema->getTable($this->getTable('oauth2_clients'));
$this->skipIf($clientsTable->hasColumn('name'), 'It seems that you already played this migration.'); $this->skipIf($clientsTable->hasColumn('name'), 'It seems that you already played this migration.');
@ -31,7 +31,7 @@ class Version20160812120952 extends WallabagMigration
} }
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
$clientsTable = $schema->getTable($this->getTable('oauth2_clients')); $clientsTable = $schema->getTable($this->getTable('oauth2_clients'));

View file

@ -10,12 +10,12 @@ use Wallabag\CoreBundle\Doctrine\WallabagMigration;
*/ */
class Version20160911214952 extends WallabagMigration class Version20160911214952 extends WallabagMigration
{ {
public function up(Schema $schema) public function up(Schema $schema): void
{ {
$redis = $this->container $redis = $this->container
->get('doctrine.orm.default_entity_manager') ->get('doctrine.orm.default_entity_manager')
->getConnection() ->getConnection()
->fetchArray('SELECT * FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'import_with_redis'"); ->fetchOne('SELECT * FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'import_with_redis'");
if (false === $redis) { if (false === $redis) {
$this->addSql('INSERT INTO ' . $this->getTable('craue_config_setting') . " (name, value, section) VALUES ('import_with_redis', 0, 'import')"); $this->addSql('INSERT INTO ' . $this->getTable('craue_config_setting') . " (name, value, section) VALUES ('import_with_redis', 0, 'import')");
@ -24,7 +24,7 @@ class Version20160911214952 extends WallabagMigration
$rabbitmq = $this->container $rabbitmq = $this->container
->get('doctrine.orm.default_entity_manager') ->get('doctrine.orm.default_entity_manager')
->getConnection() ->getConnection()
->fetchArray('SELECT * FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'import_with_rabbitmq'"); ->fetchOne('SELECT * FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'import_with_rabbitmq'");
if (false === $rabbitmq) { if (false === $rabbitmq) {
$this->addSql('INSERT INTO ' . $this->getTable('craue_config_setting') . " (name, value, section) VALUES ('import_with_rabbitmq', 0, 'import')"); $this->addSql('INSERT INTO ' . $this->getTable('craue_config_setting') . " (name, value, section) VALUES ('import_with_rabbitmq', 0, 'import')");
@ -33,7 +33,7 @@ class Version20160911214952 extends WallabagMigration
$this->skipIf(false !== $rabbitmq && false !== $redis, 'It seems that you already played this migration.'); $this->skipIf(false !== $rabbitmq && false !== $redis, 'It seems that you already played this migration.');
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
$this->addSql('DELETE FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'import_with_redis';"); $this->addSql('DELETE FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'import_with_redis';");
$this->addSql('DELETE FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'import_with_rabbitmq';"); $this->addSql('DELETE FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'import_with_rabbitmq';");

View file

@ -10,7 +10,7 @@ use Wallabag\CoreBundle\Doctrine\WallabagMigration;
*/ */
class Version20160916201049 extends WallabagMigration class Version20160916201049 extends WallabagMigration
{ {
public function up(Schema $schema) public function up(Schema $schema): void
{ {
$configTable = $schema->getTable($this->getTable('config')); $configTable = $schema->getTable($this->getTable('config'));
@ -20,7 +20,7 @@ class Version20160916201049 extends WallabagMigration
$this->addSql('DELETE FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'pocket_consumer_key';"); $this->addSql('DELETE FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'pocket_consumer_key';");
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
$configTable = $schema->getTable($this->getTable('config')); $configTable = $schema->getTable($this->getTable('config'));
$configTable->dropColumn('pocket_consumer_key'); $configTable->dropColumn('pocket_consumer_key');

View file

@ -11,7 +11,7 @@ use Wallabag\CoreBundle\Doctrine\WallabagMigration;
*/ */
class Version20161001072726 extends WallabagMigration class Version20161001072726 extends WallabagMigration
{ {
public function up(Schema $schema) public function up(Schema $schema): void
{ {
$this->skipIf('sqlite' === $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'mysql\' or \'postgresql\'.'); $this->skipIf('sqlite' === $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'mysql\' or \'postgresql\'.');
@ -24,9 +24,8 @@ class Version20161001072726 extends WallabagMigration
WHERE TABLE_NAME = '" . $this->getTable('entry_tag', WallabagMigration::UN_ESCAPED_TABLE) . "' AND CONSTRAINT_NAME LIKE 'FK_%' WHERE TABLE_NAME = '" . $this->getTable('entry_tag', WallabagMigration::UN_ESCAPED_TABLE) . "' AND CONSTRAINT_NAME LIKE 'FK_%'
AND TABLE_SCHEMA = '" . $this->connection->getDatabase() . "'" AND TABLE_SCHEMA = '" . $this->connection->getDatabase() . "'"
); );
$query->execute();
foreach ($query->fetchAll() as $fk) { foreach ($query->fetchAllAssociative() as $fk) {
$this->addSql('ALTER TABLE ' . $this->getTable('entry_tag') . ' DROP FOREIGN KEY ' . $fk['CONSTRAINT_NAME']); $this->addSql('ALTER TABLE ' . $this->getTable('entry_tag') . ' DROP FOREIGN KEY ' . $fk['CONSTRAINT_NAME']);
} }
break; break;
@ -42,9 +41,8 @@ class Version20161001072726 extends WallabagMigration
AND conrelid::regclass::text = '" . $this->getTable('entry_tag', WallabagMigration::UN_ESCAPED_TABLE) . "' AND conrelid::regclass::text = '" . $this->getTable('entry_tag', WallabagMigration::UN_ESCAPED_TABLE) . "'
AND n.nspname = 'public';" AND n.nspname = 'public';"
); );
$query->execute();
foreach ($query->fetchAll() as $fk) { foreach ($query->fetchAllAssociative() as $fk) {
$this->addSql('ALTER TABLE ' . $this->getTable('entry_tag') . ' DROP CONSTRAINT ' . $fk['conname']); $this->addSql('ALTER TABLE ' . $this->getTable('entry_tag') . ' DROP CONSTRAINT ' . $fk['conname']);
} }
break; break;
@ -65,9 +63,8 @@ class Version20161001072726 extends WallabagMigration
AND COLUMN_NAME = 'entry_id' AND COLUMN_NAME = 'entry_id'
AND TABLE_SCHEMA = '" . $this->connection->getDatabase() . "'" AND TABLE_SCHEMA = '" . $this->connection->getDatabase() . "'"
); );
$query->execute();
foreach ($query->fetchAll() as $fk) { foreach ($query->fetchAllAssociative() as $fk) {
$this->addSql('ALTER TABLE ' . $this->getTable('annotation') . ' DROP FOREIGN KEY ' . $fk['CONSTRAINT_NAME']); $this->addSql('ALTER TABLE ' . $this->getTable('annotation') . ' DROP FOREIGN KEY ' . $fk['CONSTRAINT_NAME']);
} }
break; break;
@ -84,9 +81,8 @@ class Version20161001072726 extends WallabagMigration
AND n.nspname = 'public' AND n.nspname = 'public'
AND pg_get_constraintdef(c.oid) LIKE '%entry_id%';" AND pg_get_constraintdef(c.oid) LIKE '%entry_id%';"
); );
$query->execute();
foreach ($query->fetchAll() as $fk) { foreach ($query->fetchAllAssociative() as $fk) {
$this->addSql('ALTER TABLE ' . $this->getTable('annotation') . ' DROP CONSTRAINT ' . $fk['conname']); $this->addSql('ALTER TABLE ' . $this->getTable('annotation') . ' DROP CONSTRAINT ' . $fk['conname']);
} }
break; break;
@ -95,7 +91,7 @@ class Version20161001072726 extends WallabagMigration
$this->addSql('ALTER TABLE ' . $this->getTable('annotation') . ' ADD CONSTRAINT FK_annotation_entry FOREIGN KEY (entry_id) REFERENCES ' . $this->getTable('entry') . ' (id) ON DELETE CASCADE'); $this->addSql('ALTER TABLE ' . $this->getTable('annotation') . ' ADD CONSTRAINT FK_annotation_entry FOREIGN KEY (entry_id) REFERENCES ' . $this->getTable('entry') . ' (id) ON DELETE CASCADE');
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
throw new SkipMigrationException('Too complex ...'); throw new SkipMigrationException('Too complex ...');
} }

View file

@ -10,7 +10,7 @@ use Wallabag\CoreBundle\Doctrine\WallabagMigration;
*/ */
class Version20161022134138 extends WallabagMigration class Version20161022134138 extends WallabagMigration
{ {
public function up(Schema $schema) public function up(Schema $schema): void
{ {
$this->skipIf('mysql' !== $this->connection->getDatabasePlatform()->getName(), 'This migration only apply to MySQL'); $this->skipIf('mysql' !== $this->connection->getDatabasePlatform()->getName(), 'This migration only apply to MySQL');
@ -38,7 +38,7 @@ class Version20161022134138 extends WallabagMigration
$this->addSql('ALTER TABLE ' . $this->getTable('user') . ' CHANGE `name` `name` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;'); $this->addSql('ALTER TABLE ' . $this->getTable('user') . ' CHANGE `name` `name` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;');
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
$this->skipIf('mysql' !== $this->connection->getDatabasePlatform()->getName(), 'This migration only apply to MySQL'); $this->skipIf('mysql' !== $this->connection->getDatabasePlatform()->getName(), 'This migration only apply to MySQL');

View file

@ -12,7 +12,7 @@ class Version20161024212538 extends WallabagMigration
{ {
private $constraintName = 'IDX_user_oauth_client'; private $constraintName = 'IDX_user_oauth_client';
public function up(Schema $schema) public function up(Schema $schema): void
{ {
$clientsTable = $schema->getTable($this->getTable('oauth2_clients')); $clientsTable = $schema->getTable($this->getTable('oauth2_clients'));
@ -29,7 +29,7 @@ class Version20161024212538 extends WallabagMigration
); );
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
$clientsTable = $schema->getTable($this->getTable('oauth2_clients')); $clientsTable = $schema->getTable($this->getTable('oauth2_clients'));

View file

@ -10,19 +10,19 @@ use Wallabag\CoreBundle\Doctrine\WallabagMigration;
*/ */
class Version20161031132655 extends WallabagMigration class Version20161031132655 extends WallabagMigration
{ {
public function up(Schema $schema) public function up(Schema $schema): void
{ {
$images = $this->container $images = $this->container
->get('doctrine.orm.default_entity_manager') ->get('doctrine.orm.default_entity_manager')
->getConnection() ->getConnection()
->fetchArray('SELECT * FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'download_images_enabled'"); ->fetchOne('SELECT * FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'download_images_enabled'");
$this->skipIf(false !== $images, 'It seems that you already played this migration.'); $this->skipIf(false !== $images, 'It seems that you already played this migration.');
$this->addSql('INSERT INTO ' . $this->getTable('craue_config_setting') . " (name, value, section) VALUES ('download_images_enabled', 0, 'misc')"); $this->addSql('INSERT INTO ' . $this->getTable('craue_config_setting') . " (name, value, section) VALUES ('download_images_enabled', 0, 'misc')");
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
$this->addSql('DELETE FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'download_images_enabled';"); $this->addSql('DELETE FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'download_images_enabled';");
} }

View file

@ -12,7 +12,7 @@ class Version20161104073720 extends WallabagMigration
{ {
private $indexName = 'IDX_entry_created_at'; private $indexName = 'IDX_entry_created_at';
public function up(Schema $schema) public function up(Schema $schema): void
{ {
$entryTable = $schema->getTable($this->getTable('entry')); $entryTable = $schema->getTable($this->getTable('entry'));
$this->skipIf($entryTable->hasIndex($this->indexName), 'It seems that you already played this migration.'); $this->skipIf($entryTable->hasIndex($this->indexName), 'It seems that you already played this migration.');
@ -20,7 +20,7 @@ class Version20161104073720 extends WallabagMigration
$entryTable->addIndex(['created_at'], $this->indexName); $entryTable->addIndex(['created_at'], $this->indexName);
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
$entryTable = $schema->getTable($this->getTable('entry')); $entryTable = $schema->getTable($this->getTable('entry'));
$this->skipIf(false === $entryTable->hasIndex($this->indexName), 'It seems that you already played this migration.'); $this->skipIf(false === $entryTable->hasIndex($this->indexName), 'It seems that you already played this migration.');

View file

@ -10,7 +10,7 @@ use Wallabag\CoreBundle\Doctrine\WallabagMigration;
*/ */
class Version20161106113822 extends WallabagMigration class Version20161106113822 extends WallabagMigration
{ {
public function up(Schema $schema) public function up(Schema $schema): void
{ {
$configTable = $schema->getTable($this->getTable('config')); $configTable = $schema->getTable($this->getTable('config'));
@ -22,7 +22,7 @@ class Version20161106113822 extends WallabagMigration
]); ]);
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
$configTable = $schema->getTable($this->getTable('config')); $configTable = $schema->getTable($this->getTable('config'));

View file

@ -10,12 +10,12 @@ use Wallabag\CoreBundle\Doctrine\WallabagMigration;
*/ */
class Version20161117071626 extends WallabagMigration class Version20161117071626 extends WallabagMigration
{ {
public function up(Schema $schema) public function up(Schema $schema): void
{ {
$share = $this->container $share = $this->container
->get('doctrine.orm.default_entity_manager') ->get('doctrine.orm.default_entity_manager')
->getConnection() ->getConnection()
->fetchArray('SELECT * FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'share_unmark'"); ->fetchOne('SELECT * FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'share_unmark'");
if (false === $share) { if (false === $share) {
$this->addSql('INSERT INTO ' . $this->getTable('craue_config_setting') . " (name, value, section) VALUES ('share_unmark', 0, 'entry')"); $this->addSql('INSERT INTO ' . $this->getTable('craue_config_setting') . " (name, value, section) VALUES ('share_unmark', 0, 'entry')");
@ -24,7 +24,7 @@ class Version20161117071626 extends WallabagMigration
$unmark = $this->container $unmark = $this->container
->get('doctrine.orm.default_entity_manager') ->get('doctrine.orm.default_entity_manager')
->getConnection() ->getConnection()
->fetchArray('SELECT * FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'unmark_url'"); ->fetchOne('SELECT * FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'unmark_url'");
if (false === $unmark) { if (false === $unmark) {
$this->addSql('INSERT INTO ' . $this->getTable('craue_config_setting') . " (name, value, section) VALUES ('unmark_url', 'https://unmark.it', 'entry')"); $this->addSql('INSERT INTO ' . $this->getTable('craue_config_setting') . " (name, value, section) VALUES ('unmark_url', 'https://unmark.it', 'entry')");
@ -33,7 +33,7 @@ class Version20161117071626 extends WallabagMigration
$this->skipIf(false !== $share && false !== $unmark, 'It seems that you already played this migration.'); $this->skipIf(false !== $share && false !== $unmark, 'It seems that you already played this migration.');
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
$this->addSql('DELETE FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'share_unmark';"); $this->addSql('DELETE FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'share_unmark';");
$this->addSql('DELETE FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'unmark_url';"); $this->addSql('DELETE FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'unmark_url';");

View file

@ -10,7 +10,7 @@ use Wallabag\CoreBundle\Doctrine\WallabagMigration;
*/ */
class Version20161118134328 extends WallabagMigration class Version20161118134328 extends WallabagMigration
{ {
public function up(Schema $schema) public function up(Schema $schema): void
{ {
$entryTable = $schema->getTable($this->getTable('entry')); $entryTable = $schema->getTable($this->getTable('entry'));
@ -22,7 +22,7 @@ class Version20161118134328 extends WallabagMigration
]); ]);
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
$entryTable = $schema->getTable($this->getTable('entry')); $entryTable = $schema->getTable($this->getTable('entry'));

View file

@ -10,19 +10,19 @@ use Wallabag\CoreBundle\Doctrine\WallabagMigration;
*/ */
class Version20161122144743 extends WallabagMigration class Version20161122144743 extends WallabagMigration
{ {
public function up(Schema $schema) public function up(Schema $schema): void
{ {
$access = $this->container $access = $this->container
->get('doctrine.orm.default_entity_manager') ->get('doctrine.orm.default_entity_manager')
->getConnection() ->getConnection()
->fetchArray('SELECT * FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'restricted_access'"); ->fetchOne('SELECT * FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'restricted_access'");
$this->skipIf(false !== $access, 'It seems that you already played this migration.'); $this->skipIf(false !== $access, 'It seems that you already played this migration.');
$this->addSql('INSERT INTO ' . $this->getTable('craue_config_setting') . " (name, value, section) VALUES ('restricted_access', 0, 'entry')"); $this->addSql('INSERT INTO ' . $this->getTable('craue_config_setting') . " (name, value, section) VALUES ('restricted_access', 0, 'entry')");
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
$this->addSql('DELETE FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'restricted_access';"); $this->addSql('DELETE FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'restricted_access';");
} }

View file

@ -18,7 +18,7 @@ use Wallabag\CoreBundle\Doctrine\WallabagMigration;
*/ */
class Version20161122203647 extends WallabagMigration class Version20161122203647 extends WallabagMigration
{ {
public function up(Schema $schema) public function up(Schema $schema): void
{ {
$userTable = $schema->getTable($this->getTable('user')); $userTable = $schema->getTable($this->getTable('user'));
@ -28,7 +28,7 @@ class Version20161122203647 extends WallabagMigration
$userTable->dropColumn('credentials_expired'); $userTable->dropColumn('credentials_expired');
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
$userTable = $schema->getTable($this->getTable('user')); $userTable = $schema->getTable($this->getTable('user'));

View file

@ -10,7 +10,7 @@ use Wallabag\CoreBundle\Doctrine\WallabagMigration;
*/ */
class Version20161128084725 extends WallabagMigration class Version20161128084725 extends WallabagMigration
{ {
public function up(Schema $schema) public function up(Schema $schema): void
{ {
$configTable = $schema->getTable($this->getTable('config')); $configTable = $schema->getTable($this->getTable('config'));
$this->skipIf($configTable->hasColumn('list_mode'), 'It seems that you already played this migration.'); $this->skipIf($configTable->hasColumn('list_mode'), 'It seems that you already played this migration.');
@ -18,7 +18,7 @@ class Version20161128084725 extends WallabagMigration
$configTable->addColumn('list_mode', 'integer', ['notnull' => false]); $configTable->addColumn('list_mode', 'integer', ['notnull' => false]);
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
$configTable = $schema->getTable($this->getTable('config')); $configTable = $schema->getTable($this->getTable('config'));
$configTable->dropColumn('list_mode'); $configTable->dropColumn('list_mode');

View file

@ -16,7 +16,7 @@ class Version20161128131503 extends WallabagMigration
'expires_at' => 'datetime', 'expires_at' => 'datetime',
]; ];
public function up(Schema $schema) public function up(Schema $schema): void
{ {
$userTable = $schema->getTable($this->getTable('user')); $userTable = $schema->getTable($this->getTable('user'));
@ -26,7 +26,7 @@ class Version20161128131503 extends WallabagMigration
} }
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
$userTable = $schema->getTable($this->getTable('user')); $userTable = $schema->getTable($this->getTable('user'));

View file

@ -10,7 +10,7 @@ use Wallabag\CoreBundle\Doctrine\WallabagMigration;
*/ */
class Version20161214094402 extends WallabagMigration class Version20161214094402 extends WallabagMigration
{ {
public function up(Schema $schema) public function up(Schema $schema): void
{ {
$entryTable = $schema->getTable($this->getTable('entry')); $entryTable = $schema->getTable($this->getTable('entry'));
@ -32,7 +32,7 @@ class Version20161214094402 extends WallabagMigration
} }
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
$entryTable = $schema->getTable($this->getTable('entry')); $entryTable = $schema->getTable($this->getTable('entry'));

View file

@ -12,7 +12,7 @@ class Version20161214094403 extends WallabagMigration
{ {
private $indexName = 'IDX_entry_uid'; private $indexName = 'IDX_entry_uid';
public function up(Schema $schema) public function up(Schema $schema): void
{ {
$entryTable = $schema->getTable($this->getTable('entry')); $entryTable = $schema->getTable($this->getTable('entry'));
$this->skipIf($entryTable->hasIndex($this->indexName), 'It seems that you already played this migration.'); $this->skipIf($entryTable->hasIndex($this->indexName), 'It seems that you already played this migration.');
@ -20,7 +20,7 @@ class Version20161214094403 extends WallabagMigration
$entryTable->addIndex(['uid'], $this->indexName); $entryTable->addIndex(['uid'], $this->indexName);
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
$entryTable = $schema->getTable($this->getTable('entry')); $entryTable = $schema->getTable($this->getTable('entry'));
$this->skipIf(false === $entryTable->hasIndex($this->indexName), 'It seems that you already played this migration.'); $this->skipIf(false === $entryTable->hasIndex($this->indexName), 'It seems that you already played this migration.');

View file

@ -13,7 +13,7 @@ class Version20170127093841 extends WallabagMigration
private $indexStarredName = 'IDX_entry_starred'; private $indexStarredName = 'IDX_entry_starred';
private $indexArchivedName = 'IDX_entry_archived'; private $indexArchivedName = 'IDX_entry_archived';
public function up(Schema $schema) public function up(Schema $schema): void
{ {
$entryTable = $schema->getTable($this->getTable('entry')); $entryTable = $schema->getTable($this->getTable('entry'));
$this->skipIf($entryTable->hasIndex($this->indexStarredName) && $entryTable->hasIndex($this->indexArchivedName), 'It seems that you already played this migration.'); $this->skipIf($entryTable->hasIndex($this->indexStarredName) && $entryTable->hasIndex($this->indexArchivedName), 'It seems that you already played this migration.');
@ -22,7 +22,7 @@ class Version20170127093841 extends WallabagMigration
$entryTable->addIndex(['is_archived'], $this->indexArchivedName); $entryTable->addIndex(['is_archived'], $this->indexArchivedName);
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
$entryTable = $schema->getTable($this->getTable('entry')); $entryTable = $schema->getTable($this->getTable('entry'));
$this->skipIf(false === $entryTable->hasIndex($this->indexStarredName) && false === $entryTable->hasIndex($this->indexArchivedName), 'It seems that you already played this migration.'); $this->skipIf(false === $entryTable->hasIndex($this->indexStarredName) && false === $entryTable->hasIndex($this->indexArchivedName), 'It seems that you already played this migration.');

View file

@ -10,12 +10,12 @@ use Wallabag\CoreBundle\Doctrine\WallabagMigration;
*/ */
class Version20170327194233 extends WallabagMigration class Version20170327194233 extends WallabagMigration
{ {
public function up(Schema $schema) public function up(Schema $schema): void
{ {
$scuttle = $this->container $scuttle = $this->container
->get('doctrine.orm.default_entity_manager') ->get('doctrine.orm.default_entity_manager')
->getConnection() ->getConnection()
->fetchArray('SELECT * FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'share_scuttle'"); ->fetchOne('SELECT * FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'share_scuttle'");
$this->skipIf(false !== $scuttle, 'It seems that you already played this migration.'); $this->skipIf(false !== $scuttle, 'It seems that you already played this migration.');
@ -23,7 +23,7 @@ class Version20170327194233 extends WallabagMigration
$this->addSql('INSERT INTO ' . $this->getTable('craue_config_setting') . " (name, value, section) VALUES ('scuttle_url', 'http://scuttle.org', 'entry')"); $this->addSql('INSERT INTO ' . $this->getTable('craue_config_setting') . " (name, value, section) VALUES ('scuttle_url', 'http://scuttle.org', 'entry')");
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
$this->addSql('DELETE FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'share_scuttle';"); $this->addSql('DELETE FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'share_scuttle';");
$this->addSql('DELETE FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'scuttle_url';"); $this->addSql('DELETE FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'scuttle_url';");

View file

@ -10,7 +10,7 @@ use Wallabag\CoreBundle\Doctrine\WallabagMigration;
*/ */
class Version20170405182620 extends WallabagMigration class Version20170405182620 extends WallabagMigration
{ {
public function up(Schema $schema) public function up(Schema $schema): void
{ {
$entryTable = $schema->getTable($this->getTable('entry')); $entryTable = $schema->getTable($this->getTable('entry'));
@ -27,7 +27,7 @@ class Version20170405182620 extends WallabagMigration
]); ]);
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
$entryTable = $schema->getTable($this->getTable('entry')); $entryTable = $schema->getTable($this->getTable('entry'));

View file

@ -10,7 +10,7 @@ use Wallabag\CoreBundle\Doctrine\WallabagMigration;
*/ */
class Version20170407200919 extends WallabagMigration class Version20170407200919 extends WallabagMigration
{ {
public function up(Schema $schema) public function up(Schema $schema): void
{ {
$entryTable = $schema->getTable($this->getTable('entry')); $entryTable = $schema->getTable($this->getTable('entry'));
$this->skipIf(!$entryTable->hasColumn('is_public'), 'It seems that you already played this migration.'); $this->skipIf(!$entryTable->hasColumn('is_public'), 'It seems that you already played this migration.');
@ -18,7 +18,7 @@ class Version20170407200919 extends WallabagMigration
$entryTable->dropColumn('is_public'); $entryTable->dropColumn('is_public');
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
$entryTable = $schema->getTable($this->getTable('entry')); $entryTable = $schema->getTable($this->getTable('entry'));
$this->skipIf($entryTable->hasColumn('is_public'), 'It seems that you already played this migration.'); $this->skipIf($entryTable->hasColumn('is_public'), 'It seems that you already played this migration.');

View file

@ -10,17 +10,17 @@ use Wallabag\CoreBundle\Doctrine\WallabagMigration;
*/ */
class Version20170420134133 extends WallabagMigration class Version20170420134133 extends WallabagMigration
{ {
public function up(Schema $schema) public function up(Schema $schema): void
{ {
$this->addSql('DELETE FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'download_pictures';"); $this->addSql('DELETE FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'download_pictures';");
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
$downloadPictures = $this->container $downloadPictures = $this->container
->get('doctrine.orm.default_entity_manager') ->get('doctrine.orm.default_entity_manager')
->getConnection() ->getConnection()
->fetchArray('SELECT * FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'download_pictures'"); ->fetchOne('SELECT * FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'download_pictures'");
$this->skipIf(false !== $downloadPictures, 'It seems that you already played this migration.'); $this->skipIf(false !== $downloadPictures, 'It seems that you already played this migration.');

View file

@ -10,7 +10,7 @@ use Wallabag\CoreBundle\Doctrine\WallabagMigration;
*/ */
class Version20170501115751 extends WallabagMigration class Version20170501115751 extends WallabagMigration
{ {
public function up(Schema $schema) public function up(Schema $schema): void
{ {
$this->skipIf($schema->hasTable($this->getTable('site_credential')), 'It seems that you already played this migration.'); $this->skipIf($schema->hasTable($this->getTable('site_credential')), 'It seems that you already played this migration.');
@ -31,7 +31,7 @@ class Version20170501115751 extends WallabagMigration
} }
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
$schema->dropTable($this->getTable('site_credential')); $schema->dropTable($this->getTable('site_credential'));
} }

View file

@ -17,7 +17,7 @@ class Version20170510082609 extends WallabagMigration
'email_canonical', 'email_canonical',
]; ];
public function up(Schema $schema) public function up(Schema $schema): void
{ {
$this->skipIf('mysql' !== $this->connection->getDatabasePlatform()->getName(), 'This migration only apply to MySQL'); $this->skipIf('mysql' !== $this->connection->getDatabasePlatform()->getName(), 'This migration only apply to MySQL');
@ -26,7 +26,7 @@ class Version20170510082609 extends WallabagMigration
} }
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
$this->skipIf('mysql' !== $this->connection->getDatabasePlatform()->getName(), 'This migration only apply to MySQL'); $this->skipIf('mysql' !== $this->connection->getDatabasePlatform()->getName(), 'This migration only apply to MySQL');

View file

@ -10,7 +10,7 @@ use Wallabag\CoreBundle\Doctrine\WallabagMigration;
*/ */
class Version20170511115400 extends WallabagMigration class Version20170511115400 extends WallabagMigration
{ {
public function up(Schema $schema) public function up(Schema $schema): void
{ {
$entryTable = $schema->getTable($this->getTable('entry')); $entryTable = $schema->getTable($this->getTable('entry'));
@ -21,7 +21,7 @@ class Version20170511115400 extends WallabagMigration
]); ]);
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
$entryTable = $schema->getTable($this->getTable('entry')); $entryTable = $schema->getTable($this->getTable('entry'));

View file

@ -11,7 +11,7 @@ use Wallabag\CoreBundle\Doctrine\WallabagMigration;
*/ */
class Version20170511211659 extends WallabagMigration class Version20170511211659 extends WallabagMigration
{ {
public function up(Schema $schema) public function up(Schema $schema): void
{ {
switch ($this->connection->getDatabasePlatform()->getName()) { switch ($this->connection->getDatabasePlatform()->getName()) {
case 'sqlite': case 'sqlite':
@ -62,7 +62,7 @@ EOD
} }
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
$tableName = $this->getTable('annotation'); $tableName = $this->getTable('annotation');

View file

@ -10,19 +10,19 @@ use Wallabag\CoreBundle\Doctrine\WallabagMigration;
*/ */
class Version20170602075214 extends WallabagMigration class Version20170602075214 extends WallabagMigration
{ {
public function up(Schema $schema) public function up(Schema $schema): void
{ {
$apiUserRegistration = $this->container $apiUserRegistration = $this->container
->get('doctrine.orm.default_entity_manager') ->get('doctrine.orm.default_entity_manager')
->getConnection() ->getConnection()
->fetchArray('SELECT * FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'api_user_registration'"); ->fetchOne('SELECT * FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'api_user_registration'");
$this->skipIf(false !== $apiUserRegistration, 'It seems that you already played this migration.'); $this->skipIf(false !== $apiUserRegistration, 'It seems that you already played this migration.');
$this->addSql('INSERT INTO ' . $this->getTable('craue_config_setting') . " (name, value, section) VALUES ('api_user_registration', '0', 'api')"); $this->addSql('INSERT INTO ' . $this->getTable('craue_config_setting') . " (name, value, section) VALUES ('api_user_registration', '0', 'api')");
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
$this->addSql('DELETE FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'api_user_registration';"); $this->addSql('DELETE FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'api_user_registration';");
} }

View file

@ -11,19 +11,21 @@ use Wallabag\CoreBundle\Doctrine\WallabagMigration;
*/ */
class Version20170606155640 extends WallabagMigration class Version20170606155640 extends WallabagMigration
{ {
public function up(Schema $schema) public function up(Schema $schema): void
{ {
$this->skipIf(!$schema->hasTable($this->getTable('craue_config_setting')), 'Table already renamed');
$apiUserRegistration = $this->container $apiUserRegistration = $this->container
->get('doctrine.orm.default_entity_manager') ->get('doctrine.orm.default_entity_manager')
->getConnection() ->getConnection()
->fetchArray('SELECT * FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'wallabag_url'"); ->fetchOne('SELECT * FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'wallabag_url'");
$this->skipIf(false === $apiUserRegistration, 'It seems that you already played this migration.'); $this->skipIf(false === $apiUserRegistration, 'It seems that you already played this migration.');
$this->addSql('DELETE FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'wallabag_url'"); $this->addSql('DELETE FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'wallabag_url'");
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
$this->addSql('INSERT INTO ' . $this->getTable('craue_config_setting') . " (name, value, section) VALUES ('wallabag_url', 'wallabag.me', 'misc')"); $this->addSql('INSERT INTO ' . $this->getTable('craue_config_setting') . " (name, value, section) VALUES ('wallabag_url', 'wallabag.me', 'misc')");
} }

View file

@ -10,7 +10,7 @@ use Wallabag\CoreBundle\Doctrine\WallabagMigration;
*/ */
class Version20170719231144 extends WallabagMigration class Version20170719231144 extends WallabagMigration
{ {
public function up(Schema $schema) public function up(Schema $schema): void
{ {
$this->skipIf('sqlite' === $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'mysql\' or \'postgresql\'.'); $this->skipIf('sqlite' === $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'mysql\' or \'postgresql\'.');
@ -21,13 +21,12 @@ class Version20170719231144 extends WallabagMigration
GROUP BY LOWER(label) GROUP BY LOWER(label)
HAVING COUNT(*) > 1' HAVING COUNT(*) > 1'
); );
$dupTags->execute();
foreach ($dupTags->fetchAll() as $duplicates) { foreach ($dupTags->fetchAllAssociative() as $duplicates) {
$label = $duplicates['lower_label']; $label = $duplicates['lower_label'];
// Retrieve all duplicate tags for a given tag // Retrieve all duplicate tags for a given tag
$tags = $this->connection->executeQuery(' $tags = $this->connection->query('
SELECT id SELECT id
FROM ' . $this->getTable('tag') . ' FROM ' . $this->getTable('tag') . '
WHERE LOWER(label) = :label WHERE LOWER(label) = :label
@ -41,7 +40,7 @@ class Version20170719231144 extends WallabagMigration
$newId = null; $newId = null;
$ids = []; $ids = [];
foreach ($tags->fetchAll() as $tag) { foreach ($tags->fetchAllAssociative() as $tag) {
// Ignore the first tag as we use it as the new reference tag // Ignore the first tag as we use it as the new reference tag
if ($first) { if ($first) {
$first = false; $first = false;
@ -86,7 +85,7 @@ class Version20170719231144 extends WallabagMigration
); );
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
throw new SkipMigrationException('Too complex ...'); throw new SkipMigrationException('Too complex ...');
} }

View file

@ -10,7 +10,7 @@ use Wallabag\CoreBundle\Doctrine\WallabagMigration;
*/ */
class Version20170824113337 extends WallabagMigration class Version20170824113337 extends WallabagMigration
{ {
public function up(Schema $schema) public function up(Schema $schema): void
{ {
$entryTable = $schema->getTable($this->getTable('entry')); $entryTable = $schema->getTable($this->getTable('entry'));
@ -21,7 +21,7 @@ class Version20170824113337 extends WallabagMigration
]); ]);
} }
public function postUp(Schema $schema) public function postUp(Schema $schema): void
{ {
$entryTable = $schema->getTable($this->getTable('entry')); $entryTable = $schema->getTable($this->getTable('entry'));
$this->skipIf(!$entryTable->hasColumn('starred_at'), 'Unable to add starred_at colum'); $this->skipIf(!$entryTable->hasColumn('starred_at'), 'Unable to add starred_at colum');
@ -34,7 +34,7 @@ class Version20170824113337 extends WallabagMigration
); );
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
$entryTable = $schema->getTable($this->getTable('entry')); $entryTable = $schema->getTable($this->getTable('entry'));

View file

@ -10,7 +10,7 @@ use Wallabag\CoreBundle\Doctrine\WallabagMigration;
*/ */
class Version20171008195606 extends WallabagMigration class Version20171008195606 extends WallabagMigration
{ {
public function up(Schema $schema) public function up(Schema $schema): void
{ {
$this->skipIf('sqlite' === $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'mysql\' or \'postgresql\'.'); $this->skipIf('sqlite' === $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'mysql\' or \'postgresql\'.');
@ -26,7 +26,7 @@ class Version20171008195606 extends WallabagMigration
} }
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
$this->skipIf('sqlite' === $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'mysql\' or \'postgresql\'.'); $this->skipIf('sqlite' === $this->connection->getDatabasePlatform()->getName(), 'Migration can only be executed safely on \'mysql\' or \'postgresql\'.');

View file

@ -10,7 +10,7 @@ use Wallabag\CoreBundle\Doctrine\WallabagMigration;
*/ */
class Version20171105202000 extends WallabagMigration class Version20171105202000 extends WallabagMigration
{ {
public function up(Schema $schema) public function up(Schema $schema): void
{ {
$entryTable = $schema->getTable($this->getTable('entry')); $entryTable = $schema->getTable($this->getTable('entry'));
@ -21,7 +21,7 @@ class Version20171105202000 extends WallabagMigration
]); ]);
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
$entryTable = $schema->getTable($this->getTable('entry')); $entryTable = $schema->getTable($this->getTable('entry'));

View file

@ -10,19 +10,19 @@ use Wallabag\CoreBundle\Doctrine\WallabagMigration;
*/ */
class Version20171120163128 extends WallabagMigration class Version20171120163128 extends WallabagMigration
{ {
public function up(Schema $schema) public function up(Schema $schema): void
{ {
$storeArticleHeaders = $this->container $storeArticleHeaders = $this->container
->get('doctrine.orm.default_entity_manager') ->get('doctrine.orm.default_entity_manager')
->getConnection() ->getConnection()
->fetchArray('SELECT * FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'store_article_headers'"); ->fetchOne('SELECT * FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'store_article_headers'");
$this->skipIf(false !== $storeArticleHeaders, 'It seems that you already played this migration.'); $this->skipIf(false !== $storeArticleHeaders, 'It seems that you already played this migration.');
$this->addSql('INSERT INTO ' . $this->getTable('craue_config_setting') . " (name, value, section) VALUES ('store_article_headers', '0', 'entry')"); $this->addSql('INSERT INTO ' . $this->getTable('craue_config_setting') . " (name, value, section) VALUES ('store_article_headers', '0', 'entry')");
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
$this->addSql('DELETE FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'store_article_headers';"); $this->addSql('DELETE FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'store_article_headers';");
} }

View file

@ -10,19 +10,19 @@ use Wallabag\CoreBundle\Doctrine\WallabagMigration;
*/ */
class Version20171125164500 extends WallabagMigration class Version20171125164500 extends WallabagMigration
{ {
public function up(Schema $schema) public function up(Schema $schema): void
{ {
$shaarliShareOriginUrl = $this->container $shaarliShareOriginUrl = $this->container
->get('doctrine.orm.default_entity_manager') ->get('doctrine.orm.default_entity_manager')
->getConnection() ->getConnection()
->fetchArray('SELECT * FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'shaarli_share_origin_url'"); ->fetchOne('SELECT * FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'shaarli_share_origin_url'");
$this->skipIf(false !== $shaarliShareOriginUrl, 'It seems that you already played this migration.'); $this->skipIf(false !== $shaarliShareOriginUrl, 'It seems that you already played this migration.');
$this->addSql('INSERT INTO ' . $this->getTable('craue_config_setting') . " (name, value, section) VALUES ('shaarli_share_origin_url', '0', 'entry')"); $this->addSql('INSERT INTO ' . $this->getTable('craue_config_setting') . " (name, value, section) VALUES ('shaarli_share_origin_url', '0', 'entry')");
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
$this->addSql('DELETE FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'shaarli_share_origin_url';"); $this->addSql('DELETE FROM ' . $this->getTable('craue_config_setting') . " WHERE name = 'shaarli_share_origin_url';");
} }

View file

@ -10,7 +10,7 @@ use Wallabag\CoreBundle\Doctrine\WallabagMigration;
*/ */
class Version20180405182455 extends WallabagMigration class Version20180405182455 extends WallabagMigration
{ {
public function up(Schema $schema) public function up(Schema $schema): void
{ {
$entryTable = $schema->getTable($this->getTable('entry')); $entryTable = $schema->getTable($this->getTable('entry'));
@ -21,7 +21,7 @@ class Version20180405182455 extends WallabagMigration
]); ]);
} }
public function postUp(Schema $schema) public function postUp(Schema $schema): void
{ {
$entryTable = $schema->getTable($this->getTable('entry')); $entryTable = $schema->getTable($this->getTable('entry'));
$this->skipIf(!$entryTable->hasColumn('archived_at'), 'Unable to add archived_at colum'); $this->skipIf(!$entryTable->hasColumn('archived_at'), 'Unable to add archived_at colum');
@ -34,7 +34,7 @@ class Version20180405182455 extends WallabagMigration
); );
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
$entryTable = $schema->getTable($this->getTable('entry')); $entryTable = $schema->getTable($this->getTable('entry'));

View file

@ -10,7 +10,7 @@ use Wallabag\CoreBundle\Doctrine\WallabagMigration;
*/ */
class Version20181128203230 extends WallabagMigration class Version20181128203230 extends WallabagMigration
{ {
public function up(Schema $schema) public function up(Schema $schema): void
{ {
$this->skipIf('mysql' !== $this->connection->getDatabasePlatform()->getName(), 'This migration can only be applied on \'mysql\'.'); $this->skipIf('mysql' !== $this->connection->getDatabasePlatform()->getName(), 'This migration can only be applied on \'mysql\'.');
@ -25,7 +25,7 @@ class Version20181128203230 extends WallabagMigration
$this->addSql('ALTER TABLE ' . $this->getTable('craue_config_setting') . ' CHANGE `value` `value` varchar(191)'); $this->addSql('ALTER TABLE ' . $this->getTable('craue_config_setting') . ' CHANGE `value` `value` varchar(191)');
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
$this->skipIf('mysql' !== $this->connection->getDatabasePlatform()->getName(), 'This migration can only be applied on \'mysql\'.'); $this->skipIf('mysql' !== $this->connection->getDatabasePlatform()->getName(), 'This migration can only be applied on \'mysql\'.');

View file

@ -118,13 +118,13 @@ final class Version20190129120000 extends WallabagMigration
], ],
]; ];
public function up(Schema $schema) public function up(Schema $schema): void
{ {
foreach ($this->settings as $setting) { foreach ($this->settings as $setting) {
$settingEnabled = $this->container $settingEnabled = $this->container
->get('doctrine.orm.default_entity_manager') ->get('doctrine.orm.default_entity_manager')
->getConnection() ->getConnection()
->fetchArray('SELECT * FROM ' . $this->getTable('craue_config_setting') . " WHERE name = '" . $setting['name'] . "'"); ->fetchOne('SELECT * FROM ' . $this->getTable('craue_config_setting') . " WHERE name = '" . $setting['name'] . "'");
if (false !== $settingEnabled) { if (false !== $settingEnabled) {
continue; continue;
@ -134,7 +134,7 @@ final class Version20190129120000 extends WallabagMigration
} }
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
$this->skipIf(true, 'These settings are required and should not be removed.'); $this->skipIf(true, 'These settings are required and should not be removed.');
} }

View file

@ -10,7 +10,7 @@ use Wallabag\CoreBundle\Doctrine\WallabagMigration;
*/ */
class Version20190401105353 extends WallabagMigration class Version20190401105353 extends WallabagMigration
{ {
public function up(Schema $schema) public function up(Schema $schema): void
{ {
$entryTable = $schema->getTable($this->getTable('entry')); $entryTable = $schema->getTable($this->getTable('entry'));
@ -24,7 +24,7 @@ class Version20190401105353 extends WallabagMigration
$entryTable->addIndex(['user_id', 'hashed_url'], 'hashed_url_user_id', [], ['lengths' => [null, 40]]); $entryTable->addIndex(['user_id', 'hashed_url'], 'hashed_url_user_id', [], ['lengths' => [null, 40]]);
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
$entryTable = $schema->getTable($this->getTable('entry')); $entryTable = $schema->getTable($this->getTable('entry'));

View file

@ -10,7 +10,7 @@ use Wallabag\CoreBundle\Doctrine\WallabagMigration;
*/ */
class Version20190601125843 extends WallabagMigration class Version20190601125843 extends WallabagMigration
{ {
public function up(Schema $schema) public function up(Schema $schema): void
{ {
$entryTable = $schema->getTable($this->getTable('entry')); $entryTable = $schema->getTable($this->getTable('entry'));
@ -31,7 +31,7 @@ class Version20190601125843 extends WallabagMigration
$entryTable->addIndex(['user_id', 'hashed_given_url'], 'hashed_given_url_user_id', [], ['lengths' => [null, 40]]); $entryTable->addIndex(['user_id', 'hashed_given_url'], 'hashed_given_url_user_id', [], ['lengths' => [null, 40]]);
} }
public function down(Schema $schema) public function down(Schema $schema): void
{ {
$entryTable = $schema->getTable($this->getTable('entry')); $entryTable = $schema->getTable($this->getTable('entry'));

View file

@ -48,7 +48,7 @@ final class Version20190826204730 extends WallabagMigration
$previous_rule = $this->container $previous_rule = $this->container
->get('doctrine.orm.default_entity_manager') ->get('doctrine.orm.default_entity_manager')
->getConnection() ->getConnection()
->fetchArray('SELECT * FROM ' . $this->getTable('ignore_origin_instance_rule') . " WHERE rule = '" . $entity['rule'] . "'"); ->fetchOne('SELECT * FROM ' . $this->getTable('ignore_origin_instance_rule') . " WHERE rule = '" . $entity['rule'] . "'");
if (false === $previous_rule) { if (false === $previous_rule) {
$this->addSql('INSERT INTO ' . $this->getTable('ignore_origin_instance_rule') . " (rule) VALUES ('" . $entity['rule'] . "');"); $this->addSql('INSERT INTO ' . $this->getTable('ignore_origin_instance_rule') . " (rule) VALUES ('" . $entity['rule'] . "');");

View file

@ -0,0 +1,62 @@
<?php
namespace Application\Migrations;
use Doctrine\DBAL\Schema\Schema;
use Wallabag\CoreBundle\Doctrine\WallabagMigration;
/**
* Remove the deprecated (and removed in DBAL v3) `json_array` type.
*/
final class Version20221221092957 extends WallabagMigration
{
public function up(Schema $schema): void
{
$userTable = $this->getTable('user');
switch ($this->connection->getDatabasePlatform()->getName()) {
case 'sqlite':
$this->addSql('CREATE TEMPORARY TABLE __temp__wallabag_user AS SELECT id, username, username_canonical, email, email_canonical, enabled, password, last_login, password_requested_at, name, created_at, updated_at, authCode, emailTwoFactor, salt, confirmation_token, roles, googleAuthenticatorSecret, backupCodes FROM ' . $userTable);
$this->addSql('DROP TABLE ' . $userTable);
$this->addSql('CREATE TABLE ' . $userTable . ' (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, username VARCHAR(180) NOT NULL, username_canonical VARCHAR(180) NOT NULL, email VARCHAR(180) NOT NULL, email_canonical VARCHAR(180) NOT NULL, enabled BOOLEAN NOT NULL, salt VARCHAR(255) DEFAULT NULL, password VARCHAR(255) NOT NULL, last_login DATETIME DEFAULT NULL, confirmation_token VARCHAR(180) DEFAULT NULL, password_requested_at DATETIME DEFAULT NULL, roles CLOB NOT NULL --(DC2Type:array)
, name CLOB DEFAULT NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, authCode INTEGER DEFAULT NULL, googleAuthenticatorSecret VARCHAR(255) DEFAULT NULL, backupCodes CLOB DEFAULT NULL --(DC2Type:json)
, emailTwoFactor BOOLEAN NOT NULL)');
$this->addSql('INSERT INTO ' . $userTable . ' (id, username, username_canonical, email, email_canonical, enabled, password, last_login, password_requested_at, name, created_at, updated_at, authCode, emailTwoFactor, salt, confirmation_token, roles, googleAuthenticatorSecret, backupCodes) SELECT id, username, username_canonical, email, email_canonical, enabled, password, last_login, password_requested_at, name, created_at, updated_at, authCode, emailTwoFactor, salt, confirmation_token, roles, googleAuthenticatorSecret, backupCodes FROM __temp__wallabag_user');
$this->addSql('DROP TABLE __temp__wallabag_user');
$this->addSql('CREATE UNIQUE INDEX UNIQ_1D63E7E592FC23A8 ON ' . $userTable . ' (username_canonical)');
$this->addSql('CREATE UNIQUE INDEX UNIQ_1D63E7E5A0D96FBF ON ' . $userTable . ' (email_canonical)');
$this->addSql('CREATE UNIQUE INDEX UNIQ_1D63E7E5C05FB297 ON ' . $userTable . ' (confirmation_token)');
break;
case 'mysql':
$this->addSql('ALTER TABLE ' . $userTable . ' CHANGE backupCodes backupCodes JSON DEFAULT NULL');
break;
case 'postgresql':
$this->addSql('ALTER TABLE ' . $userTable . ' ALTER backupcodes TYPE JSON USING backupcodes::json');
break;
}
}
public function down(Schema $schema): void
{
$userTable = $this->getTable('user');
switch ($this->connection->getDatabasePlatform()->getName()) {
case 'sqlite':
$this->addSql('CREATE TEMPORARY TABLE __temp__wallabag_user AS SELECT id, username, username_canonical, email, email_canonical, enabled, salt, password, last_login, confirmation_token, password_requested_at, roles, name, created_at, updated_at, authCode, googleAuthenticatorSecret, backupCodes, emailTwoFactor FROM ' . $userTable);
$this->addSql('DROP TABLE ' . $userTable);
$this->addSql('CREATE TABLE ' . $userTable . ' (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, username VARCHAR(180) NOT NULL, username_canonical VARCHAR(180) NOT NULL, email VARCHAR(180) NOT NULL, email_canonical VARCHAR(180) NOT NULL, enabled BOOLEAN NOT NULL, salt VARCHAR(255) DEFAULT NULL, password VARCHAR(255) NOT NULL, last_login DATETIME DEFAULT NULL, confirmation_token VARCHAR(180) DEFAULT NULL, password_requested_at DATETIME DEFAULT NULL, roles CLOB NOT NULL --(DC2Type:array)
, name CLOB DEFAULT NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, authCode INTEGER DEFAULT NULL, googleAuthenticatorSecret VARCHAR(255) DEFAULT NULL, backupCodes CLOB DEFAULT NULL --(DC2Type:json_array)
, emailTwoFactor BOOLEAN NOT NULL)');
$this->addSql('INSERT INTO ' . $userTable . ' (id, username, username_canonical, email, email_canonical, enabled, salt, password, last_login, confirmation_token, password_requested_at, roles, name, created_at, updated_at, authCode, googleAuthenticatorSecret, backupCodes, emailTwoFactor) SELECT id, username, username_canonical, email, email_canonical, enabled, salt, password, last_login, confirmation_token, password_requested_at, roles, name, created_at, updated_at, authCode, googleAuthenticatorSecret, backupCodes, emailTwoFactor FROM __temp__wallabag_user');
$this->addSql('DROP TABLE __temp__wallabag_user');
$this->addSql('CREATE UNIQUE INDEX UNIQ_1D63E7E592FC23A8 ON ' . $userTable . ' (username_canonical)');
$this->addSql('CREATE UNIQUE INDEX UNIQ_1D63E7E5A0D96FBF ON ' . $userTable . ' (email_canonical)');
$this->addSql('CREATE UNIQUE INDEX UNIQ_1D63E7E5C05FB297 ON ' . $userTable . ' (confirmation_token)');
break;
case 'mysql':
$this->addSql('ALTER TABLE ' . $userTable . ' CHANGE backupCodes backupCodes JSON DEFAULT NULL COMMENT \'(DC2Type:json_array)\'');
break;
case 'postgresql':
$this->addSql('ALTER TABLE ' . $userTable . ' ALTER backupCodes TYPE TEXT');
break;
}
}
}

View file

@ -0,0 +1,30 @@
<?php
namespace Application\Migrations;
use Doctrine\DBAL\Schema\Schema;
use Wallabag\CoreBundle\Doctrine\WallabagMigration;
/**
* Added a new setting to display or not thumbnails.
*/
final class Version20230613121354 extends WallabagMigration
{
public function up(Schema $schema): void
{
$configTable = $schema->getTable($this->getTable('config'));
$this->skipIf($configTable->hasColumn('display_thumbnails'), 'It seems that you already played this migration.');
$configTable->addColumn('display_thumbnails', 'integer', [
'default' => 1,
'notnull' => false,
]);
}
public function down(Schema $schema): void
{
$configTable = $schema->getTable($this->getTable('config'));
$configTable->dropColumn('display_thumbnails');
}
}

View file

@ -54,7 +54,7 @@
} }
a { a {
border-bottom: 1px dotted $blueAccentColor; border-bottom: 1px dotted $blue-accent-color;
text-decoration: none; text-decoration: none;
} }
@ -105,14 +105,15 @@
margin: 2.1rem 0 0.68rem; margin: 2.1rem 0 0.68rem;
} }
aside { .entry-info {
.tools { .tools {
display: flex; display: flex;
flex-flow: row wrap; margin: 8px 5px 5px;
flex-wrap: wrap;
.stats { .stats {
margin: 0;
font-size: 0.7em; font-size: 0.7em;
margin: 8px 5px 5px;
li { li {
display: inline-flex; display: inline-flex;
@ -133,18 +134,21 @@
} }
.tags { .tags {
float: right; display: flex;
margin: 5px 15px 10px; margin: 0;
align-items: center;
gap: 5px;
} }
} }
.chip { .chip {
background-color: #9e9e9e; display: flex;
padding: 0 15px 0 10px; margin: 0;
margin: auto 2px; padding: 0;
border-radius: 6px; height: 25px;
height: 18px; line-height: 25px;
line-height: 18px; align-items: center;
background-color: transparent;
a, a,
i { i {
@ -152,15 +156,45 @@
} }
i.material-icons { i.material-icons {
float: right;
font-size: 16px; font-size: 16px;
line-height: 18px; vertical-align: sub;
padding-left: 8px;
} }
} }
.chip-label {
padding-left: 10px;
padding-right: 5px;
background-color: #9e9e9e;
border-radius: 6px 0 0 6px;
}
.chip-action {
padding: 0 5px;
background-color: #868686;
border-radius: 0 6px 6px 0;
}
.chip-label,
.chip-action {
min-width: 30px;
text-align: center;
}
.chip-label:hover,
.chip-label:active,
.chip-label:focus,
.chip-action:hover,
.chip-action:active,
.chip-action:focus {
background-color: #5e5e5e;
}
} }
} }
.entry-info {
margin-bottom: 40px;
}
.reader-mode { .reader-mode {
width: 70px !important; width: 70px !important;
transition: width 0.2s ease; transition: width 0.2s ease;
@ -200,3 +234,28 @@
margin: 0; margin: 0;
z-index: 9999; z-index: 9999;
} }
@media only screen and (max-width: 640px) {
.entry-info {
margin-bottom: 20px;
}
#article .entry-info .tools {
margin-left: 0;
margin-right: 0;
}
#article .entry-info .tools .tags {
gap: 10px;
}
#article .entry-info .chip {
height: 32px;
line-height: 32px;
}
#article .entry-info .chip-label,
#article .entry-info .chip-action {
min-width: 40px;
}
}

View file

@ -73,7 +73,7 @@ main {
.card-entry-labels-hidden li { .card-entry-labels-hidden li {
display: inline-block; display: inline-block;
background-color: $blueAccentColor; background-color: $blue-accent-color;
margin: 0 5px; margin: 0 5px;
padding: 5px 12px; padding: 5px 12px;
border-radius: 3px; border-radius: 3px;
@ -85,10 +85,6 @@ main {
white-space: nowrap; white-space: nowrap;
} }
.card-content .estimatedTime {
margin-bottom: 10px;
}
.card-action { .card-action {
padding: 10px 10px 10px 15px; padding: 10px 10px 10px 15px;
@ -160,7 +156,7 @@ a.original:not(.waves-effect) {
.card-tag-labels li { .card-tag-labels li {
margin: 10px 10px 10px auto; margin: 10px 10px 10px auto;
padding: 5px 12px 5px 16px !important; padding: 5px 12px 5px 16px !important;
background-color: $blueAccentColor; background-color: $blue-accent-color;
border-radius: 3px; border-radius: 3px;
color: #fff; color: #fff;
cursor: default; cursor: default;
@ -251,7 +247,7 @@ a.original:not(.waves-effect) {
} }
.chip { .chip {
background-color: $blueAccentColor; background-color: $blue-accent-color;
padding: 0 7px; padding: 0 7px;
margin: auto 1px; margin: auto 1px;
border-radius: 6px; border-radius: 6px;
@ -315,10 +311,19 @@ a.original:not(.waves-effect) {
color: #fff !important; color: #fff !important;
} }
.settings .div_tabs { .settings .tabs-container {
padding-bottom: 15px; padding-bottom: 15px;
} }
.settings .settings-checkbox-col {
padding: 0;
}
.settings .settings-checkbox-label {
margin-bottom: 20px;
height: 3rem;
}
.entries-row { .entries-row {
display: grid; display: grid;
margin: 0.4rem 0 0; margin: 0.4rem 0 0;

View file

@ -1,6 +1,8 @@
.dark-theme { .dark-theme {
body, body {
main #content, background-color: #101010;
}
#article, #article,
.card, .card,
.card-panel, .card-panel,
@ -10,13 +12,11 @@
.collapsible-header, .collapsible-header,
.collection, .collection,
.dropdown-content, .dropdown-content,
.nav-panel-add,
.nav-panel-search,
.side-nav, .side-nav,
.side-nav .collapsible-body, .side-nav .collapsible-body,
.side-nav.fixed .collapsible-body, .side-nav.fixed .collapsible-body,
.tabs { .tabs {
background-color: #121212; background-color: #131716;
} }
table.striped > tbody > tr:nth-child(2n+1), table.striped > tbody > tr:nth-child(2n+1),
@ -50,7 +50,7 @@
background-color: #272727; background-color: #272727;
} }
main #content, #content,
#article article, #article article,
#article article h1, #article article h1,
#article article h2, #article article h2,
@ -59,7 +59,8 @@
#article article h5, #article article h5,
#article article h6, #article article h6,
.dropdown-content li > a, .dropdown-content li > a,
.results a, .nav-panels .input-field input:focus,
.results-item,
.side-nav li > a, .side-nav li > a,
.side-nav li > a > i.material-icons { .side-nav li > a > i.material-icons {
color: #dfdfdf; color: #dfdfdf;
@ -67,18 +68,19 @@
.cyan, .cyan,
.cyan.darken-1, .cyan.darken-1,
.cyan.darken-2 { .cyan.darken-2,
.nav-panel-add,
.nav-panel-search {
background-color: #1d1d1d !important; background-color: #1d1d1d !important;
} }
.grey-text.text-darken-4 { .grey-text.text-darken-4,
.nav-panel-item .add,
.nav-panel-item .search,
.nav-panels .close {
color: #dfdfdf !important; color: #dfdfdf !important;
} }
#article .chip {
background-color: #373737;
}
.side-nav li.active { .side-nav li.active {
background-color: #2f2f2f; background-color: #2f2f2f;
} }
@ -120,11 +122,20 @@
} }
.hljs, .hljs,
#article pre.hljs { #article pre {
color: #abb2bf; color: #abb2bf;
background-color: #282c34; background-color: #282c34;
} }
nav input {
color: #abb2bf;
}
.input-field.nav-panel-add.disabled,
.input-field.nav-panel-add.disabled input {
background-color: transparent;
}
@media only screen and (min-width: 992px) { @media only screen and (min-width: 992px) {
#article { #article {
background-color: #101010; background-color: #101010;

View file

@ -2,40 +2,73 @@
* Entries * Entries
* ========================================================================== */ * ========================================================================== */
.mass-buttons { .mass-action-toggle {
margin: 10px 5px 10px 20px; display: inline-flex;
background-color: transparent;
border: none;
cursor: pointer;
#selectAll { &:focus {
position: relative; background-color: transparent;
opacity: initial;
left: 0;
}
span {
padding: 3px;
}
button {
i {
font-size: 15px;
}
height: 24px;
line-height: 24px;
padding: 0 0.5rem;
margin-right: 0.75rem;
} }
} }
.card-stacked { .mass-action {
input[type="checkbox"] { margin: 10px 5px 10px 20px;
position: relative; }
opacity: initial;
left: 0;
}
.entry-checkbox { .mass-action-group {
margin-right: 10px; display: flex;
padding: 3px;
gap: 10px;
}
.mass-action-button {
height: 24px;
line-height: 24px;
padding: 0 0.5rem;
i {
font-size: 1rem;
}
}
.entry-checkbox {
margin: 10px 15px 10px 5px;
.card & {
float: right;
margin-right: 0;
padding: 10px;
}
}
.entries .entry-checkbox-input,
.mass-action .entry-checkbox-input {
position: relative;
left: 0;
width: 20px;
min-height: 25px;
height: 100%;
vertical-align: middle;
opacity: initial;
z-index: 10;
}
.toggle-checkbox:not(:checked) + .mass-action,
.toggle-checkbox:not(:checked) + .mass-action-tags,
.toggle-checkbox:not(:checked) ~ .entries .entry-checkbox,
.toggle-checkbox:checked ~ .entries .card-preview {
display: none;
}
.mass-action-tags {
display: flex;
align-items: center;
gap: 10px;
.mass-action-tags-input {
margin: 0;
} }
} }
@ -62,10 +95,10 @@
.nb-results { .nb-results {
display: inline-flex; display: inline-flex;
} }
}
a { .results-item {
color: #444; color: #444;
}
} }
.pagination { .pagination {
@ -138,3 +171,11 @@ footer {
margin-bottom: 10px; margin-bottom: 10px;
} }
} }
@media screen and (min-width: 993px) {
.mass-action {
display: flex;
align-items: center;
gap: 30px;
}
}

View file

@ -21,12 +21,13 @@
word-wrap: normal; word-wrap: normal;
white-space: nowrap; white-space: nowrap;
direction: ltr; direction: ltr;
user-select: none;
/* Support for all WebKit browsers. */ /* Support for all WebKit browsers. */
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
/* Support for Safari and Chrome. */ /* Support for Safari and Chrome. */
text-rendering: optimizeLegibility; text-rendering: optimizelegibility;
/* Support for Firefox. */ /* Support for Firefox. */
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;

View file

@ -19,7 +19,7 @@ body {
} }
a { a {
color: $blueAccentColor; color: $blue-accent-color;
} }
main, main,

View file

@ -10,7 +10,7 @@
@media only screen and (min-width: 992px) { @media only screen and (min-width: 992px) {
nav, nav,
body:not(.entry):not(.login) main, .index main,
footer { footer {
padding-left: 240px; padding-left: 240px;
} }

View file

@ -131,11 +131,11 @@ nav {
margin: 0 1%; margin: 0 1%;
} }
#button_filters { .button-filters {
display: none; display: none;
} }
#button_export { .button-export {
display: none; display: none;
} }
@ -161,6 +161,16 @@ nav {
} }
@media (min-width: 993px) { @media (min-width: 993px) {
.toggle-add-url-container {
flex-grow: 1;
}
.toggle-add-url {
display: flex;
width: 100%;
justify-content: end;
}
.button-collapse { .button-collapse {
display: none; display: none;
} }

View file

@ -18,20 +18,16 @@
/* Hide useless blocks */ /* Hide useless blocks */
body > header, body > header,
#article_toolbar,
#links,
#sort,
body > footer, body > footer,
.top_link, .entry-tools,
div.tools,
header div, header div,
.messages, .messages,
.entry + .results, .entry + .results,
#slide-out, .left-bar,
.progress, .progress,
.hide-on-large-only, .hide-on-large-only,
#article > aside, .entry-info,
#article .mbm a { .title-edit {
display: none !important; display: none !important;
} }
@ -39,7 +35,7 @@
padding-left: 0 !important; padding-left: 0 !important;
} }
#article { .article {
margin: inherit !important; margin: inherit !important;
} }

View file

@ -45,6 +45,6 @@
font-weight: bold; font-weight: bold;
} }
span.numberItems { .items-number {
float: right; float: right;
} }

View file

@ -2,4 +2,4 @@
Variables Variables
========================================================================== */ ========================================================================== */
$blueAccentColor: #00acc1; $blue-accent-color: #00acc1;

View file

@ -19,7 +19,7 @@ import './css/index.scss';
const mobileMaxWidth = 993; const mobileMaxWidth = 993;
function darkTheme() { (function darkTheme() {
const rootEl = document.querySelector('html'); const rootEl = document.querySelector('html');
const themeDom = { const themeDom = {
darkClass: 'dark-theme', darkClass: 'dark-theme',
@ -87,35 +87,42 @@ function darkTheme() {
return true; return true;
}, },
}; };
const addDarkThemeListeners = () => {
$(document).ready(() => {
const lightThemeButtons = document.querySelectorAll('.js-theme-toggle[data-theme="light"]');
[...lightThemeButtons].map((lightThemeButton) => {
lightThemeButton.addEventListener('click', (e) => {
e.preventDefault();
themeDom.removeClass(rootEl);
themeCookie.setCookie(false);
});
return true;
});
const darkThemeButtons = document.querySelectorAll('.js-theme-toggle[data-theme="dark"]');
[...darkThemeButtons].map((darkThemeButton) => {
darkThemeButton.addEventListener('click', (e) => {
e.preventDefault();
themeDom.addClass(rootEl);
themeCookie.setCookie(true);
});
return true;
});
const autoThemeButtons = document.querySelectorAll('.js-theme-toggle[data-theme="auto"]');
[...autoThemeButtons].map((autoThemeButton) => {
autoThemeButton.addEventListener('click', (e) => {
e.preventDefault();
themeCookie.removeCookie();
preferedColorScheme.choose();
});
return true;
});
});
};
preferedColorScheme.init(); preferedColorScheme.init();
const lightThemeButtons = document.querySelectorAll('.js-theme-toggle[data-theme="light"]'); addDarkThemeListeners();
[...lightThemeButtons].map((lightThemeButton) => { }());
lightThemeButton.addEventListener('click', (e) => {
e.preventDefault();
themeDom.removeClass(rootEl);
themeCookie.setCookie(false);
});
return true;
});
const darkThemeButtons = document.querySelectorAll('.js-theme-toggle[data-theme="dark"]');
[...darkThemeButtons].map((darkThemeButton) => {
darkThemeButton.addEventListener('click', (e) => {
e.preventDefault();
themeDom.addClass(rootEl);
themeCookie.setCookie(true);
});
return true;
});
const autoThemeButtons = document.querySelectorAll('.js-theme-toggle[data-theme="auto"]');
[...autoThemeButtons].map((autoThemeButton) => {
autoThemeButton.addEventListener('click', (e) => {
e.preventDefault();
themeCookie.removeCookie();
preferedColorScheme.choose();
});
return true;
});
}
const stickyNav = () => { const stickyNav = () => {
const nav = $('.js-entry-nav-top'); const nav = $('.js-entry-nav-top');
@ -150,7 +157,6 @@ const articleScroll = () => {
$(document).ready(() => { $(document).ready(() => {
// sideNav // sideNav
$('.button-collapse').sideNav(); $('.button-collapse').sideNav();
darkTheme();
$('select').material_select(); $('select').material_select();
$('.collapsible').collapsible({ $('.collapsible').collapsible({
accordion: false, accordion: false,

View file

@ -80,6 +80,13 @@ $(document).ready(() => {
}); });
Mousetrap.bind('enter', () => { Mousetrap.bind('enter', () => {
window.location.href = window.location.origin + $(card).find('span.card-title a').attr('href'); if (typeof card !== 'object') {
return;
}
const url = $(card).find('.card-title a').attr('href');
if (typeof url === 'string' && url.length > 0) {
window.location.href = window.location.origin + url;
}
}); });
}); });

View file

@ -14,6 +14,7 @@ framework:
translator: translator:
enabled: true enabled: true
fallback: "%locale%" fallback: "%locale%"
default_path: '%kernel.project_dir%/translations'
secret: "%secret%" secret: "%secret%"
router: router:
resource: "%kernel.project_dir%/app/config/routing.yml" resource: "%kernel.project_dir%/app/config/routing.yml"
@ -33,6 +34,8 @@ framework:
fragments: ~ fragments: ~
http_method_override: true http_method_override: true
assets: ~ assets: ~
mailer:
dsn: "%mailer_dsn%"
# Twig Configuration # Twig Configuration
twig: twig:
@ -56,6 +59,8 @@ doctrine:
charset: "%database_charset%" charset: "%database_charset%"
path: "%database_path%" path: "%database_path%"
unix_socket: "%database_socket%" unix_socket: "%database_socket%"
types:
json_array: Wallabag\CoreBundle\Doctrine\JsonArrayType
orm: orm:
auto_generate_proxy_classes: "%kernel.debug%" auto_generate_proxy_classes: "%kernel.debug%"
@ -72,22 +77,14 @@ stof_doctrine_extensions:
sluggable: true sluggable: true
doctrine_migrations: doctrine_migrations:
dir_name: "%kernel.project_dir%/app/DoctrineMigrations" migrations_paths:
namespace: Application\Migrations 'Application\Migrations': "%kernel.project_dir%/app/DoctrineMigrations"
table_name: migration_versions storage:
name: Application Migrations table_storage:
table_name: 'migration_versions'
# Swiftmailer Configuration version_column_name: 'version'
swiftmailer: version_column_length: 192
transport: "%mailer_transport%" executed_at_column_name: 'executed_at'
username: "%mailer_user%"
password: "%mailer_password%"
host: "%mailer_host%"
port: "%mailer_port%"
encryption: "%mailer_encryption%"
auth_mode: "%mailer_auth_mode%"
spool:
type: memory
fos_rest: fos_rest:
param_fetcher_listener: true param_fetcher_listener: true
@ -133,12 +130,13 @@ nelmio_api_doc:
title: wallabag API documentation title: wallabag API documentation
description: This is the API documentation of wallabag description: This is the API documentation of wallabag
version: 2.x version: 2.x
securityDefinitions: components:
Bearer: securitySchemes:
type: apiKey Bearer:
description: 'Value: Bearer {jwt}' type: apiKey
name: Authorization description: 'Value: Bearer {jwt}'
in: header name: Authorization
in: header
security: security:
- Bearer: [] - Bearer: []
@ -179,8 +177,10 @@ fos_user:
confirmation: confirmation:
enabled: "%fosuser_confirmation%" enabled: "%fosuser_confirmation%"
from_email: from_email:
address: "%from_email%" address: "%from_email%"
sender_name: wallabag sender_name: wallabag
service:
mailer: Wallabag\UserBundle\Mailer\UserMailer
fos_oauth_server: fos_oauth_server:
db_driver: orm db_driver: orm
@ -201,15 +201,15 @@ scheb_two_factor:
lifetime: 2592000 lifetime: 2592000
backup_codes: backup_codes:
enabled: "%twofactor_auth%" enabled: true
google: google:
enabled: "%twofactor_auth%" enabled: true
issuer: "%server_name%" issuer: "%server_name%"
template: "@WallabagUser/Authentication/form.html.twig" template: "@WallabagUser/Authentication/form.html.twig"
email: email:
enabled: "%twofactor_auth%" enabled: true
sender_email: "%twofactor_sender%" sender_email: "%twofactor_sender%"
digits: 6 digits: 6
template: "@WallabagUser/Authentication/form.html.twig" template: "@WallabagUser/Authentication/form.html.twig"

View file

@ -8,6 +8,10 @@ framework:
profiler: profiler:
only_exceptions: false only_exceptions: false
mailer:
# see https://mailcatcher.me/
dsn: smtp://127.0.0.1:1025
web_profiler: web_profiler:
toolbar: true toolbar: true
intercept_redirects: false intercept_redirects: false
@ -35,12 +39,6 @@ monolog:
VERBOSITY_DEBUG: DEBUG VERBOSITY_DEBUG: DEBUG
channels: [doctrine] channels: [doctrine]
swiftmailer:
# see https://mailcatcher.me/
transport: smtp
host: 'localhost'
port: 1025
# If you want to use cache for queries used in WallabagExtension # If you want to use cache for queries used in WallabagExtension
# Uncomment the following lines # Uncomment the following lines
#doctrine: #doctrine:

View file

@ -11,16 +11,13 @@ framework:
collect: false collect: false
translator: translator:
enabled: false enabled: false
mailer:
dsn: 'null://null'
web_profiler: web_profiler:
toolbar: false toolbar: false
intercept_redirects: false intercept_redirects: false
swiftmailer:
# to be able to read emails sent
spool:
type: file
doctrine: doctrine:
dbal: dbal:
driver: "%test_database_driver%" driver: "%test_database_driver%"

View file

@ -23,16 +23,10 @@ parameters:
# with PostgreSQL and SQLite, you must set "utf8" # with PostgreSQL and SQLite, you must set "utf8"
database_charset: utf8mb4 database_charset: utf8mb4
domain_name: https://your-wallabag-url-instance.com domain_name: https://your-wallabag-instance.wallabag.org
server_name: "Your wallabag instance" server_name: "Your wallabag instance"
mailer_transport: smtp mailer_dsn: smtp://127.0.0.1
mailer_user: ~
mailer_password: ~
mailer_host: 127.0.0.1
mailer_port: false
mailer_encryption: ~
mailer_auth_mode: ~
locale: en locale: en
@ -40,7 +34,6 @@ parameters:
secret: CHANGE_ME_TO_SOMETHING_SECRET_AND_RANDOM secret: CHANGE_ME_TO_SOMETHING_SECRET_AND_RANDOM
# two factor stuff # two factor stuff
twofactor_auth: true
twofactor_sender: no-reply@wallabag.org twofactor_sender: no-reply@wallabag.org
# fosuser stuff # fosuser stuff

View file

@ -7,7 +7,7 @@ _profiler:
prefix: /_profiler prefix: /_profiler
_errors: _errors:
resource: "@TwigBundle/Resources/config/routing/errors.xml" resource: '@TwigBundle/Resources/config/routing/errors.xml'
prefix: /_error prefix: /_error
_main: _main:

View file

@ -34,12 +34,10 @@ security:
provider: fos_userbundle provider: fos_userbundle
login_firewall: login_firewall:
logout_on_user_change: true
pattern: ^/login$ pattern: ^/login$
anonymous: ~ anonymous: ~
secured_area: secured_area:
logout_on_user_change: true
pattern: ^/ pattern: ^/
form_login: form_login:
provider: fos_userbundle provider: fos_userbundle

View file

@ -33,7 +33,7 @@ services:
Wallabag\AnnotationBundle\: Wallabag\AnnotationBundle\:
resource: '../../src/Wallabag/AnnotationBundle/*' resource: '../../src/Wallabag/AnnotationBundle/*'
exclude: '../../src/Wallabag/AnnotationBundle/{Controller,Entity}' exclude: '../../src/Wallabag/AnnotationBundle/{Controller,Entity,DataFixtures}'
Wallabag\ApiBundle\: Wallabag\ApiBundle\:
resource: '../../src/Wallabag/ApiBundle/*' resource: '../../src/Wallabag/ApiBundle/*'
@ -41,7 +41,80 @@ services:
Wallabag\CoreBundle\: Wallabag\CoreBundle\:
resource: '../../src/Wallabag/CoreBundle/*' resource: '../../src/Wallabag/CoreBundle/*'
exclude: ['../../src/Wallabag/CoreBundle/{Controller,Entity}', '../../src/Wallabag/CoreBundle/Event/*Event.php'] exclude: ['../../src/Wallabag/CoreBundle/{Controller,Entity,DataFixtures}', '../../src/Wallabag/CoreBundle/Event/*Event.php']
# controllers are imported separately to make sure services can be injected
# as action arguments even if you don't extend any base controller class
Wallabag\AnnotationBundle\Controller\:
resource: '../../src/Wallabag/AnnotationBundle/Controller/'
tags: ['controller.service_arguments']
Wallabag\ApiBundle\Controller\:
resource: '../../src/Wallabag/ApiBundle/Controller/'
tags: ['controller.service_arguments']
Wallabag\CoreBundle\Controller\:
resource: '../../src/Wallabag/CoreBundle/Controller/'
tags: ['controller.service_arguments']
Wallabag\ImportBundle\Controller\:
resource: '../../src/Wallabag/ImportBundle/Controller/'
tags: ['controller.service_arguments']
Wallabag\UserBundle\Controller\:
resource: '../../src/Wallabag/UserBundle/Controller/'
tags: ['controller.service_arguments']
# inject alias service into controllers
Wallabag\ImportBundle\Controller\ChromeController:
arguments:
$rabbitMqProducer: '@old_sound_rabbit_mq.import_chrome_producer'
$redisProducer: '@wallabag_import.producer.redis.chrome'
Wallabag\ImportBundle\Controller\DeliciousController:
arguments:
$rabbitMqProducer: '@old_sound_rabbit_mq.import_delicious_producer'
$redisProducer: '@wallabag_import.producer.redis.delicious'
Wallabag\ImportBundle\Controller\ElcuratorController:
arguments:
$rabbitMqProducer: '@old_sound_rabbit_mq.import_elcurator_producer'
$redisProducer: '@wallabag_import.producer.redis.elcurator'
Wallabag\ImportBundle\Controller\FirefoxController:
arguments:
$rabbitMqProducer: '@old_sound_rabbit_mq.import_firefox_producer'
$redisProducer: '@wallabag_import.producer.redis.firefox'
Wallabag\ImportBundle\Controller\InstapaperController:
arguments:
$rabbitMqProducer: '@old_sound_rabbit_mq.import_instapaper_producer'
$redisProducer: '@wallabag_import.producer.redis.instapaper'
Wallabag\ImportBundle\Controller\PinboardController:
arguments:
$rabbitMqProducer: '@old_sound_rabbit_mq.import_pinboard_producer'
$redisProducer: '@wallabag_import.producer.redis.pinboard'
Wallabag\ImportBundle\Controller\PocketController:
arguments:
$rabbitMqProducer: '@old_sound_rabbit_mq.import_pocket_producer'
$redisProducer: '@wallabag_import.producer.redis.pocket'
Wallabag\ImportBundle\Controller\ReadabilityController:
arguments:
$rabbitMqProducer: '@old_sound_rabbit_mq.import_readability_producer'
$redisProducer: '@wallabag_import.producer.redis.readability'
Wallabag\ImportBundle\Controller\WallabagV1Controller:
arguments:
$rabbitMqProducer: '@old_sound_rabbit_mq.import_wallabag_v1_producer'
$redisProducer: '@wallabag_import.producer.redis.wallabag_v1'
Wallabag\ImportBundle\Controller\WallabagV2Controller:
arguments:
$rabbitMqProducer: '@old_sound_rabbit_mq.import_wallabag_v2_producer'
$redisProducer: '@wallabag_import.producer.redis.wallabag_v2'
Wallabag\ImportBundle\: Wallabag\ImportBundle\:
resource: '../../src/Wallabag/ImportBundle/*' resource: '../../src/Wallabag/ImportBundle/*'
@ -49,7 +122,7 @@ services:
Wallabag\UserBundle\: Wallabag\UserBundle\:
resource: '../../src/Wallabag/UserBundle/*' resource: '../../src/Wallabag/UserBundle/*'
exclude: '../../src/Wallabag/UserBundle/{Controller,Entity}' exclude: '../../src/Wallabag/UserBundle/{Controller,Entity,DataFixtures}'
Doctrine\DBAL\Connection: Doctrine\DBAL\Connection:
alias: doctrine.dbal.default_connection alias: doctrine.dbal.default_connection
@ -96,9 +169,6 @@ services:
FOS\UserBundle\Model\UserManagerInterface: FOS\UserBundle\Model\UserManagerInterface:
alias: fos_user.user_manager alias: fos_user.user_manager
Twig_Extensions_Extension_Text:
class: Twig_Extensions_Extension_Text
MatomoTwigExtension\MatomoTwigExtension: MatomoTwigExtension\MatomoTwigExtension:
public: false public: false
@ -186,8 +256,6 @@ services:
path: '%redis_path%' path: '%redis_path%'
password: '%redis_password%' password: '%redis_password%'
Wallabag\CoreBundle\Controller\ExceptionController: ~
Wallabag\CoreBundle\Event\Subscriber\SQLiteCascadeDeleteSubscriber: Wallabag\CoreBundle\Event\Subscriber\SQLiteCascadeDeleteSubscriber:
tags: tags:
- { name: doctrine.event_subscriber } - { name: doctrine.event_subscriber }
@ -200,9 +268,30 @@ services:
arguments: arguments:
$baseFolder: "%kernel.project_dir%/web/assets/images" $baseFolder: "%kernel.project_dir%/web/assets/images"
Wallabag\CoreBundle\Command\ExportCommand:
arguments:
$projectDir: '%kernel.project_dir%'
Wallabag\CoreBundle\Command\InstallCommand:
arguments:
$databaseDriver: '%database_driver%'
$databaseName: '%database_name%'
$defaultSettings: '%wallabag_core.default_internal_settings%'
$defaultIgnoreOriginInstanceRules: '%wallabag_core.default_ignore_origin_instance_rules%'
wallabag_core.entry.download_images.client: wallabag_core.entry.download_images.client:
alias: 'httplug.client.wallabag_core.entry.download_images' alias: 'httplug.client.wallabag_core.entry.download_images'
Wallabag\UserBundle\Mailer\UserMailer:
arguments:
$parameters:
template:
confirmation: '%fos_user.registration.confirmation.template%'
resetting: '%fos_user.resetting.email.template%'
from_email:
confirmation: '%fos_user.registration.confirmation.from_email%'
resetting: '%fos_user.resetting.email.from_email%'
Wallabag\UserBundle\EventListener\CreateConfigListener: Wallabag\UserBundle\EventListener\CreateConfigListener:
arguments: arguments:
$itemsOnPage: "%wallabag_core.items_on_page%" $itemsOnPage: "%wallabag_core.items_on_page%"
@ -211,6 +300,7 @@ services:
$readingSpeed: "%wallabag_core.reading_speed%" $readingSpeed: "%wallabag_core.reading_speed%"
$actionMarkAsRead: "%wallabag_core.action_mark_as_read%" $actionMarkAsRead: "%wallabag_core.action_mark_as_read%"
$listMode: "%wallabag_core.list_mode%" $listMode: "%wallabag_core.list_mode%"
$displayThumbnails: "%wallabag_core.display_thumbnails%"
Wallabag\UserBundle\EventListener\AuthenticationFailureListener: Wallabag\UserBundle\EventListener\AuthenticationFailureListener:
tags: tags:
@ -260,3 +350,13 @@ services:
Wallabag\ImportBundle\Import\ChromeImport: Wallabag\ImportBundle\Import\ChromeImport:
tags: tags:
- { name: wallabag_import.import, alias: chrome } - { name: wallabag_import.import, alias: chrome }
# to factorize the proximity and bypass translation for prev & next
pagerfanta.view.default_wallabag:
class: Pagerfanta\View\OptionableView
arguments:
- '@pagerfanta.view.twitter_bootstrap'
- { proximity: 1, prev_message: "<", next_message: ">" }
public: false
tags:
- { name: pagerfanta.view, alias: default_wallabag }

View file

@ -5,6 +5,20 @@ services:
autoconfigure: true autoconfigure: true
public: true public: true
Wallabag\ImportBundle\Consumer\RabbitMQConsumerTotalProxy:
lazy: true
arguments:
$pocketConsumer: '@old_sound_rabbit_mq.import_pocket_consumer'
$readabilityConsumer: '@old_sound_rabbit_mq.import_readability_consumer'
$wallabagV1Consumer: '@old_sound_rabbit_mq.import_wallabag_v1_consumer'
$wallabagV2Consumer: '@old_sound_rabbit_mq.import_wallabag_v2_consumer'
$firefoxConsumer: '@old_sound_rabbit_mq.import_firefox_consumer'
$chromeConsumer: '@old_sound_rabbit_mq.import_chrome_consumer'
$instapaperConsumer: '@old_sound_rabbit_mq.import_instapaper_consumer'
$pinboardConsumer: '@old_sound_rabbit_mq.import_pinboard_consumer'
$deliciousConsumer: '@old_sound_rabbit_mq.import_delicious_consumer'
$elcuratorConsumer: '@old_sound_rabbit_mq.import_elcurator_consumer'
wallabag_import.consumer.amqp.pocket: wallabag_import.consumer.amqp.pocket:
class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer
arguments: arguments:

View file

@ -1,6 +1,6 @@
wallabag_core: wallabag_core:
version: 2.5.2 version: 2.6.2
paypal_url: "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=9UBA65LG3FX9Y&lc=gb" paypal_url: "https://liberapay.com/wallabag/donate"
languages: languages:
en: 'English' en: 'English'
fr: 'Français' fr: 'Français'
@ -30,6 +30,7 @@ wallabag_core:
cache_lifetime: 10 cache_lifetime: 10
action_mark_as_read: 1 action_mark_as_read: 1
list_mode: 0 list_mode: 0
display_thumbnails: 1
fetching_error_message_title: 'No title found' fetching_error_message_title: 'No title found'
fetching_error_message: | fetching_error_message: |
wallabag can't retrieve contents for this article. Please <a href="https://doc.wallabag.org/en/user/errors_during_fetching.html#how-can-i-help-to-fix-that">troubleshoot this issue</a>. wallabag can't retrieve contents for this article. Please <a href="https://doc.wallabag.org/en/user/errors_during_fetching.html#how-can-i-help-to-fix-that">troubleshoot this issue</a>.

View file

@ -1,33 +1,38 @@
{ {
"name": "wallabag/wallabag", "name": "wallabag/wallabag",
"type": "project",
"description": "open source self hostable read-it-later web application", "description": "open source self hostable read-it-later web application",
"license": "MIT",
"type": "project",
"keywords": [ "keywords": [
"poche", "poche",
"wallabag", "wallabag",
"read-it-later", "read-it-later",
"read it later" "read it later"
], ],
"homepage": "https://github.com/wallabag/wallabag",
"license": "MIT",
"authors": [ "authors": [
{ {
"name": "Nicolas Lœuillet", "name": "Nicolas Lœuillet",
"email": "nicolas@loeuillet.org", "email": "nicolas@loeuillet.org",
"homepage": "http://www.cdetc.fr", "homepage": "https://nicolas.loeuillet.org",
"role": "Developer" "role": "Developer"
}, },
{ {
"name": "Thomas Citharel", "name": "Thomas Citharel",
"homepage": "http://tcit.fr", "homepage": "https://tcit.fr",
"role": "Developer" "role": "Developer"
}, },
{ {
"name": "Jérémy Benoist", "name": "Jérémy Benoist",
"homepage": "https://www.j0k3r.net", "homepage": "https://www.j0k3r.net",
"role": "Developer" "role": "Developer"
},
{
"name": "Kevin Decherf",
"homepage": "https://kdecherf.com/",
"role": "Developer"
} }
], ],
"homepage": "https://github.com/wallabag/wallabag",
"support": { "support": {
"email": "hello@wallabag.org", "email": "hello@wallabag.org",
"issues": "https://github.com/wallabag/wallabag/issues" "issues": "https://github.com/wallabag/wallabag/issues"
@ -51,46 +56,47 @@
"ext-tidy": "*", "ext-tidy": "*",
"ext-tokenizer": "*", "ext-tokenizer": "*",
"ext-xml": "*", "ext-xml": "*",
"babdev/pagerfanta-bundle": "^2.5", "babdev/pagerfanta-bundle": "^3.7",
"bdunogier/guzzle-site-authenticator": "^1.0.0", "bdunogier/guzzle-site-authenticator": "^1.0.0",
"craue/config-bundle": "^2.3.0", "craue/config-bundle": "^2.3.0",
"defuse/php-encryption": "^2.1", "defuse/php-encryption": "^2.1",
"doctrine/collections": "^1.6", "doctrine/collections": "^1.6",
"doctrine/common": "^2.13", "doctrine/common": "^3.0",
"doctrine/dbal": "^2.13", "doctrine/dbal": "^3.3",
"doctrine/doctrine-bundle": "^1.9", "doctrine/doctrine-bundle": "^2.0",
"doctrine/doctrine-cache-bundle": "^1.3", "doctrine/doctrine-migrations-bundle": "^3.2",
"doctrine/doctrine-migrations-bundle": "^1.3",
"doctrine/event-manager": "^1.1", "doctrine/event-manager": "^1.1",
"doctrine/migrations": "^1.8", "doctrine/migrations": "^3.2",
"doctrine/orm": "^2.6", "doctrine/orm": "^2.6",
"doctrine/persistence": "^1.3", "doctrine/persistence": "^3.0",
"egulias/email-validator": "^3.2",
"enshrined/svg-sanitize": "^0.15.4", "enshrined/svg-sanitize": "^0.15.4",
"friendsofsymfony/jsrouting-bundle": "^2.2", "friendsofsymfony/jsrouting-bundle": "^2.2",
"friendsofsymfony/oauth-server-bundle": "^1.5", "friendsofsymfony/oauth-server-bundle": "dev-master#dc8ff343363cf794d30eb1a123610d186a43f162",
"friendsofsymfony/rest-bundle": "~2.1", "friendsofsymfony/rest-bundle": "~3.4",
"friendsofsymfony/user-bundle": "2.1.*", "friendsofsymfony/user-bundle": "^3.1",
"guzzlehttp/guzzle": "^5.3.1", "guzzlehttp/guzzle": "^5.3.1",
"guzzlehttp/psr7": "^1.8", "guzzlehttp/psr7": "^2.5",
"html2text/html2text": "^4.1", "html2text/html2text": "^4.1",
"incenteev/composer-parameter-handler": "^2.1", "incenteev/composer-parameter-handler": "^2.1",
"j0k3r/graby": "^2.0", "j0k3r/graby": "^2.0",
"javibravo/simpleue": "^2.0", "javibravo/simpleue": "^2.0",
"jms/serializer": "^3.17", "jms/serializer": "^3.17",
"jms/serializer-bundle": "~3.6", "jms/serializer-bundle": "~5.0",
"kphoen/rulerz": "^0.21", "kphoen/rulerz": "^0.21",
"kphoen/rulerz-bundle": "~0.13", "kphoen/rulerz-bundle": "~0.13",
"laminas/laminas-code": "^3.4", "laminas/laminas-code": "^4.7",
"laminas/laminas-diactoros": "^2.3", "lcobucci/jwt": "~4.1.5",
"lexik/form-filter-bundle": "^5.0.4", "lexik/form-filter-bundle": "^7.0",
"mgargano/simplehtmldom": "~1.5", "mgargano/simplehtmldom": "~1.5",
"mnapoli/piwik-twig-extension": "^3.0", "mnapoli/piwik-twig-extension": "^3.0",
"nelmio/api-doc-bundle": "^3.0", "nelmio/api-doc-bundle": "^4.10",
"nelmio/cors-bundle": "~1.5", "nelmio/cors-bundle": "~2.2",
"ocramius/proxy-manager": "^2.1.1", "ocramius/proxy-manager": "^2.1.1",
"pagerfanta/pagerfanta": "^2.4", "pagerfanta/doctrine-orm-adapter": "^3.7",
"php-amqplib/php-amqplib": "^2.12", "pagerfanta/twig": "^3.7",
"php-amqplib/rabbitmq-bundle": "^1.14", "php-amqplib/php-amqplib": "^3.4",
"php-amqplib/rabbitmq-bundle": "^2.11",
"php-http/client-common": "^2.4", "php-http/client-common": "^2.4",
"php-http/discovery": "^1.14", "php-http/discovery": "^1.14",
"php-http/guzzle5-adapter": "^2.0", "php-http/guzzle5-adapter": "^2.0",
@ -102,27 +108,34 @@
"predis/predis": "^2.0.3", "predis/predis": "^2.0.3",
"psr/http-message": "^1.0", "psr/http-message": "^1.0",
"psr/log": "^1.1", "psr/log": "^1.1",
"scheb/two-factor-bundle": "^4.11.0", "scheb/2fa-backup-code": "^5.13",
"sensio/framework-extra-bundle": "^5.2", "scheb/2fa-bundle": "^5.13",
"sentry/sentry-symfony": "3.5.3", "scheb/2fa-email": "^5.13",
"scheb/2fa-google-authenticator": "^5.13",
"scheb/2fa-qr-code": "^5.13",
"scheb/2fa-trusted-device": "^5.13",
"sensio/framework-extra-bundle": "^6.2",
"sentry/sentry-symfony": "4.10.0",
"stof/doctrine-extensions-bundle": "^1.2", "stof/doctrine-extensions-bundle": "^1.2",
"swiftmailer/swiftmailer": "^6.3",
"symfony/dom-crawler": "^4.0", "symfony/dom-crawler": "^4.0",
"symfony/mailer": "^4.0",
"symfony/monolog-bundle": "^3.1", "symfony/monolog-bundle": "^3.1",
"symfony/swiftmailer-bundle": "^3.2", "symfony/proxy-manager-bridge": "^4.4",
"symfony/symfony": "^4.0", "symfony/symfony": "^4.0",
"tecnickcom/tcpdf": "^6.3.0", "tecnickcom/tcpdf": "^6.3.0",
"twig/extensions": "^1.5", "twig/extra-bundle": "^3.4",
"twig/twig": "^2.15", "twig/string-extra": "^3.4",
"twig/twig": "^3.4.3",
"wallabag/php-mobi": "~1.0", "wallabag/php-mobi": "~1.0",
"wallabag/phpepub": "^4.0.10", "wallabag/phpepub": "^4.0.10",
"willdurand/hateoas": "^3.8", "willdurand/hateoas": "^3.8",
"willdurand/hateoas-bundle": "~2.1" "willdurand/hateoas-bundle": "~2.1"
}, },
"require-dev": { "require-dev": {
"dama/doctrine-test-bundle": "^6.0", "dama/doctrine-test-bundle": "^7.1",
"doctrine/doctrine-fixtures-bundle": "~3.0", "doctrine/doctrine-fixtures-bundle": "~3.0",
"friendsofphp/php-cs-fixer": "~2.13", "ergebnis/composer-normalize": "^2.28",
"friendsofphp/php-cs-fixer": "~3.4",
"friendsoftwig/twigcs": "^6.0", "friendsoftwig/twigcs": "^6.0",
"m6web/redis-mock": "^5.0", "m6web/redis-mock": "^5.0",
"php-http/mock-client": "^1.0", "php-http/mock-client": "^1.0",
@ -137,24 +150,8 @@
"suggest": { "suggest": {
"ext-imagick": "To keep GIF animation when downloading image is enabled" "ext-imagick": "To keep GIF animation when downloading image is enabled"
}, },
"scripts": { "minimum-stability": "dev",
"post-cmd": [ "prefer-stable": true,
"Incenteev\\ParameterHandler\\ScriptHandler::buildParameters",
"bin/console cache:clear --no-warmup",
"bin/console assets:install web --symlink --relative"
],
"post-install-cmd": [
"@post-cmd"
],
"post-update-cmd": [
"@post-cmd"
]
},
"extra": {
"incenteev-parameters": {
"file": "app/config/parameters.yml"
}
},
"autoload": { "autoload": {
"psr-4": { "psr-4": {
"Wallabag\\": "src/Wallabag/" "Wallabag\\": "src/Wallabag/"
@ -173,15 +170,34 @@
] ]
}, },
"config": { "config": {
"allow-plugins": {
"phpstan/extension-installer": true,
"php-http/discovery": true,
"ergebnis/composer-normalize": true
},
"bin-dir": "bin", "bin-dir": "bin",
"platform": { "platform": {
"php": "7.4.29" "php": "7.4.29"
}, },
"sort-packages": true, "sort-packages": true
"allow-plugins": {
"phpstan/extension-installer": true
}
}, },
"minimum-stability": "dev", "extra": {
"prefer-stable": true "incenteev-parameters": {
"file": "app/config/parameters.yml"
},
"public-dir": "web"
},
"scripts": {
"post-install-cmd": [
"@post-cmd"
],
"post-update-cmd": [
"@post-cmd"
],
"post-cmd": [
"Incenteev\\ParameterHandler\\ScriptHandler::buildParameters",
"bin/console cache:clear --no-warmup",
"bin/console assets:install web --symlink --relative"
]
}
} }

4884
composer.lock generated

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
FROM php:7.4-fpm AS rootless FROM php:8.1-fpm AS rootless
ARG DEBIAN_FRONTEND=noninteractive ARG DEBIAN_FRONTEND=noninteractive
ARG NODE_VERSION=16 ARG NODE_VERSION=16
@ -33,7 +33,8 @@ RUN apt-get update && apt-get install -y \
zlib1g-dev \ zlib1g-dev \
git \ git \
build-essential \ build-essential \
nodejs nodejs \
npm
RUN docker-php-ext-configure gd --with-freetype --with-jpeg --with-webp RUN docker-php-ext-configure gd --with-freetype --with-jpeg --with-webp
RUN docker-php-ext-install -j "$(nproc)" \ RUN docker-php-ext-install -j "$(nproc)" \
bcmath \ bcmath \
@ -53,7 +54,7 @@ RUN docker-php-ext-install -j "$(nproc)" \
RUN pecl install redis; \ RUN pecl install redis; \
pecl install imagick; \ pecl install imagick; \
pecl install xdebug; \ pecl install xdebug-3.1.6; \
docker-php-ext-enable \ docker-php-ext-enable \
redis \ redis \
imagick \ imagick \

View file

@ -6,29 +6,22 @@ parameters:
database_name: ${DATABASE_NAME:-symfony} database_name: ${DATABASE_NAME:-symfony}
database_user: ${DATABASE_USER:-root} database_user: ${DATABASE_USER:-root}
database_password: ${DATABASE_PASSWORD:-~} database_password: ${DATABASE_PASSWORD:-~}
database_path: ${DATABASE_PATH:-"%kernel.root_dir%/data/db/wallabag.sqlite"} database_path: '${DATABASE_PATH:-"%kernel.root_dir%/data/db/wallabag.sqlite"}'
database_table_prefix: wallabag_ database_table_prefix: ${DATABASE_TABLE_PREFIX:-wallabag_}
database_socket: null database_socket: null
database_charset: ${DATABASE_CHARSET:-utf8} database_charset: ${DATABASE_CHARSET:-utf8}
domain_name: ${DOMAIN_NAME:-https://www.example.com} domain_name: ${DOMAIN_NAME:-https://www.example.com}
server_name: ${SERVER_NAME:-"Your wallabag instance"} server_name: ${SERVER_NAME:-"Your wallabag instance"}
mailer_transport: ${MAILER_TRANSPORT:-smtp} mailer_dsn: ${MAILER_DSN:-"smtp://127.0.0.1"}
mailer_user: ${MAILER_USER:-~}
mailer_password: ${MAILER_PASSWORD:-~}
mailer_host: ${MAILER_HOST:-127.0.0.1}
mailer_port: ${MAILER_PORT:-25}
mailer_encryption: ${MAILER_ENCRYPTION:-~}
mailer_auth_mode: ${MAILER_AUTH_MODE:-~}
locale: ${LOCALE:-en} locale: ${LOCALE:-en}
# A secret key that's used to generate certain security-related tokens # A secret key that's used to generate certain security-related tokens
secret: ${SECRET:-~} secret: ${SECRET:-~}
# two factor stuff # two factor stuff
twofactor_auth: ${TWOFACTOR_AUTH:-true}
twofactor_sender: ${TWOFACTOR_SENDER:-no-reply@wallabag.org} twofactor_sender: ${TWOFACTOR_SENDER:-no-reply@wallabag.org}
# fosuser stuff # fosuser stuff

View file

@ -1,6 +1,6 @@
{ {
"name": "wallabag", "name": "wallabag",
"version": "2.5.0", "version": "2.6.0",
"description": "wallabag is a self hostable application for saving web pages", "description": "wallabag is a self hostable application for saving web pages",
"private": true, "private": true,
"directories": { "directories": {
@ -17,17 +17,22 @@
{ {
"name": "Nicolas Lœuillet", "name": "Nicolas Lœuillet",
"email": "nicolas@loeuillet.org", "email": "nicolas@loeuillet.org",
"homepage": "http://www.cdetc.fr", "homepage": "https://nicolas.loeuillet.org",
"role": "Developer" "role": "Developer"
}, },
{ {
"name": "Thomas Citharel", "name": "Thomas Citharel",
"homepage": "http://tcit.fr", "homepage": "https://tcit.fr",
"role": "Developer" "role": "Developer"
}, },
{ {
"name": "Jérémy Benoist", "name": "Jérémy Benoist",
"homepage": "http://www.j0k3r.net", "homepage": "https://www.j0k3r.net",
"role": "Developer"
},
{
"name": "Kevin Decherf",
"homepage": "https://kdecherf.com/",
"role": "Developer" "role": "Developer"
} }
], ],
@ -36,49 +41,50 @@
"url": "https://github.com/wallabag/wallabag/issues" "url": "https://github.com/wallabag/wallabag/issues"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.20.2", "@babel/core": "^7.22.9",
"@babel/eslint-parser": "^7.19.1", "@babel/eslint-parser": "^7.22.9",
"@babel/preset-env": "^7.20.2", "@babel/preset-env": "^7.22.9",
"autoprefixer": "^10.4.13", "autoprefixer": "^10.4.14",
"babel-loader": "^9.1.0", "babel-loader": "^9.1.3",
"css-loader": "^6.7.2", "css-loader": "^6.8.1",
"eslint": "^8.28.0", "eslint": "^8.46.0",
"eslint-config-airbnb-base": "^15.0.0", "eslint-config-airbnb-base": "^15.0.0",
"eslint-plugin-import": "^2.26.0", "eslint-plugin-import": "^2.28.0",
"eslint-webpack-plugin": "^3.2.0", "eslint-webpack-plugin": "^4.0.1",
"file-loader": "^6.2.0", "file-loader": "^6.2.0",
"lato-font": "^3.0.0", "lato-font": "^3.0.0",
"mini-css-extract-plugin": "^2.7.0", "mini-css-extract-plugin": "^2.7.6",
"node-sass": "^8.0.0", "node-sass": "^9.0.0",
"postcss": "^8.4.19", "postcss": "^8.4.27",
"postcss-loader": "^7.0.1", "postcss-loader": "^7.3.3",
"postcss-scss": "^4.0.6", "postcss-scss": "^4.0.6",
"sass": "^1.56.1", "sass": "^1.64.1",
"sass-loader": "^13.2.0", "sass-loader": "^13.3.2",
"style-loader": "^3.3.1", "style-loader": "^3.3.3",
"stylelint": "^14.15.0", "stylelint": "^15.10.2",
"stylelint-config-standard": "^29.0.0", "stylelint-config-standard": "^34.0.0",
"stylelint-scss": "^4.3.0", "stylelint-config-standard-scss": "^10.0.0",
"stylelint-webpack-plugin": "^3.3.0", "stylelint-scss": "^5.0.1",
"terser-webpack-plugin": "^5.3.6", "stylelint-webpack-plugin": "^4.1.1",
"terser-webpack-plugin": "^5.3.9",
"url-loader": "^4.1.1", "url-loader": "^4.1.1",
"webpack": "^5.75.0", "webpack": "^5.88.2",
"webpack-cli": "^5.0.0", "webpack-cli": "^5.1.4",
"webpack-dev-server": "^4.11.1", "webpack-dev-server": "^4.15.1",
"webpack-manifest-plugin": "^5.0.0", "webpack-manifest-plugin": "^5.0.0",
"webpack-merge": "^5.7.3" "webpack-merge": "^5.9.0"
}, },
"dependencies": { "dependencies": {
"annotator": "wallabag/annotator#master", "annotator": "wallabag/annotator#master",
"clipboard": "^2.0.11", "clipboard": "^2.0.11",
"hammerjs": "^2.0.8", "hammerjs": "^2.0.8",
"highlight.js": "^11.7.0", "highlight.js": "^11.8.0",
"icomoon-free-npm": "^0.0.0", "icomoon-free-npm": "^0.0.0",
"jquery": "^3.6.1", "jquery": "^3.7.0",
"jquery.cookie": "^1.4.1", "jquery.cookie": "^1.4.1",
"jr-qrcode": "^1.0.7", "jr-qrcode": "^1.0.7",
"material-design-icons-iconfont": "^6.7.0", "material-design-icons-iconfont": "^6.7.0",
"materialize-css": "^0.98.1", "materialize-css": "^0.100.2",
"mathjax": "^3.2.2", "mathjax": "^3.2.2",
"mousetrap": "^1.6.0", "mousetrap": "^1.6.0",
"ptsans-npm-webfont": "^0.0.4", "ptsans-npm-webfont": "^0.0.4",

View file

@ -1,40 +1,10 @@
parameters: parameters:
ignoreErrors: ignoreErrors:
-
message: "#^Call to an undefined method Psr\\\\Container\\\\ContainerInterface\\:\\:getParameter\\(\\)\\.$#"
count: 2
path: src/Wallabag/ApiBundle/Controller/EntryRestController.php
-
message: "#^Call to an undefined method Psr\\\\Container\\\\ContainerInterface\\:\\:getParameter\\(\\)\\.$#"
count: 1
path: src/Wallabag/ApiBundle/Controller/UserRestController.php
-
message: "#^Call to an undefined method Psr\\\\Container\\\\ContainerInterface\\:\\:getParameter\\(\\)\\.$#"
count: 3
path: src/Wallabag/ApiBundle/Controller/WallabagRestController.php
-
message: "#^Call to an undefined method Doctrine\\\\Persistence\\\\ObjectManager\\:\\:getConnection\\(\\)\\.$#"
count: 5
path: src/Wallabag/CoreBundle/Command/InstallCommand.php
- -
message: "#^Call to an undefined method Wallabag\\\\CoreBundle\\\\Entity\\\\RuleInterface\\:\\:getConfig\\(\\)\\.$#" message: "#^Call to an undefined method Wallabag\\\\CoreBundle\\\\Entity\\\\RuleInterface\\:\\:getConfig\\(\\)\\.$#"
count: 1 count: 1
path: src/Wallabag/CoreBundle/Controller/ConfigController.php path: src/Wallabag/CoreBundle/Controller/ConfigController.php
-
message: "#^Call to an undefined method Psr\\\\Container\\\\ContainerInterface\\:\\:getParameter\\(\\)\\.$#"
count: 1
path: src/Wallabag/CoreBundle/Controller/StaticController.php
-
message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#"
count: 1
path: src/Wallabag/CoreBundle/DependencyInjection/Configuration.php
- -
message: "#^Call to an undefined method Lexik\\\\Bundle\\\\FormFilterBundle\\\\Filter\\\\Query\\\\QueryInterface\\:\\:getExpressionBuilder\\(\\)\\.$#" message: "#^Call to an undefined method Lexik\\\\Bundle\\\\FormFilterBundle\\\\Filter\\\\Query\\\\QueryInterface\\:\\:getExpressionBuilder\\(\\)\\.$#"
count: 1 count: 1
@ -45,11 +15,6 @@ parameters:
count: 10 count: 10
path: src/Wallabag/CoreBundle/Form/Type/EntryFilterType.php path: src/Wallabag/CoreBundle/Form/Type/EntryFilterType.php
-
message: "#^Call to an undefined method Doctrine\\\\Persistence\\\\ObjectManager\\:\\:getConnection\\(\\)\\.$#"
count: 1
path: src/Wallabag/ImportBundle/Command/ImportCommand.php
- -
message: "#^Call to an undefined method Wallabag\\\\ImportBundle\\\\Import\\\\ImportInterface\\:\\:setFilepath\\(\\)\\.$#" message: "#^Call to an undefined method Wallabag\\\\ImportBundle\\\\Import\\\\ImportInterface\\:\\:setFilepath\\(\\)\\.$#"
count: 1 count: 1
@ -70,11 +35,6 @@ parameters:
count: 1 count: 1
path: src/Wallabag/ImportBundle/Controller/WallabagController.php path: src/Wallabag/ImportBundle/Controller/WallabagController.php
-
message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#"
count: 1
path: src/Wallabag/ImportBundle/DependencyInjection/Configuration.php
- -
message: "#^Call to an undefined method Scheb\\\\TwoFactorBundle\\\\Model\\\\Email\\\\TwoFactorInterface\\:\\:getName\\(\\)\\.$#" message: "#^Call to an undefined method Scheb\\\\TwoFactorBundle\\\\Model\\\\Email\\\\TwoFactorInterface\\:\\:getName\\(\\)\\.$#"
count: 2 count: 2
@ -94,3 +54,13 @@ parameters:
message: "#^Property Tests\\\\Wallabag\\\\CoreBundle\\\\Helper\\\\RedirectTest\\:\\:\\$routerMock has unknown class PHPUnit_Framework_MockObject_MockObject as its type\\.$#" message: "#^Property Tests\\\\Wallabag\\\\CoreBundle\\\\Helper\\\\RedirectTest\\:\\:\\$routerMock has unknown class PHPUnit_Framework_MockObject_MockObject as its type\\.$#"
count: 1 count: 1
path: tests/Wallabag/CoreBundle/Helper/RedirectTest.php path: tests/Wallabag/CoreBundle/Helper/RedirectTest.php
-
message: "#^Method Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface\\:\\:dispatch()#"
count: 15
path: src/*
-
message: "#^Method FOS\\\\UserBundle\\\\Model\\\\UserManagerInterface\\:\\:updateUser()#"
count: 7
path: src/Wallabag/CoreBundle/Controller/ConfigController.php

View file

@ -31,7 +31,7 @@
</whitelist> </whitelist>
</filter> </filter>
<listeners> <extensions>
<listener class="\DAMA\DoctrineTestBundle\PHPUnit\PHPUnitListener" /> <extension class="DAMA\DoctrineTestBundle\PHPUnit\PHPUnitExtension" />
</listeners> </extensions>
</phpunit> </phpunit>

View file

@ -9,7 +9,7 @@ ENV=$4
rm -rf "${TMP_FOLDER:?}"/"$RELEASE_FOLDER" rm -rf "${TMP_FOLDER:?}"/"$RELEASE_FOLDER"
mkdir "$TMP_FOLDER"/"$RELEASE_FOLDER" mkdir "$TMP_FOLDER"/"$RELEASE_FOLDER"
git clone https://github.com/wallabag/wallabag.git "$TMP_FOLDER"/"$RELEASE_FOLDER"/"$VERSION" git clone https://github.com/wallabag/wallabag.git --single-branch --depth 1 --branch $1 "$TMP_FOLDER"/"$RELEASE_FOLDER"/"$VERSION"
cd "$TMP_FOLDER"/"$RELEASE_FOLDER"/"$VERSION" && SYMFONY_ENV="$ENV" COMPOSER_MEMORY_LIMIT=-1 composer install -n --no-dev cd "$TMP_FOLDER"/"$RELEASE_FOLDER"/"$VERSION" && SYMFONY_ENV="$ENV" COMPOSER_MEMORY_LIMIT=-1 composer install -n --no-dev
cd "$TMP_FOLDER"/"$RELEASE_FOLDER"/"$VERSION" && php bin/console wallabag:install --env="$ENV" -n cd "$TMP_FOLDER"/"$RELEASE_FOLDER"/"$VERSION" && php bin/console wallabag:install --env="$ENV" -n
cd "$TMP_FOLDER"/"$RELEASE_FOLDER"/"$VERSION" && php bin/console assets:install --env="$ENV" --symlink --relative cd "$TMP_FOLDER"/"$RELEASE_FOLDER"/"$VERSION" && php bin/console assets:install --env="$ENV" --symlink --relative

View file

@ -2,20 +2,33 @@
namespace Wallabag\AnnotationBundle\Controller; namespace Wallabag\AnnotationBundle\Controller;
use Doctrine\ORM\EntityManagerInterface;
use FOS\RestBundle\Controller\AbstractFOSRestController; use FOS\RestBundle\Controller\AbstractFOSRestController;
use JMS\Serializer\SerializerInterface; use JMS\Serializer\SerializerInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Component\Form\FormFactoryInterface; use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
use Wallabag\AnnotationBundle\Entity\Annotation; use Wallabag\AnnotationBundle\Entity\Annotation;
use Wallabag\AnnotationBundle\Form\EditAnnotationType; use Wallabag\AnnotationBundle\Form\EditAnnotationType;
use Wallabag\AnnotationBundle\Form\NewAnnotationType; use Wallabag\AnnotationBundle\Form\NewAnnotationType;
use Wallabag\AnnotationBundle\Repository\AnnotationRepository;
use Wallabag\CoreBundle\Entity\Entry; use Wallabag\CoreBundle\Entity\Entry;
class WallabagAnnotationController extends AbstractFOSRestController class WallabagAnnotationController extends AbstractFOSRestController
{ {
protected EntityManagerInterface $entityManager;
protected SerializerInterface $serializer;
protected FormFactoryInterface $formFactory;
public function __construct(EntityManagerInterface $entityManager, SerializerInterface $serializer, FormFactoryInterface $formFactory)
{
$this->entityManager = $entityManager;
$this->serializer = $serializer;
$this->formFactory = $formFactory;
}
/** /**
* Retrieve annotations for an entry. * Retrieve annotations for an entry.
* *
@ -25,16 +38,14 @@ class WallabagAnnotationController extends AbstractFOSRestController
* *
* @return JsonResponse * @return JsonResponse
*/ */
public function getAnnotationsAction(Entry $entry) public function getAnnotationsAction(Entry $entry, AnnotationRepository $annotationRepository)
{ {
$annotationRows = $this $annotationRows = $annotationRepository->findByEntryIdAndUserId($entry->getId(), $this->getUser()->getId());
->getDoctrine()
->getRepository(Annotation::class)
->findAnnotationsByPageId($entry->getId(), $this->getUser()->getId());
$total = \count($annotationRows); $total = \count($annotationRows);
$annotations = ['total' => $total, 'rows' => $annotationRows]; $annotations = ['total' => $total, 'rows' => $annotationRows];
$json = $this->get(SerializerInterface::class)->serialize($annotations, 'json'); $json = $this->serializer->serialize($annotations, 'json');
return (new JsonResponse())->setJson($json); return (new JsonResponse())->setJson($json);
} }
@ -52,21 +63,20 @@ class WallabagAnnotationController extends AbstractFOSRestController
{ {
$data = json_decode($request->getContent(), true); $data = json_decode($request->getContent(), true);
$em = $this->get('doctrine')->getManager();
$annotation = new Annotation($this->getUser()); $annotation = new Annotation($this->getUser());
$annotation->setEntry($entry); $annotation->setEntry($entry);
$form = $this->get(FormFactoryInterface::class)->createNamed('', NewAnnotationType::class, $annotation, [ $form = $this->formFactory->createNamed('', NewAnnotationType::class, $annotation, [
'csrf_protection' => false, 'csrf_protection' => false,
'allow_extra_fields' => true, 'allow_extra_fields' => true,
]); ]);
$form->submit($data); $form->submit($data);
if ($form->isValid()) { if ($form->isValid()) {
$em->persist($annotation); $this->entityManager->persist($annotation);
$em->flush(); $this->entityManager->flush();
$json = $this->get(SerializerInterface::class)->serialize($annotation, 'json'); $json = $this->serializer->serialize($annotation, 'json');
return JsonResponse::fromJsonString($json); return JsonResponse::fromJsonString($json);
} }
@ -80,31 +90,35 @@ class WallabagAnnotationController extends AbstractFOSRestController
* @see Wallabag\ApiBundle\Controller\WallabagRestController * @see Wallabag\ApiBundle\Controller\WallabagRestController
* *
* @Route("/annotations/{annotation}.{_format}", methods={"PUT"}, name="annotations_put_annotation", defaults={"_format": "json"}) * @Route("/annotations/{annotation}.{_format}", methods={"PUT"}, name="annotations_put_annotation", defaults={"_format": "json"})
* @ParamConverter("annotation", class="Wallabag\AnnotationBundle\Entity\Annotation")
* *
* @return JsonResponse * @return JsonResponse
*/ */
public function putAnnotationAction(Annotation $annotation, Request $request) public function putAnnotationAction(Request $request, AnnotationRepository $annotationRepository, int $annotation)
{ {
$data = json_decode($request->getContent(), true); try {
$annotation = $this->validateAnnotation($annotationRepository, $annotation, $this->getUser()->getId());
$form = $this->get(FormFactoryInterface::class)->createNamed('', EditAnnotationType::class, $annotation, [ $data = json_decode($request->getContent(), true, 512, \JSON_THROW_ON_ERROR);
'csrf_protection' => false,
'allow_extra_fields' => true,
]);
$form->submit($data);
if ($form->isValid()) { $form = $this->formFactory->createNamed('', EditAnnotationType::class, $annotation, [
$em = $this->get('doctrine')->getManager(); 'csrf_protection' => false,
$em->persist($annotation); 'allow_extra_fields' => true,
$em->flush(); ]);
$form->submit($data);
$json = $this->get(SerializerInterface::class)->serialize($annotation, 'json'); if ($form->isValid()) {
$this->entityManager->persist($annotation);
$this->entityManager->flush();
return JsonResponse::fromJsonString($json); $json = $this->serializer->serialize($annotation, 'json');
return JsonResponse::fromJsonString($json);
}
return $form;
} catch (\InvalidArgumentException $e) {
throw new NotFoundHttpException($e);
} }
return $form;
} }
/** /**
@ -113,18 +127,33 @@ class WallabagAnnotationController extends AbstractFOSRestController
* @see Wallabag\ApiBundle\Controller\WallabagRestController * @see Wallabag\ApiBundle\Controller\WallabagRestController
* *
* @Route("/annotations/{annotation}.{_format}", methods={"DELETE"}, name="annotations_delete_annotation", defaults={"_format": "json"}) * @Route("/annotations/{annotation}.{_format}", methods={"DELETE"}, name="annotations_delete_annotation", defaults={"_format": "json"})
* @ParamConverter("annotation", class="Wallabag\AnnotationBundle\Entity\Annotation")
* *
* @return JsonResponse * @return JsonResponse
*/ */
public function deleteAnnotationAction(Annotation $annotation) public function deleteAnnotationAction(AnnotationRepository $annotationRepository, int $annotation)
{ {
$em = $this->get('doctrine')->getManager(); try {
$em->remove($annotation); $annotation = $this->validateAnnotation($annotationRepository, $annotation, $this->getUser()->getId());
$em->flush();
$json = $this->get(SerializerInterface::class)->serialize($annotation, 'json'); $this->entityManager->remove($annotation);
$this->entityManager->flush();
return (new JsonResponse())->setJson($json); $json = $this->serializer->serialize($annotation, 'json');
return (new JsonResponse())->setJson($json);
} catch (\InvalidArgumentException $e) {
throw new NotFoundHttpException($e);
}
}
private function validateAnnotation(AnnotationRepository $annotationRepository, int $annotationId, int $userId)
{
$annotation = $annotationRepository->findOneByIdAndUserId($annotationId, $userId);
if (null === $annotation) {
throw new NotFoundHttpException();
}
return $annotation;
} }
} }

View file

@ -34,6 +34,15 @@ class AnnotationFixtures extends Fixture implements DependentFixtureInterface
$this->addReference('annotation2', $annotation2); $this->addReference('annotation2', $annotation2);
$annotation3 = new Annotation($this->getReference('bob-user'));
$annotation3->setEntry($this->getReference('entry3'));
$annotation3->setText('This is my first annotation !');
$annotation3->setQuote('content');
$manager->persist($annotation3);
$this->addReference('annotation3', $annotation3);
$manager->flush(); $manager->flush();
} }

View file

@ -12,9 +12,6 @@ class Configuration implements ConfigurationInterface
*/ */
public function getConfigTreeBuilder() public function getConfigTreeBuilder()
{ {
$treeBuilder = new TreeBuilder(); return new TreeBuilder('wallabag_annotation');
$rootNode = $treeBuilder->root('wallabag_annotation');
return $treeBuilder;
} }
} }

View file

@ -49,6 +49,24 @@ class AnnotationRepository extends ServiceEntityRepository
; ;
} }
/**
* Find annotation by id and user.
*
* @param int $annotationId
* @param int $userId
*
* @return Annotation
*/
public function findOneByIdAndUserId($annotationId, $userId)
{
return $this->createQueryBuilder('a')
->where('a.id = :annotationId')->setParameter('annotationId', $annotationId)
->andWhere('a.user = :userId')->setParameter('userId', $userId)
->setMaxResults(1)
->getQuery()
->getOneOrNullResult();
}
/** /**
* Find annotations for entry id. * Find annotations for entry id.
* *
@ -57,7 +75,7 @@ class AnnotationRepository extends ServiceEntityRepository
* *
* @return array * @return array
*/ */
public function findAnnotationsByPageId($entryId, $userId) public function findByEntryIdAndUserId($entryId, $userId)
{ {
return $this->createQueryBuilder('a') return $this->createQueryBuilder('a')
->where('a.entry = :entryId')->setParameter('entryId', $entryId) ->where('a.entry = :entryId')->setParameter('entryId', $entryId)
@ -72,9 +90,9 @@ class AnnotationRepository extends ServiceEntityRepository
* *
* @param int $entryId * @param int $entryId
* *
* @return array * @return Annotation|null
*/ */
public function findLastAnnotationByPageId($entryId, $userId) public function findLastAnnotationByUserId($entryId, $userId)
{ {
return $this->createQueryBuilder('a') return $this->createQueryBuilder('a')
->where('a.entry = :entryId')->setParameter('entryId', $entryId) ->where('a.entry = :entryId')->setParameter('entryId', $entryId)

View file

@ -3,8 +3,7 @@
namespace Wallabag\ApiBundle\Controller; namespace Wallabag\ApiBundle\Controller;
use Nelmio\ApiDocBundle\Annotation\Operation; use Nelmio\ApiDocBundle\Annotation\Operation;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; use OpenApi\Annotations as OA;
use Swagger\Annotations as SWG;
use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
@ -19,15 +18,17 @@ class AnnotationRestController extends WallabagRestController
* @Operation( * @Operation(
* tags={"Annotations"}, * tags={"Annotations"},
* summary="Retrieve annotations for an entry.", * summary="Retrieve annotations for an entry.",
* @SWG\Parameter( * @OA\Parameter(
* name="entry", * name="entry",
* in="path", * in="path",
* description="The entry ID", * description="The entry ID",
* required=true, * required=true,
* pattern="\w+", * @OA\Schema(
* type="integer" * type="integer",
* pattern="\w+",
* )
* ), * ),
* @SWG\Response( * @OA\Response(
* response="200", * response="200",
* description="Returned when successful" * description="Returned when successful"
* ) * )
@ -52,40 +53,48 @@ class AnnotationRestController extends WallabagRestController
* @Operation( * @Operation(
* tags={"Annotations"}, * tags={"Annotations"},
* summary="Creates a new annotation.", * summary="Creates a new annotation.",
* @SWG\Parameter( * @OA\Parameter(
* name="entry", * name="entry",
* in="path", * in="path",
* description="The entry ID", * description="The entry ID",
* required=true, * required=true,
* pattern="\w+", * @OA\Schema(
* type="integer" * type="integer",
* ), * pattern="\w+",
* @SWG\Parameter(
* name="ranges",
* in="body",
* description="The range array for the annotation",
* required=false,
* pattern="\w+",
* @SWG\Schema(
* type="array",
* @SWG\Items(type="string")
* ) * )
* ), * ),
* @SWG\Parameter( * @OA\RequestBody(
* name="quote", * @OA\JsonContent(
* in="body", * type="object",
* description="The annotated text", * required={"text"},
* required=false, * @OA\Property(
* @SWG\Schema(type="string") * property="ranges",
* type="array",
* description="The range array for the annotation",
* @OA\Items(
* type="string",
* pattern="\w+",
* )
* ),
* @OA\Property(
* property="quote",
* type="array",
* description="The annotated text",
* @OA\Items(
* type="string",
* )
* ),
* @OA\Property(
* property="text",
* type="array",
* description="Content of annotation",
* @OA\Items(
* type="string",
* )
* ),
* )
* ), * ),
* @SWG\Parameter( * @OA\Response(
* name="text",
* in="body",
* description="Content of annotation",
* required=true,
* @SWG\Schema(type="string")
* ),
* @SWG\Response(
* response="200", * response="200",
* description="Returned when successful" * description="Returned when successful"
* ) * )
@ -111,26 +120,27 @@ class AnnotationRestController extends WallabagRestController
* @Operation( * @Operation(
* tags={"Annotations"}, * tags={"Annotations"},
* summary="Updates an annotation.", * summary="Updates an annotation.",
* @SWG\Parameter( * @OA\Parameter(
* name="annotation", * name="annotation",
* in="path", * in="path",
* description="The annotation ID", * description="The annotation ID",
* required=true, * required=true,
* pattern="\w+", * @OA\Schema(
* type="string" * type="string",
* pattern="\w+",
* )
* ), * ),
* @SWG\Response( * @OA\Response(
* response="200", * response="200",
* description="Returned when successful" * description="Returned when successful"
* ) * )
* ) * )
* *
* @Route("/api/annotations/{annotation}.{_format}", methods={"PUT"}, name="api_put_annotation", defaults={"_format": "json"}) * @Route("/api/annotations/{annotation}.{_format}", methods={"PUT"}, name="api_put_annotation", defaults={"_format": "json"})
* @ParamConverter("annotation", class="Wallabag\AnnotationBundle\Entity\Annotation")
* *
* @return JsonResponse * @return JsonResponse
*/ */
public function putAnnotationAction(Annotation $annotation, Request $request) public function putAnnotationAction(int $annotation, Request $request)
{ {
$this->validateAuthentication(); $this->validateAuthentication();
@ -146,26 +156,27 @@ class AnnotationRestController extends WallabagRestController
* @Operation( * @Operation(
* tags={"Annotations"}, * tags={"Annotations"},
* summary="Removes an annotation.", * summary="Removes an annotation.",
* @SWG\Parameter( * @OA\Parameter(
* name="annotation", * name="annotation",
* in="path", * in="path",
* description="The annotation ID", * description="The annotation ID",
* required=true, * required=true,
* pattern="\w+", * @OA\Schema(
* type="string" * type="string",
* pattern="\w+",
* )
* ), * ),
* @SWG\Response( * @OA\Response(
* response="200", * response="200",
* description="Returned when successful" * description="Returned when successful"
* ) * )
* ) * )
* *
* @Route("/api/annotations/{annotation}.{_format}", methods={"DELETE"}, name="api_delete_annotation", defaults={"_format": "json"}) * @Route("/api/annotations/{annotation}.{_format}", methods={"DELETE"}, name="api_delete_annotation", defaults={"_format": "json"})
* @ParamConverter("annotation", class="Wallabag\AnnotationBundle\Entity\Annotation")
* *
* @return JsonResponse * @return JsonResponse
*/ */
public function deleteAnnotationAction(Annotation $annotation) public function deleteAnnotationAction(int $annotation)
{ {
$this->validateAuthentication(); $this->validateAuthentication();

View file

@ -5,7 +5,7 @@ namespace Wallabag\ApiBundle\Controller;
use JMS\Serializer\SerializationContext; use JMS\Serializer\SerializationContext;
use JMS\Serializer\SerializerInterface; use JMS\Serializer\SerializerInterface;
use Nelmio\ApiDocBundle\Annotation\Operation; use Nelmio\ApiDocBundle\Annotation\Operation;
use Swagger\Annotations as SWG; use OpenApi\Annotations as OA;
use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
@ -17,7 +17,7 @@ class ConfigRestController extends WallabagRestController
* @Operation( * @Operation(
* tags={"Config"}, * tags={"Config"},
* summary="Retrieve configuration for current user.", * summary="Retrieve configuration for current user.",
* @SWG\Response( * @OA\Response(
* response="200", * response="200",
* description="Returned when successful" * description="Returned when successful"
* ) * )
@ -27,11 +27,11 @@ class ConfigRestController extends WallabagRestController
* *
* @return JsonResponse * @return JsonResponse
*/ */
public function getConfigAction() public function getConfigAction(SerializerInterface $serializer)
{ {
$this->validateAuthentication(); $this->validateAuthentication();
$json = $this->get(SerializerInterface::class)->serialize( $json = $serializer->serialize(
$this->getUser()->getConfig(), $this->getUser()->getConfig(),
'json', 'json',
SerializationContext::create()->setGroups(['config_api']) SerializationContext::create()->setGroups(['config_api'])

View file

@ -2,17 +2,18 @@
namespace Wallabag\ApiBundle\Controller; namespace Wallabag\ApiBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Translation\TranslatorInterface; use Symfony\Contracts\Translation\TranslatorInterface;
use Wallabag\ApiBundle\Entity\Client; use Wallabag\ApiBundle\Entity\Client;
use Wallabag\ApiBundle\Form\Type\ClientType; use Wallabag\ApiBundle\Form\Type\ClientType;
use Wallabag\ApiBundle\Repository\ClientRepository;
class DeveloperController extends Controller class DeveloperController extends AbstractController
{ {
/** /**
* List all clients and link to create a new one. * List all clients and link to create a new one.
@ -21,9 +22,9 @@ class DeveloperController extends Controller
* *
* @return Response * @return Response
*/ */
public function indexAction() public function indexAction(ClientRepository $repo)
{ {
$clients = $this->get('doctrine')->getRepository(Client::class)->findByUser($this->getUser()->getId()); $clients = $repo->findByUser($this->getUser()->getId());
return $this->render('@WallabagCore/Developer/index.html.twig', [ return $this->render('@WallabagCore/Developer/index.html.twig', [
'clients' => $clients, 'clients' => $clients,
@ -37,21 +38,20 @@ class DeveloperController extends Controller
* *
* @return Response * @return Response
*/ */
public function createClientAction(Request $request) public function createClientAction(Request $request, EntityManagerInterface $entityManager, TranslatorInterface $translator)
{ {
$em = $this->get('doctrine')->getManager();
$client = new Client($this->getUser()); $client = new Client($this->getUser());
$clientForm = $this->createForm(ClientType::class, $client); $clientForm = $this->createForm(ClientType::class, $client);
$clientForm->handleRequest($request); $clientForm->handleRequest($request);
if ($clientForm->isSubmitted() && $clientForm->isValid()) { if ($clientForm->isSubmitted() && $clientForm->isValid()) {
$client->setAllowedGrantTypes(['token', 'authorization_code', 'password', 'refresh_token']); $client->setAllowedGrantTypes(['token', 'authorization_code', 'password', 'refresh_token']);
$em->persist($client); $entityManager->persist($client);
$em->flush(); $entityManager->flush();
$this->get(SessionInterface::class)->getFlashBag()->add( $this->addFlash(
'notice', 'notice',
$this->get(TranslatorInterface::class)->trans('flashes.developer.notice.client_created', ['%name%' => $client->getName()]) $translator->trans('flashes.developer.notice.client_created', ['%name%' => $client->getName()])
); );
return $this->render('@WallabagCore/Developer/client_parameters.html.twig', [ return $this->render('@WallabagCore/Developer/client_parameters.html.twig', [
@ -73,19 +73,18 @@ class DeveloperController extends Controller
* *
* @return RedirectResponse * @return RedirectResponse
*/ */
public function deleteClientAction(Client $client) public function deleteClientAction(Client $client, EntityManagerInterface $entityManager, TranslatorInterface $translator)
{ {
if (null === $this->getUser() || $client->getUser()->getId() !== $this->getUser()->getId()) { if (null === $this->getUser() || $client->getUser()->getId() !== $this->getUser()->getId()) {
throw $this->createAccessDeniedException('You can not access this client.'); throw $this->createAccessDeniedException('You can not access this client.');
} }
$em = $this->get('doctrine')->getManager(); $entityManager->remove($client);
$em->remove($client); $entityManager->flush();
$em->flush();
$this->get(SessionInterface::class)->getFlashBag()->add( $this->addFlash(
'notice', 'notice',
$this->get(TranslatorInterface::class)->trans('flashes.developer.notice.client_deleted', ['%name%' => $client->getName()]) $translator->trans('flashes.developer.notice.client_deleted', ['%name%' => $client->getName()])
); );
return $this->redirect($this->generateUrl('developer')); return $this->redirect($this->generateUrl('developer'));
@ -100,6 +99,9 @@ class DeveloperController extends Controller
*/ */
public function howtoFirstAppAction() public function howtoFirstAppAction()
{ {
return $this->render('@WallabagCore/Developer/howto_app.html.twig'); return $this->render('@WallabagCore/Developer/howto_app.html.twig',
[
'wallabag_url' => $this->getParameter('domain_name'),
]);
} }
} }

File diff suppressed because it is too large Load diff

View file

@ -5,9 +5,9 @@ namespace Wallabag\ApiBundle\Controller;
use Hateoas\Configuration\Route as HateoasRoute; use Hateoas\Configuration\Route as HateoasRoute;
use Hateoas\Representation\Factory\PagerfantaFactory; use Hateoas\Representation\Factory\PagerfantaFactory;
use Nelmio\ApiDocBundle\Annotation\Operation; use Nelmio\ApiDocBundle\Annotation\Operation;
use OpenApi\Annotations as OA;
use Pagerfanta\Doctrine\ORM\QueryAdapter as DoctrineORMAdapter; use Pagerfanta\Doctrine\ORM\QueryAdapter as DoctrineORMAdapter;
use Pagerfanta\Pagerfanta; use Pagerfanta\Pagerfanta;
use Swagger\Annotations as SWG;
use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
@ -21,34 +21,34 @@ class SearchRestController extends WallabagRestController
* @Operation( * @Operation(
* tags={"Search"}, * tags={"Search"},
* summary="Search all entries by term.", * summary="Search all entries by term.",
* @SWG\Parameter( * @OA\Parameter(
* name="term", * name="term",
* in="body", * in="query",
* description="Any query term", * description="Any query term",
* required=false, * required=false,
* @SWG\Schema(type="string") * @OA\Schema(type="string")
* ), * ),
* @SWG\Parameter( * @OA\Parameter(
* name="page", * name="page",
* in="body", * in="query",
* description="what page you want.", * description="what page you want.",
* required=false, * required=false,
* @SWG\Schema( * @OA\Schema(
* type="integer", * type="integer",
* default=1 * default=1
* ) * )
* ), * ),
* @SWG\Parameter( * @OA\Parameter(
* name="perPage", * name="perPage",
* in="body", * in="query",
* description="results per page.", * description="results per page.",
* required=false, * required=false,
* @SWG\Schema( * @OA\Schema(
* type="integer", * type="integer",
* default=30 * default=30
* ) * )
* ), * ),
* @SWG\Response( * @OA\Response(
* response="200", * response="200",
* description="Returned when successful" * description="Returned when successful"
* ) * )
@ -58,7 +58,7 @@ class SearchRestController extends WallabagRestController
* *
* @return JsonResponse * @return JsonResponse
*/ */
public function getSearchAction(Request $request) public function getSearchAction(Request $request, EntryRepository $entryRepository)
{ {
$this->validateAuthentication(); $this->validateAuthentication();
@ -66,12 +66,11 @@ class SearchRestController extends WallabagRestController
$page = (int) $request->query->get('page', 1); $page = (int) $request->query->get('page', 1);
$perPage = (int) $request->query->get('perPage', 30); $perPage = (int) $request->query->get('perPage', 30);
$qb = $this->get(EntryRepository::class) $qb = $entryRepository->getBuilderForSearchByUser(
->getBuilderForSearchByUser( $this->getUser()->getId(),
$this->getUser()->getId(), $term,
$term, null
null );
);
$pagerAdapter = new DoctrineORMAdapter($qb->getQuery(), true, false); $pagerAdapter = new DoctrineORMAdapter($qb->getQuery(), true, false);
$pager = new Pagerfanta($pagerAdapter); $pager = new Pagerfanta($pagerAdapter);

View file

@ -2,14 +2,15 @@
namespace Wallabag\ApiBundle\Controller; namespace Wallabag\ApiBundle\Controller;
use JMS\Serializer\SerializerInterface;
use Nelmio\ApiDocBundle\Annotation\Operation; use Nelmio\ApiDocBundle\Annotation\Operation;
use Swagger\Annotations as SWG; use OpenApi\Annotations as OA;
use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
use Wallabag\CoreBundle\Entity\Entry; use Wallabag\CoreBundle\Entity\Entry;
use Wallabag\CoreBundle\Entity\Tag; use Wallabag\CoreBundle\Entity\Tag;
use Wallabag\CoreBundle\Repository\EntryRepository;
use Wallabag\CoreBundle\Repository\TagRepository;
class TagRestController extends WallabagRestController class TagRestController extends WallabagRestController
{ {
@ -19,7 +20,7 @@ class TagRestController extends WallabagRestController
* @Operation( * @Operation(
* tags={"Tags"}, * tags={"Tags"},
* summary="Retrieve all tags.", * summary="Retrieve all tags.",
* @SWG\Response( * @OA\Response(
* response="200", * response="200",
* description="Returned when successful" * description="Returned when successful"
* ) * )
@ -29,15 +30,13 @@ class TagRestController extends WallabagRestController
* *
* @return JsonResponse * @return JsonResponse
*/ */
public function getTagsAction() public function getTagsAction(TagRepository $tagRepository)
{ {
$this->validateAuthentication(); $this->validateAuthentication();
$tags = $this->get('doctrine') $tags = $tagRepository->findAllFlatTagsWithNbEntries($this->getUser()->getId());
->getRepository(Tag::class)
->findAllFlatTagsWithNbEntries($this->getUser()->getId());
$json = $this->get(SerializerInterface::class)->serialize($tags, 'json'); $json = $this->serializer->serialize($tags, 'json');
return (new JsonResponse())->setJson($json); return (new JsonResponse())->setJson($json);
} }
@ -48,15 +47,17 @@ class TagRestController extends WallabagRestController
* @Operation( * @Operation(
* tags={"Tags"}, * tags={"Tags"},
* summary="Permanently remove one tag from every entry by passing the Tag label.", * summary="Permanently remove one tag from every entry by passing the Tag label.",
* @SWG\Parameter( * @OA\Parameter(
* name="tag", * name="tag",
* in="body", * in="query",
* description="Tag as a string", * description="Tag as a string",
* required=true, * required=true,
* pattern="\w+", * @OA\Schema(
* @SWG\Schema(type="string") * type="string",
* pattern="\w+",
* )
* ), * ),
* @SWG\Response( * @OA\Response(
* response="200", * response="200",
* description="Returned when successful" * description="Returned when successful"
* ) * )
@ -66,12 +67,12 @@ class TagRestController extends WallabagRestController
* *
* @return JsonResponse * @return JsonResponse
*/ */
public function deleteTagLabelAction(Request $request) public function deleteTagLabelAction(Request $request, TagRepository $tagRepository, EntryRepository $entryRepository)
{ {
$this->validateAuthentication(); $this->validateAuthentication();
$label = $request->get('tag', ''); $label = $request->get('tag', '');
$tags = $this->get('doctrine')->getRepository(Tag::class)->findByLabelsAndUser([$label], $this->getUser()->getId()); $tags = $tagRepository->findByLabelsAndUser([$label], $this->getUser()->getId());
if (empty($tags)) { if (empty($tags)) {
throw $this->createNotFoundException('Tag not found'); throw $this->createNotFoundException('Tag not found');
@ -79,13 +80,11 @@ class TagRestController extends WallabagRestController
$tag = $tags[0]; $tag = $tags[0];
$this->get('doctrine') $entryRepository->removeTag($this->getUser()->getId(), $tag);
->getRepository(Entry::class)
->removeTag($this->getUser()->getId(), $tag);
$this->cleanOrphanTag($tag); $this->cleanOrphanTag($tag);
$json = $this->get(SerializerInterface::class)->serialize($tag, 'json'); $json = $this->serializer->serialize($tag, 'json');
return (new JsonResponse())->setJson($json); return (new JsonResponse())->setJson($json);
} }
@ -96,17 +95,17 @@ class TagRestController extends WallabagRestController
* @Operation( * @Operation(
* tags={"Tags"}, * tags={"Tags"},
* summary="Permanently remove some tags from every entry.", * summary="Permanently remove some tags from every entry.",
* @SWG\Parameter( * @OA\Parameter(
* name="tags", * name="tags",
* in="body", * in="query",
* description="Tags as strings (comma splitted)", * description="Tags as strings (comma splitted)",
* required=true, * required=true,
* @SWG\Schema( * @OA\Schema(
* type="string", * type="string",
* example="tag1,tag2", * example="tag1,tag2",
* ) * )
* ), * ),
* @SWG\Response( * @OA\Response(
* response="200", * response="200",
* description="Returned when successful" * description="Returned when successful"
* ) * )
@ -116,25 +115,23 @@ class TagRestController extends WallabagRestController
* *
* @return JsonResponse * @return JsonResponse
*/ */
public function deleteTagsLabelAction(Request $request) public function deleteTagsLabelAction(Request $request, TagRepository $tagRepository, EntryRepository $entryRepository)
{ {
$this->validateAuthentication(); $this->validateAuthentication();
$tagsLabels = $request->get('tags', ''); $tagsLabels = $request->get('tags', '');
$tags = $this->get('doctrine')->getRepository(Tag::class)->findByLabelsAndUser(explode(',', $tagsLabels), $this->getUser()->getId()); $tags = $tagRepository->findByLabelsAndUser(explode(',', $tagsLabels), $this->getUser()->getId());
if (empty($tags)) { if (empty($tags)) {
throw $this->createNotFoundException('Tags not found'); throw $this->createNotFoundException('Tags not found');
} }
$this->get('doctrine') $entryRepository->removeTags($this->getUser()->getId(), $tags);
->getRepository(Entry::class)
->removeTags($this->getUser()->getId(), $tags);
$this->cleanOrphanTag($tags); $this->cleanOrphanTag($tags);
$json = $this->get(SerializerInterface::class)->serialize($tags, 'json'); $json = $this->serializer->serialize($tags, 'json');
return (new JsonResponse())->setJson($json); return (new JsonResponse())->setJson($json);
} }
@ -145,15 +142,17 @@ class TagRestController extends WallabagRestController
* @Operation( * @Operation(
* tags={"Tags"}, * tags={"Tags"},
* summary="Permanently remove one tag from every entry by passing the Tag ID.", * summary="Permanently remove one tag from every entry by passing the Tag ID.",
* @SWG\Parameter( * @OA\Parameter(
* name="tag", * name="tag",
* in="body", * in="path",
* description="The tag", * description="The tag",
* required=true, * required=true,
* pattern="\w+", * @OA\Schema(
* @SWG\Schema(type="integer") * type="integer",
* pattern="\w+",
* )
* ), * ),
* @SWG\Response( * @OA\Response(
* response="200", * response="200",
* description="Returned when successful" * description="Returned when successful"
* ) * )
@ -163,23 +162,21 @@ class TagRestController extends WallabagRestController
* *
* @return JsonResponse * @return JsonResponse
*/ */
public function deleteTagAction(Tag $tag) public function deleteTagAction(Tag $tag, TagRepository $tagRepository, EntryRepository $entryRepository)
{ {
$this->validateAuthentication(); $this->validateAuthentication();
$tagFromDb = $this->get('doctrine')->getRepository(Tag::class)->findByLabelsAndUser([$tag->getLabel()], $this->getUser()->getId()); $tagFromDb = $tagRepository->findByLabelsAndUser([$tag->getLabel()], $this->getUser()->getId());
if (empty($tagFromDb)) { if (empty($tagFromDb)) {
throw $this->createNotFoundException('Tag not found'); throw $this->createNotFoundException('Tag not found');
} }
$this->get('doctrine') $entryRepository->removeTag($this->getUser()->getId(), $tag);
->getRepository(Entry::class)
->removeTag($this->getUser()->getId(), $tag);
$this->cleanOrphanTag($tag); $this->cleanOrphanTag($tag);
$json = $this->get(SerializerInterface::class)->serialize($tag, 'json'); $json = $this->serializer->serialize($tag, 'json');
return (new JsonResponse())->setJson($json); return (new JsonResponse())->setJson($json);
} }
@ -195,14 +192,12 @@ class TagRestController extends WallabagRestController
$tags = [$tags]; $tags = [$tags];
} }
$em = $this->get('doctrine')->getManager();
foreach ($tags as $tag) { foreach ($tags as $tag) {
if (0 === \count($tag->getEntries())) { if (0 === \count($tag->getEntries())) {
$em->remove($tag); $this->entityManager->remove($tag);
} }
} }
$em->flush(); $this->entityManager->flush();
} }
} }

View file

@ -5,7 +5,7 @@ namespace Wallabag\ApiBundle\Controller;
use JMS\Serializer\SerializationContext; use JMS\Serializer\SerializationContext;
use JMS\Serializer\SerializerBuilder; use JMS\Serializer\SerializerBuilder;
use Nelmio\ApiDocBundle\Annotation\Operation; use Nelmio\ApiDocBundle\Annotation\Operation;
use Swagger\Annotations as SWG; use OpenApi\Annotations as OA;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
@ -17,7 +17,7 @@ class TaggingRuleRestController extends WallabagRestController
* @Operation( * @Operation(
* tags={"TaggingRule"}, * tags={"TaggingRule"},
* summary="Export all tagging rules as a json file.", * summary="Export all tagging rules as a json file.",
* @SWG\Response( * @OA\Response(
* response="200", * response="200",
* description="Returned when successful" * description="Returned when successful"
* ) * )

View file

@ -3,18 +3,18 @@
namespace Wallabag\ApiBundle\Controller; namespace Wallabag\ApiBundle\Controller;
use Craue\ConfigBundle\Util\Config; use Craue\ConfigBundle\Util\Config;
use Doctrine\ORM\EntityManagerInterface;
use FOS\UserBundle\Event\UserEvent; use FOS\UserBundle\Event\UserEvent;
use FOS\UserBundle\FOSUserEvents; use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Model\UserManagerInterface; use FOS\UserBundle\Model\UserManagerInterface;
use JMS\Serializer\SerializationContext; use JMS\Serializer\SerializationContext;
use JMS\Serializer\SerializerInterface; use Nelmio\ApiDocBundle\Annotation\Model;
use Nelmio\ApiDocBundle\Annotation\Operation; use Nelmio\ApiDocBundle\Annotation\Operation;
use Swagger\Annotations as SWG; use OpenApi\Annotations as OA;
use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Translation\TranslatorInterface;
use Wallabag\ApiBundle\Entity\Client; use Wallabag\ApiBundle\Entity\Client;
use Wallabag\UserBundle\Entity\User; use Wallabag\UserBundle\Entity\User;
use Wallabag\UserBundle\Form\NewUserType; use Wallabag\UserBundle\Form\NewUserType;
@ -27,9 +27,10 @@ class UserRestController extends WallabagRestController
* @Operation( * @Operation(
* tags={"User"}, * tags={"User"},
* summary="Retrieve current logged in user informations.", * summary="Retrieve current logged in user informations.",
* @SWG\Response( * @OA\Response(
* response="200", * response="200",
* description="Returned when successful" * description="Returned when successful",
* @Model(type=User::class, groups={"user_api"}))
* ) * )
* ) * )
* *
@ -50,37 +51,48 @@ class UserRestController extends WallabagRestController
* @Operation( * @Operation(
* tags={"User"}, * tags={"User"},
* summary="Register an user and create a client.", * summary="Register an user and create a client.",
* @SWG\Parameter( * @OA\RequestBody(
* name="username", * @OA\JsonContent(
* in="body", * type="object",
* description="The user's username", * required={"username", "password", "email"},
* required=true, * @OA\Property(
* @SWG\Schema(type="string") * property="username",
* description="The user's username",
* type="string",
* example="wallabag",
* ),
* @OA\Property(
* property="password",
* description="The user's password",
* type="string",
* example="hidden_value",
* ),
* @OA\Property(
* property="email",
* description="The user's email",
* type="string",
* example="wallabag@wallabag.io",
* ),
* @OA\Property(
* property="client_name",
* description="The client name (to be used by your app)",
* type="string",
* example="Fancy App",
* ),
* )
* ), * ),
* @SWG\Parameter( * @OA\Response(
* name="password", * response="201",
* in="body", * description="Returned when successful",
* description="The user's password", * @Model(type=User::class, groups={"user_api_with_client"})),
* required=true,
* @SWG\Schema(type="string")
* ), * ),
* @SWG\Parameter( * @OA\Response(
* name="email", * response="403",
* in="body", * description="Server doesn't allow registrations"
* description="The user's email",
* required=true,
* @SWG\Schema(type="string")
* ), * ),
* @SWG\Parameter( * @OA\Response(
* name="client_name", * response="400",
* in="body", * description="Request is incorrectly formatted"
* description="The client name (to be used by your app)",
* required=true,
* @SWG\Schema(type="string")
* ),
* @SWG\Response(
* response="200",
* description="Returned when successful"
* ) * )
* ) * )
* *
@ -90,17 +102,16 @@ class UserRestController extends WallabagRestController
* *
* @return JsonResponse * @return JsonResponse
*/ */
public function putUserAction(Request $request) public function putUserAction(Request $request, Config $craueConfig, UserManagerInterface $userManager, EntityManagerInterface $entityManager, EventDispatcherInterface $eventDispatcher)
{ {
if (!$this->container->getParameter('fosuser_registration') || !$this->get(Config::class)->get('api_user_registration')) { if (!$this->getParameter('fosuser_registration') || !$craueConfig->get('api_user_registration')) {
$json = $this->get(SerializerInterface::class)->serialize(['error' => "Server doesn't allow registrations"], 'json'); $json = $this->serializer->serialize(['error' => "Server doesn't allow registrations"], 'json');
return (new JsonResponse()) return (new JsonResponse())
->setJson($json) ->setJson($json)
->setStatusCode(JsonResponse::HTTP_FORBIDDEN); ->setStatusCode(JsonResponse::HTTP_FORBIDDEN);
} }
$userManager = $this->get(UserManagerInterface::class);
$user = $userManager->createUser(); $user = $userManager->createUser();
\assert($user instanceof User); \assert($user instanceof User);
// user will be disabled BY DEFAULT to avoid spamming account to be enabled // user will be disabled BY DEFAULT to avoid spamming account to be enabled
@ -140,7 +151,7 @@ class UserRestController extends WallabagRestController
$errors['password'] = $this->translateErrors($data['plainPassword']['children']['first']['errors']); $errors['password'] = $this->translateErrors($data['plainPassword']['children']['first']['errors']);
} }
$json = $this->get(SerializerInterface::class)->serialize(['error' => $errors], 'json'); $json = $this->serializer->serialize(['error' => $errors], 'json');
return (new JsonResponse()) return (new JsonResponse())
->setJson($json) ->setJson($json)
@ -151,15 +162,14 @@ class UserRestController extends WallabagRestController
$client = new Client($user); $client = new Client($user);
$client->setName($request->request->get('client_name', 'Default client')); $client->setName($request->request->get('client_name', 'Default client'));
$this->get('doctrine')->getManager()->persist($client); $entityManager->persist($client);
$user->addClient($client); $user->addClient($client);
$userManager->updateUser($user); $userManager->updateUser($user);
// dispatch a created event so the associated config will be created // dispatch a created event so the associated config will be created
$event = new UserEvent($user, $request); $eventDispatcher->dispatch(new UserEvent($user, $request), FOSUserEvents::USER_CREATED);
$this->get(EventDispatcherInterface::class)->dispatch(FOSUserEvents::USER_CREATED, $event);
return $this->sendUser($user, 'user_api_with_client', JsonResponse::HTTP_CREATED); return $this->sendUser($user, 'user_api_with_client', JsonResponse::HTTP_CREATED);
} }
@ -174,7 +184,7 @@ class UserRestController extends WallabagRestController
*/ */
private function sendUser(User $user, $group = 'user_api', $status = JsonResponse::HTTP_OK) private function sendUser(User $user, $group = 'user_api', $status = JsonResponse::HTTP_OK)
{ {
$json = $this->get(SerializerInterface::class)->serialize( $json = $this->serializer->serialize(
$user, $user,
'json', 'json',
SerializationContext::create()->setGroups([$group]) SerializationContext::create()->setGroups([$group])
@ -196,7 +206,7 @@ class UserRestController extends WallabagRestController
{ {
$translatedErrors = []; $translatedErrors = [];
foreach ($errors as $error) { foreach ($errors as $error) {
$translatedErrors[] = $this->get(TranslatorInterface::class)->trans($error); $translatedErrors[] = $this->translator->trans($error);
} }
return $translatedErrors; return $translatedErrors;

View file

@ -2,29 +2,54 @@
namespace Wallabag\ApiBundle\Controller; namespace Wallabag\ApiBundle\Controller;
use Craue\ConfigBundle\Util\Config;
use Doctrine\ORM\EntityManagerInterface;
use FOS\RestBundle\Controller\AbstractFOSRestController; use FOS\RestBundle\Controller\AbstractFOSRestController;
use JMS\Serializer\SerializationContext; use JMS\Serializer\SerializationContext;
use JMS\Serializer\SerializerInterface; use JMS\Serializer\SerializerInterface;
use Nelmio\ApiDocBundle\Annotation\Model;
use Nelmio\ApiDocBundle\Annotation\Operation; use Nelmio\ApiDocBundle\Annotation\Operation;
use Swagger\Annotations as SWG; use OpenApi\Annotations as OA;
use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Security\Core\Exception\AccessDeniedException; use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Contracts\Translation\TranslatorInterface;
use Wallabag\ApiBundle\Entity\ApplicationInfo;
use Wallabag\UserBundle\Entity\User; use Wallabag\UserBundle\Entity\User;
class WallabagRestController extends AbstractFOSRestController class WallabagRestController extends AbstractFOSRestController
{ {
protected EntityManagerInterface $entityManager;
protected SerializerInterface $serializer;
protected AuthorizationCheckerInterface $authorizationChecker;
protected TokenStorageInterface $tokenStorage;
protected TranslatorInterface $translator;
public function __construct(EntityManagerInterface $entityManager, SerializerInterface $serializer, AuthorizationCheckerInterface $authorizationChecker, TokenStorageInterface $tokenStorage, TranslatorInterface $translator)
{
$this->entityManager = $entityManager;
$this->serializer = $serializer;
$this->authorizationChecker = $authorizationChecker;
$this->tokenStorage = $tokenStorage;
$this->translator = $translator;
}
/** /**
* Retrieve version number. * Retrieve version number.
* *
* @Operation( * @Operation(
* tags={"Informations"}, * tags={"Information"},
* summary="Retrieve version number.", * summary="Retrieve version number.",
* @SWG\Response( * @OA\Response(
* response="200", * response="200",
* description="Returned when successful" * description="Returned when successful",
* @OA\JsonContent(
* description="Version number of the application.",
* type="string",
* example="2.5.2",
* )
* ) * )
* ) * )
* *
@ -36,21 +61,20 @@ class WallabagRestController extends AbstractFOSRestController
*/ */
public function getVersionAction() public function getVersionAction()
{ {
$version = $this->container->getParameter('wallabag_core.version'); $version = $this->getParameter('wallabag_core.version');
$json = $this->get(SerializerInterface::class)->serialize($version, 'json'); $json = $this->serializer->serialize($version, 'json');
return (new JsonResponse())->setJson($json); return (new JsonResponse())->setJson($json);
} }
/** /**
* Retrieve information about the wallabag instance.
*
* @Operation( * @Operation(
* tags={"Informations"}, * tags={"Information"},
* summary="Retrieve information about the wallabag instance.", * summary="Retrieve information about the running wallabag application.",
* @SWG\Response( * @OA\Response(
* response="200", * response="200",
* description="Returned when successful" * description="Returned when successful",
* @Model(type=ApplicationInfo::class),
* ) * )
* ) * )
* *
@ -58,20 +82,19 @@ class WallabagRestController extends AbstractFOSRestController
* *
* @return JsonResponse * @return JsonResponse
*/ */
public function getInfoAction() public function getInfoAction(Config $craueConfig)
{ {
$info = [ $info = new ApplicationInfo(
'appname' => 'wallabag', $this->getParameter('wallabag_core.version'),
'version' => $this->container->getParameter('wallabag_core.version'), $this->getParameter('fosuser_registration') && $craueConfig->get('api_user_registration'),
'allowed_registration' => $this->container->getParameter('fosuser_registration'), );
];
return (new JsonResponse())->setJson($this->get(SerializerInterface::class)->serialize($info, 'json')); return (new JsonResponse())->setJson($this->serializer->serialize($info, 'json'));
} }
protected function validateAuthentication() protected function validateAuthentication()
{ {
if (false === $this->get(AuthorizationCheckerInterface::class)->isGranted('IS_AUTHENTICATED_FULLY')) { if (false === $this->authorizationChecker->isGranted('IS_AUTHENTICATED_FULLY')) {
throw new AccessDeniedException(); throw new AccessDeniedException();
} }
} }
@ -84,8 +107,9 @@ class WallabagRestController extends AbstractFOSRestController
*/ */
protected function validateUserAccess($requestUserId) protected function validateUserAccess($requestUserId)
{ {
$user = $this->get(TokenStorageInterface::class)->getToken()->getUser(); $user = $this->tokenStorage->getToken()->getUser();
\assert($user instanceof User); \assert($user instanceof User);
if ($requestUserId !== $user->getId()) { if ($requestUserId !== $user->getId()) {
throw $this->createAccessDeniedException('Access forbidden. Entry user id: ' . $requestUserId . ', logged user id: ' . $user->getId()); throw $this->createAccessDeniedException('Access forbidden. Entry user id: ' . $requestUserId . ', logged user id: ' . $user->getId());
} }
@ -104,7 +128,7 @@ class WallabagRestController extends AbstractFOSRestController
$context = new SerializationContext(); $context = new SerializationContext();
$context->setSerializeNull(true); $context->setSerializeNull(true);
$json = $this->get(SerializerInterface::class)->serialize($data, 'json', $context); $json = $this->serializer->serialize($data, 'json', $context);
return (new JsonResponse())->setJson($json); return (new JsonResponse())->setJson($json);
} }

View file

@ -17,9 +17,6 @@ class Configuration implements ConfigurationInterface
*/ */
public function getConfigTreeBuilder() public function getConfigTreeBuilder()
{ {
$treeBuilder = new TreeBuilder(); return new TreeBuilder('wallabag_api');
$rootNode = $treeBuilder->root('wallabag_api');
return $treeBuilder;
} }
} }

View file

@ -0,0 +1,44 @@
<?php
namespace Wallabag\ApiBundle\Entity;
use OpenApi\Annotations as OA;
class ApplicationInfo
{
/**
* @var string
* @OA\Property(
* description="Name of the application.",
* type="string",
* example="wallabag",
* )
*/
public $appname;
/**
* @var string
* @OA\Property(
* description="Version number of the application.",
* type="string",
* example="2.5.2",
* )
*/
public $version;
/**
* @var bool
* @OA\Property(
* description="Indicates whether registration is allowed. See PUT /api/user.",
* type="boolean"
* )
*/
public $allowed_registration;
public function __construct($version, $allowed_registration)
{
$this->appname = 'wallabag';
$this->version = $version;
$this->allowed_registration = $allowed_registration;
}
}

Some files were not shown because too many files have changed in this diff Show more