Compare commits

..

363 Commits

Author SHA1 Message Date
b4f1776828 cleanup 2025-10-02 11:56:06 +02:00
5629330cb6 Remove voter & add tests 2025-10-02 11:54:12 +02:00
7e7674a4a6 Add availability to disable an importer 2025-05-26 16:37:13 +02:00
cad5a24fb6 Merge pull request #8199 from wallabag/dependabot/npm_and_yarn/webpack-5.99.9
Bump webpack from 5.99.8 to 5.99.9
2025-05-26 02:33:07 +00:00
2cd1df4722 Bump webpack from 5.99.8 to 5.99.9
Bumps [webpack](https://github.com/webpack/webpack) from 5.99.8 to 5.99.9.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.99.8...v5.99.9)

---
updated-dependencies:
- dependency-name: webpack
  dependency-version: 5.99.9
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-26 02:29:37 +00:00
843d177d80 Merge pull request #8190 from weblate/weblate-wallabag-messages
Translations update from Hosted Weblate
2025-05-24 20:47:57 +02:00
95ff88dae8 Translated using Weblate (Polish)
Currently translated at 100.0% (604 of 604 strings)
2025-05-24 15:28:38 +02:00
34740694fe Merge pull request #8183 from wallabag/dependabot/composer/tecnickcom/tcpdf-6.9.4 2025-05-19 07:09:56 +02:00
1f3c8eeb61 Merge pull request #8181 from wallabag/dependabot/composer/shipmonk/composer-dependency-analyser-1.8.3 2025-05-19 07:09:36 +02:00
d3c448c858 Merge pull request #8180 from wallabag/dependabot/npm_and_yarn/sass-embedded-1.89.0
Bump sass-embedded from 1.88.0 to 1.89.0
2025-05-19 02:31:18 +00:00
f57280a247 Bump tecnickcom/tcpdf from 6.9.3 to 6.9.4
Bumps [tecnickcom/tcpdf](https://github.com/tecnickcom/TCPDF) from 6.9.3 to 6.9.4.
- [Changelog](https://github.com/tecnickcom/TCPDF/blob/main/CHANGELOG.TXT)
- [Commits](https://github.com/tecnickcom/TCPDF/compare/6.9.3...6.9.4)

---
updated-dependencies:
- dependency-name: tecnickcom/tcpdf
  dependency-version: 6.9.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-19 02:28:50 +00:00
366adf0770 Bump shipmonk/composer-dependency-analyser from 1.8.2 to 1.8.3
Bumps [shipmonk/composer-dependency-analyser](https://github.com/shipmonk-rnd/composer-dependency-analyser) from 1.8.2 to 1.8.3.
- [Release notes](https://github.com/shipmonk-rnd/composer-dependency-analyser/releases)
- [Commits](https://github.com/shipmonk-rnd/composer-dependency-analyser/compare/1.8.2...1.8.3)

---
updated-dependencies:
- dependency-name: shipmonk/composer-dependency-analyser
  dependency-version: 1.8.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-19 02:28:14 +00:00
29e43a809d Bump sass-embedded from 1.88.0 to 1.89.0
Bumps [sass-embedded](https://github.com/sass/embedded-host-node) from 1.88.0 to 1.89.0.
- [Changelog](https://github.com/sass/embedded-host-node/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sass/embedded-host-node/compare/1.88.0...1.89.0)

---
updated-dependencies:
- dependency-name: sass-embedded
  dependency-version: 1.89.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-19 02:28:03 +00:00
8c91ff613c Merge pull request #8176 from wallabag/dependabot/github_actions/dependabot/fetch-metadata-2.4.0 2025-05-12 05:40:31 +02:00
33ab6a8b9c Merge pull request #8172 from wallabag/dependabot/composer/doctrine/doctrine-migrations-bundle-3.4.2 2025-05-12 05:40:13 +02:00
2d7f2e84be Bump dependabot/fetch-metadata from 2.3.0 to 2.4.0
Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 2.3.0 to 2.4.0.
- [Release notes](https://github.com/dependabot/fetch-metadata/releases)
- [Commits](https://github.com/dependabot/fetch-metadata/compare/v2.3.0...v2.4.0)

---
updated-dependencies:
- dependency-name: dependabot/fetch-metadata
  dependency-version: 2.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-12 02:57:36 +00:00
0b0724cc95 Merge pull request #8174 from wallabag/dependabot/npm_and_yarn/webpack-5.99.8
Bump webpack from 5.99.7 to 5.99.8
2025-05-12 02:22:49 +00:00
3037c374c1 Merge pull request #8175 from wallabag/dependabot/npm_and_yarn/sass-embedded-1.88.0
Bump sass-embedded from 1.87.0 to 1.88.0
2025-05-12 02:21:14 +00:00
2a70f6c1b5 Bump webpack from 5.99.7 to 5.99.8
Bumps [webpack](https://github.com/webpack/webpack) from 5.99.7 to 5.99.8.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.99.7...v5.99.8)

---
updated-dependencies:
- dependency-name: webpack
  dependency-version: 5.99.8
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-12 02:18:28 +00:00
046cdb978b Merge pull request #8173 from wallabag/dependabot/npm_and_yarn/babel-dependencies-9cfe5952ef
Bump @babel/preset-env from 7.27.1 to 7.27.2 in the babel-dependencies group
2025-05-12 02:16:19 +00:00
dcaf6b0713 Bump sass-embedded from 1.87.0 to 1.88.0
Bumps [sass-embedded](https://github.com/sass/embedded-host-node) from 1.87.0 to 1.88.0.
- [Changelog](https://github.com/sass/embedded-host-node/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sass/embedded-host-node/compare/1.87.0...1.88.0)

---
updated-dependencies:
- dependency-name: sass-embedded
  dependency-version: 1.88.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-12 02:14:04 +00:00
c2d35a35e3 Bump @babel/preset-env in the babel-dependencies group
Bumps the babel-dependencies group with 1 update: [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env).


Updates `@babel/preset-env` from 7.27.1 to 7.27.2
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.27.2/packages/babel-preset-env)

---
updated-dependencies:
- dependency-name: "@babel/preset-env"
  dependency-version: 7.27.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: babel-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-12 02:13:02 +00:00
48bdeb930d Bump doctrine/doctrine-migrations-bundle from 3.4.1 to 3.4.2
Bumps [doctrine/doctrine-migrations-bundle](https://github.com/doctrine/DoctrineMigrationsBundle) from 3.4.1 to 3.4.2.
- [Release notes](https://github.com/doctrine/DoctrineMigrationsBundle/releases)
- [Commits](https://github.com/doctrine/DoctrineMigrationsBundle/compare/3.4.1...3.4.2)

---
updated-dependencies:
- dependency-name: doctrine/doctrine-migrations-bundle
  dependency-version: 3.4.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-12 02:06:54 +00:00
c60d237fb2 Merge pull request #8166 from wallabag/dependabot/composer/symfony-dependencies-1a593181cc 2025-05-05 06:31:39 +02:00
94ccfff72a Merge pull request #8167 from wallabag/dependabot/composer/twig-dependencies-1852d16abb 2025-05-05 06:31:21 +02:00
ab51a65319 Merge pull request #8169 from wallabag/dependabot/composer/j0k3r/graby-site-config-1.0.199 2025-05-05 06:30:38 +02:00
f4b089e679 Merge pull request #8164 from weblate/weblate-wallabag-messages 2025-05-05 06:30:19 +02:00
db21570517 Translated using Weblate (French)
Currently translated at 100.0% (604 of 604 strings)
2025-05-05 05:04:17 +02:00
38a18f644b Merge pull request #8171 from wallabag/dependabot/npm_and_yarn/core-js-3.42.0
Bump core-js from 3.41.0 to 3.42.0
2025-05-05 03:04:09 +00:00
5d3d639d3c Merge pull request #8170 from wallabag/dependabot/npm_and_yarn/babel-dependencies-d1a4844c32
Bump the babel-dependencies group with 3 updates
2025-05-05 03:02:06 +00:00
e6fc4e038a Bump core-js from 3.41.0 to 3.42.0
Bumps [core-js](https://github.com/zloirock/core-js/tree/HEAD/packages/core-js) from 3.41.0 to 3.42.0.
- [Release notes](https://github.com/zloirock/core-js/releases)
- [Changelog](https://github.com/zloirock/core-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/zloirock/core-js/commits/v3.42.0/packages/core-js)

---
updated-dependencies:
- dependency-name: core-js
  dependency-version: 3.42.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-05 02:59:06 +00:00
50853f2ad4 Bump the babel-dependencies group with 3 updates
Bumps the babel-dependencies group with 3 updates: [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core), [@babel/eslint-parser](https://github.com/babel/babel/tree/HEAD/eslint/babel-eslint-parser) and [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env).


Updates `@babel/core` from 7.26.10 to 7.27.1
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.27.1/packages/babel-core)

Updates `@babel/eslint-parser` from 7.27.0 to 7.27.1
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.27.1/eslint/babel-eslint-parser)

Updates `@babel/preset-env` from 7.26.9 to 7.27.1
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.27.1/packages/babel-preset-env)

---
updated-dependencies:
- dependency-name: "@babel/core"
  dependency-version: 7.27.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: babel-dependencies
- dependency-name: "@babel/eslint-parser"
  dependency-version: 7.27.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: babel-dependencies
- dependency-name: "@babel/preset-env"
  dependency-version: 7.27.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: babel-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-05 02:58:42 +00:00
14af4f356d Bump j0k3r/graby-site-config from 1.0.198 to 1.0.199
Bumps [j0k3r/graby-site-config](https://github.com/j0k3r/graby-site-config) from 1.0.198 to 1.0.199.
- [Release notes](https://github.com/j0k3r/graby-site-config/releases)
- [Changelog](https://github.com/j0k3r/graby-site-config/blob/master/dallasnews.com.txt)
- [Commits](https://github.com/j0k3r/graby-site-config/compare/1.0.198...1.0.199)

---
updated-dependencies:
- dependency-name: j0k3r/graby-site-config
  dependency-version: 1.0.199
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-05 02:23:50 +00:00
de630c6050 Bump the twig-dependencies group with 3 updates
Bumps the twig-dependencies group with 3 updates: [twig/extra-bundle](https://github.com/twigphp/twig-extra-bundle), [twig/string-extra](https://github.com/twigphp/string-extra) and [twig/twig](https://github.com/twigphp/Twig).


Updates `twig/extra-bundle` from 3.20.0 to 3.21.0
- [Commits](https://github.com/twigphp/twig-extra-bundle/compare/v3.20.0...v3.21.0)

Updates `twig/string-extra` from 3.20.0 to 3.21.0
- [Commits](https://github.com/twigphp/string-extra/compare/v3.20.0...v3.21.0)

Updates `twig/twig` from 3.20.0 to 3.21.1
- [Changelog](https://github.com/twigphp/Twig/blob/3.x/CHANGELOG)
- [Commits](https://github.com/twigphp/Twig/compare/v3.20.0...v3.21.1)

---
updated-dependencies:
- dependency-name: twig/extra-bundle
  dependency-version: 3.21.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: twig-dependencies
- dependency-name: twig/string-extra
  dependency-version: 3.21.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: twig-dependencies
- dependency-name: twig/twig
  dependency-version: 3.21.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: twig-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-05 02:22:54 +00:00
9559492524 Bump symfony/phpunit-bridge in the symfony-dependencies group
Bumps the symfony-dependencies group with 1 update: [symfony/phpunit-bridge](https://github.com/symfony/phpunit-bridge).


Updates `symfony/phpunit-bridge` from 7.2.0 to 7.2.6
- [Release notes](https://github.com/symfony/phpunit-bridge/releases)
- [Changelog](https://github.com/symfony/phpunit-bridge/blob/7.2/CHANGELOG.md)
- [Commits](https://github.com/symfony/phpunit-bridge/compare/v7.2.0...v7.2.6)

---
updated-dependencies:
- dependency-name: symfony/phpunit-bridge
  dependency-version: 7.2.6
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: symfony-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-05 02:22:42 +00:00
ba1020abd5 Merge pull request #8161 from wallabag/dependabot/npm_and_yarn/sass-embedded-1.87.0
Bump sass-embedded from 1.86.3 to 1.87.0
2025-04-28 02:08:10 +00:00
394ef8f935 Merge pull request #8160 from wallabag/dependabot/npm_and_yarn/webpack-5.99.7
Bump webpack from 5.99.6 to 5.99.7
2025-04-28 02:05:48 +00:00
cb1d340fca Bump sass-embedded from 1.86.3 to 1.87.0
Bumps [sass-embedded](https://github.com/sass/embedded-host-node) from 1.86.3 to 1.87.0.
- [Changelog](https://github.com/sass/embedded-host-node/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sass/embedded-host-node/compare/1.86.3...1.87.0)

---
updated-dependencies:
- dependency-name: sass-embedded
  dependency-version: 1.87.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-28 02:02:38 +00:00
478e10ba4a Bump webpack from 5.99.6 to 5.99.7
Bumps [webpack](https://github.com/webpack/webpack) from 5.99.6 to 5.99.7.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.99.6...v5.99.7)

---
updated-dependencies:
- dependency-name: webpack
  dependency-version: 5.99.7
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-28 02:02:28 +00:00
72a3477a83 Merge pull request #8156 from wallabag/phpstan-level-5
PHPStan level 5
2025-04-22 08:03:58 +02:00
36eb513e1b PHPStan level 5 2025-04-22 07:59:38 +02:00
3ef7064ada Merge pull request #8155 from wallabag/dependabot/npm_and_yarn/webpack-5.99.6
Bump webpack from 5.99.5 to 5.99.6
2025-04-21 08:01:51 +00:00
1f8a30f56d Merge pull request #8151 from wallabag/dependabot/composer/tecnickcom/tcpdf-6.9.3
Bump tecnickcom/tcpdf from 6.9.1 to 6.9.3
2025-04-21 10:01:30 +02:00
a03da9414e Merge pull request #8152 from wallabag/dependabot/composer/ergebnis/composer-normalize-2.47.0
Bump ergebnis/composer-normalize from 2.46.0 to 2.47.0
2025-04-21 10:00:37 +02:00
885e042097 Bump webpack from 5.99.5 to 5.99.6
Bumps [webpack](https://github.com/webpack/webpack) from 5.99.5 to 5.99.6.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.99.5...v5.99.6)

---
updated-dependencies:
- dependency-name: webpack
  dependency-version: 5.99.6
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-21 03:20:53 +00:00
03873e5ac9 Merge pull request #8154 from wallabag/dependabot/npm_and_yarn/symfony/stimulus-bridge-4.0.1
Bump @symfony/stimulus-bridge from 4.0.0 to 4.0.1
2025-04-21 03:19:39 +00:00
1393656e56 Merge pull request #8153 from wallabag/dependabot/npm_and_yarn/eslint-webpack-plugin-5.0.1
Bump eslint-webpack-plugin from 5.0.0 to 5.0.1
2025-04-21 03:16:49 +00:00
16c6f191db Bump @symfony/stimulus-bridge from 4.0.0 to 4.0.1
Bumps @symfony/stimulus-bridge from 4.0.0 to 4.0.1.

---
updated-dependencies:
- dependency-name: "@symfony/stimulus-bridge"
  dependency-version: 4.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-21 03:14:07 +00:00
c554bf7d6d Bump eslint-webpack-plugin from 5.0.0 to 5.0.1
Bumps [eslint-webpack-plugin](https://github.com/webpack-contrib/eslint-webpack-plugin) from 5.0.0 to 5.0.1.
- [Release notes](https://github.com/webpack-contrib/eslint-webpack-plugin/releases)
- [Changelog](https://github.com/webpack-contrib/eslint-webpack-plugin/blob/master/CHANGELOG.md)
- [Commits](https://github.com/webpack-contrib/eslint-webpack-plugin/compare/v5.0.0...v5.0.1)

---
updated-dependencies:
- dependency-name: eslint-webpack-plugin
  dependency-version: 5.0.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-21 03:13:12 +00:00
9fba643094 Bump ergebnis/composer-normalize from 2.46.0 to 2.47.0
Bumps [ergebnis/composer-normalize](https://github.com/ergebnis/composer-normalize) from 2.46.0 to 2.47.0.
- [Release notes](https://github.com/ergebnis/composer-normalize/releases)
- [Changelog](https://github.com/ergebnis/composer-normalize/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ergebnis/composer-normalize/compare/2.46.0...2.47.0)

---
updated-dependencies:
- dependency-name: ergebnis/composer-normalize
  dependency-version: 2.47.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-21 02:49:22 +00:00
dab0bc520b Bump tecnickcom/tcpdf from 6.9.1 to 6.9.3
Bumps [tecnickcom/tcpdf](https://github.com/tecnickcom/TCPDF) from 6.9.1 to 6.9.3.
- [Changelog](https://github.com/tecnickcom/TCPDF/blob/main/CHANGELOG.TXT)
- [Commits](https://github.com/tecnickcom/TCPDF/compare/6.9.1...6.9.3)

---
updated-dependencies:
- dependency-name: tecnickcom/tcpdf
  dependency-version: 6.9.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-21 02:44:59 +00:00
1f89bed117 Merge pull request #8148 from weblate/weblate-wallabag-messages
Translations update from Hosted Weblate
2025-04-17 09:19:23 +02:00
fed449b1e2 Translated using Weblate (Galician)
Currently translated at 100.0% (604 of 604 strings)
2025-04-17 09:13:57 +02:00
fe4474869c Translated using Weblate (Occitan)
Currently translated at 100.0% (35 of 35 strings)
2025-04-17 09:13:57 +02:00
6937241226 Translated using Weblate (Polish)
Currently translated at 100.0% (604 of 604 strings)
2025-04-17 09:13:57 +02:00
00ad4e0a78 Translated using Weblate (Occitan)
Currently translated at 99.1% (599 of 604 strings)
2025-04-17 09:13:57 +02:00
ef00122edc Merge pull request #8149 from wallabag/fix/ci-use-ubuntu-latest
Use `ubuntu-latest` in CI
2025-04-17 09:13:51 +02:00
ae2a867cdd Use ubuntu-latest in CI
`ubuntu-20.04` is now fully deprecated
2025-04-17 09:08:54 +02:00
7ffcd8f7f6 Merge branch '2.6' into master 2025-04-14 21:56:24 +02:00
96dea32650 Merge pull request #8141 from wallabag/impr/title-ellipsis
Replace hardcoded title truncate with CSS text-overflow
2025-04-14 20:44:50 +02:00
70999075a6 Merge pull request #8139 from wallabag/fix/otp-wrongly-enabled
Avoid non-validated OTP to be enabled
2025-04-14 09:46:17 +02:00
262f674245 Avoid non-validated OTP to be enabled
The OTP code must be required when enabling OTP. If the provided code is wrong, disable OTP, redirect and notice the user.
2025-04-14 09:18:37 +02:00
a3ac567c31 Merge pull request #8145 from wallabag/dependabot/composer/ergebnis/composer-normalize-2.46.0 2025-04-14 07:04:17 +02:00
e7668eabd1 Merge pull request #8146 from wallabag/dependabot/npm_and_yarn/webpack-5.99.5
Bump webpack from 5.98.0 to 5.99.5
2025-04-14 02:55:40 +00:00
df12d66564 Bump webpack from 5.98.0 to 5.99.5
Bumps [webpack](https://github.com/webpack/webpack) from 5.98.0 to 5.99.5.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.98.0...v5.99.5)

---
updated-dependencies:
- dependency-name: webpack
  dependency-version: 5.99.5
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-14 02:52:21 +00:00
8b53d3c9c5 Bump ergebnis/composer-normalize from 2.45.0 to 2.46.0
Bumps [ergebnis/composer-normalize](https://github.com/ergebnis/composer-normalize) from 2.45.0 to 2.46.0.
- [Release notes](https://github.com/ergebnis/composer-normalize/releases)
- [Changelog](https://github.com/ergebnis/composer-normalize/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ergebnis/composer-normalize/compare/2.45.0...2.46.0)

---
updated-dependencies:
- dependency-name: ergebnis/composer-normalize
  dependency-version: 2.46.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-14 02:10:45 +00:00
260beeec68 Replace hardcoded title truncate with CSS text-overflow
Signed-off-by: Kevin Decherf <kevin@kdecherf.com>
2025-04-13 15:56:37 +02:00
01ffc6c3d5 Merge pull request #8137 from wallabag/prepare-2.6.12-release
Prepare 2.6.12 release
2025-04-10 11:59:57 +02:00
5586930376 Prepare 2.6.12 release 2025-04-10 11:39:50 +02:00
b45116b73e Merge pull request #8136 from wallabag/update-dependencies
Update dependencies
2025-04-10 11:32:25 +02:00
c2e38cedac Update dependencies 2025-04-10 11:22:33 +02:00
35dcc43366 Merge pull request #8135 from wallabag/fix-changelog
Fix changelog
2025-04-10 11:10:58 +02:00
de8f859536 Fix changelog 2025-04-10 10:59:31 +02:00
e6ce9c524c Merge branch '2.6' 2025-04-10 01:45:52 +02:00
5cdac6c0bb Merge pull request #8133 from wallabag/prepare-2.6.11-release
Prepare 2.6.11 release
2025-04-08 22:42:32 +02:00
466cd17d5b Prepare 2.6.11 release 2025-04-08 21:23:58 +02:00
14cdd123ce Update generated assets 2025-04-08 21:23:58 +02:00
bdb420b13f Use ubuntu latest in all jobs 2025-04-08 21:16:07 +02:00
99c8a06594 Merge commit from fork
Protect actions with a CSRF token
2025-04-08 21:00:14 +02:00
387224f830 Merge pull request #8031 from wallabag/use-stimulus
Use Stimulus
2025-04-07 18:40:31 +02:00
e4fb100163 Remove jQuery 2025-04-07 14:56:06 +02:00
e28e1bddb4 Extract Entries Navigation controller 2025-04-07 14:56:06 +02:00
b266d6ca2f Fix esc shortcut after opening add url or search 2025-04-07 14:56:06 +02:00
8b0e6319e4 Extract Shortcuts controller 2025-04-07 14:56:06 +02:00
7eaaf5d38c Extract Dark Theme controller 2025-04-07 14:56:06 +02:00
a8cb9f4f77 Extract Leftbar and Add Tag controllers 2025-04-07 14:56:06 +02:00
c9cfae11f7 Extract Sticky Nav controller 2025-04-07 14:56:06 +02:00
2054be7bd4 Extract Topbar controller 2025-04-07 14:56:06 +02:00
f7c8466231 Extract Batch Edit controller 2025-04-07 14:56:06 +02:00
e438b5e63f Extract Tag controller 2025-04-07 14:56:06 +02:00
1fd861078d Extract Fake Radio controller 2025-04-07 14:56:06 +02:00
a06da68e72 Extract Config controller 2025-04-07 14:56:06 +02:00
9da9e6b004 Extract Clipboard controller 2025-04-07 14:56:06 +02:00
ffeca7f94d Extract Annotations controller 2025-04-07 14:56:06 +02:00
d515e11fe4 Extract Scroll Storage controller 2025-04-07 14:56:06 +02:00
019d252446 Extract Scroll Indicator controller 2025-04-07 14:56:06 +02:00
503b82ea13 Extract Highlight controller 2025-04-07 14:56:06 +02:00
3125eb43ad Extract QRCode controller 2025-04-07 14:56:06 +02:00
e5042074a2 Extract Materialize Toast controller 2025-04-07 14:56:06 +02:00
76c101938d Extract Materialize FAB controller 2025-04-07 14:56:06 +02:00
a7a4c5fefb Extract Materialize Form Select controller 2025-04-07 14:56:06 +02:00
1b683dbb05 Extract Materialize Dropdown controller 2025-04-07 14:56:06 +02:00
a69ea46945 Extract Materialize Collapsible controller 2025-04-07 14:56:06 +02:00
2a2172037e Extract Materialize Tooltip controller 2025-04-07 14:56:06 +02:00
0589066ed1 Extract Materialize Tabs controller 2025-04-07 14:56:06 +02:00
1f76184d02 Extract Materialize Sidenav controller 2025-04-07 14:56:06 +02:00
66c6a25941 Install Stimulus 2025-04-07 14:56:06 +02:00
46f505f69f Merge pull request #8124 from wallabag/phpstan-level-4
PHPStan level 4
2025-04-07 14:20:14 +02:00
b4483023e6 Move to PHPStan level 4 2025-04-07 12:20:06 +02:00
31e1be4191 Add phpstan-baseline target in Makefile 2025-04-07 11:42:05 +02:00
63dc69d70f Merge pull request #8122 from wallabag/modernize-code-base-with-rector
Modernize code base with Rector
2025-04-07 10:03:12 +02:00
4e177e1778 Migrate to SensioLabs attributes 2025-04-07 09:17:32 +02:00
a766826a69 Migrate to JMS attributes 2025-04-07 09:17:32 +02:00
a1440dffda Migrate to Gedmo attributes 2025-04-07 09:17:32 +02:00
2a60d8473d Migrate to Symfony attributes 2025-04-07 09:17:32 +02:00
6a3780ce81 Add root files to Rector configuration 2025-04-07 09:17:32 +02:00
42a63be61a Modernize to app min PHP version 2025-04-07 09:17:32 +02:00
9e2720cddc Modernize to PHP 8.1 2025-04-07 09:17:32 +02:00
ca018c77e3 Migrate to readonly properties 2025-04-07 09:17:32 +02:00
a107773c11 Modernize to PHP 8.0 2025-04-07 09:17:32 +02:00
1d5674a230 Migrate to constructor promoted properties 2025-04-07 09:17:32 +02:00
4168727f36 Modernize to PHP 7.4 2025-04-07 09:17:31 +02:00
ce8ed589d5 Modernize to PHP 7.3 2025-04-07 09:17:31 +02:00
f8c8bb7d93 Modernize to PHP 7.1 2025-04-07 09:17:31 +02:00
241cddc899 Modernize to PHP 7.0 2025-04-07 09:17:31 +02:00
745fef44f4 Modernize to PHP 5.5 2025-04-07 09:17:31 +02:00
99a49bfc96 Add Doctrine attributes set 2025-04-07 09:17:31 +02:00
84eb99c59b Initial Rector fixes with basic configuration 2025-04-07 09:17:31 +02:00
a679117736 Install rector 2025-04-07 09:17:31 +02:00
eadb6838c0 Merge pull request #8126 from wallabag/dependabot/npm_and_yarn/sass-embedded-1.86.3
Bump sass-embedded from 1.86.0 to 1.86.3
2025-04-07 04:39:25 +00:00
5fca2db1e5 Merge pull request #8127 from wallabag/dependabot/composer/jms/serializer-3.32.4 2025-04-07 06:35:34 +02:00
b56d3fef87 Merge pull request #8128 from wallabag/dependabot/composer/j0k3r/graby-site-config-1.0.198 2025-04-07 06:35:08 +02:00
4b652b416c Merge pull request #8129 from wallabag/dependabot/composer/tecnickcom/tcpdf-6.9.1 2025-04-07 06:34:51 +02:00
528650b525 Merge pull request #8131 from wallabag/dependabot/composer/guzzlehttp/psr7-2.7.1 2025-04-07 06:34:22 +02:00
5597f527d5 Merge pull request #8132 from wallabag/dependabot/composer/friendsofphp/php-cs-fixer-3.75.0 2025-04-07 06:34:05 +02:00
c79d4449bd Bump friendsofphp/php-cs-fixer from 3.74.0 to 3.75.0
Bumps [friendsofphp/php-cs-fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer) from 3.74.0 to 3.75.0.
- [Release notes](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/releases)
- [Changelog](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/compare/v3.74.0...v3.75.0)

---
updated-dependencies:
- dependency-name: friendsofphp/php-cs-fixer
  dependency-version: 3.75.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-07 03:01:31 +00:00
07d888a71e Bump guzzlehttp/psr7 from 2.7.0 to 2.7.1
Bumps [guzzlehttp/psr7](https://github.com/guzzle/psr7) from 2.7.0 to 2.7.1.
- [Release notes](https://github.com/guzzle/psr7/releases)
- [Changelog](https://github.com/guzzle/psr7/blob/2.7/CHANGELOG.md)
- [Commits](https://github.com/guzzle/psr7/compare/2.7.0...2.7.1)

---
updated-dependencies:
- dependency-name: guzzlehttp/psr7
  dependency-version: 2.7.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-07 03:01:18 +00:00
10e80a7b9a Bump tecnickcom/tcpdf from 6.8.2 to 6.9.1
Bumps [tecnickcom/tcpdf](https://github.com/tecnickcom/TCPDF) from 6.8.2 to 6.9.1.
- [Changelog](https://github.com/tecnickcom/TCPDF/blob/main/CHANGELOG.TXT)
- [Commits](https://github.com/tecnickcom/TCPDF/compare/6.8.2...6.9.1)

---
updated-dependencies:
- dependency-name: tecnickcom/tcpdf
  dependency-version: 6.9.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-07 03:00:55 +00:00
967ac9f9ac Bump j0k3r/graby-site-config from 1.0.197 to 1.0.198
Bumps [j0k3r/graby-site-config](https://github.com/j0k3r/graby-site-config) from 1.0.197 to 1.0.198.
- [Release notes](https://github.com/j0k3r/graby-site-config/releases)
- [Changelog](https://github.com/j0k3r/graby-site-config/blob/master/dallasnews.com.txt)
- [Commits](https://github.com/j0k3r/graby-site-config/compare/1.0.197...1.0.198)

---
updated-dependencies:
- dependency-name: j0k3r/graby-site-config
  dependency-version: 1.0.198
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-07 03:00:49 +00:00
be9b1ef60a Bump jms/serializer from 3.32.3 to 3.32.4
Bumps [jms/serializer](https://github.com/schmittjoh/serializer) from 3.32.3 to 3.32.4.
- [Release notes](https://github.com/schmittjoh/serializer/releases)
- [Changelog](https://github.com/schmittjoh/serializer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/schmittjoh/serializer/compare/3.32.3...3.32.4)

---
updated-dependencies:
- dependency-name: jms/serializer
  dependency-version: 3.32.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-07 02:59:59 +00:00
d29e757a09 Bump sass-embedded from 1.86.0 to 1.86.3
Bumps [sass-embedded](https://github.com/sass/embedded-host-node) from 1.86.0 to 1.86.3.
- [Changelog](https://github.com/sass/embedded-host-node/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sass/embedded-host-node/compare/1.86.0...1.86.3)

---
updated-dependencies:
- dependency-name: sass-embedded
  dependency-version: 1.86.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-07 02:24:26 +00:00
8a15feb730 Merge pull request #8119 from wallabag/remove-deprecated-scheb-2fa-qr-code-package
Remove deprecated scheb/2fa-qr-code package
2025-04-05 18:16:48 +02:00
d4fbb80dd5 Merge pull request #8121 from wallabag/clean-phpstan-baseline
Clean PHPStan baseline
2025-04-05 18:11:11 +02:00
27a93cc281 Merge pull request #8120 from wallabag/migrate-to-doctrine-attributes
Migrate to Doctrine attributes
2025-04-05 18:09:31 +02:00
e63d473032 Clean PHPStan baseline 2025-04-05 16:19:38 +02:00
41767e8fbc Migrate to Doctrine attributes 2025-04-05 12:59:51 +02:00
c0bb737200 Remove deprecated scheb/2fa-qr-code package 2025-04-05 11:49:08 +02:00
0d93add058 Merge pull request #8117 from wallabag/fix-some-depreciation-notices
Fix some depreciation notices
2025-04-02 21:15:50 +02:00
3f2f57e0c0 Fix some other deprecation notices 2025-04-02 02:13:45 +02:00
412352ff03 Fix direct deprecation notices 2025-04-02 02:13:45 +02:00
4ab26a1902 Fix self deprecation notices 2025-04-02 02:13:45 +02:00
a7f7022229 Replace getQuotedTableName by using DefaultQuoteStrategy 2025-04-02 02:13:45 +02:00
95730754e8 Replace property access by getters 2025-04-02 02:08:55 +02:00
402d80cd30 Replace LifecycleEventArgs by PreRemoveEventArgs 2025-04-02 02:08:55 +02:00
c9301bd0b3 Use built in FOSUserBundle mailer 2025-04-02 02:08:55 +02:00
47d3bd4b69 Replace MASTER_REQUEST by MAIN_REQUEST 2025-04-02 02:08:55 +02:00
f7f5c714ac Replace get by constructor injection 2025-04-02 02:08:55 +02:00
069c09d8d9 Replace query by executeQuery 2025-04-02 02:08:55 +02:00
1127b147c0 Replace AuthenticationEvents::AUTHENTICATION_FAILURE by LoginFailureEvent 2025-04-02 02:08:55 +02:00
c50265c1eb Replace setMethods by onlyMethods 2025-04-02 02:08:55 +02:00
f3e88ec461 Merge pull request #8054 from wallabag/dependabot/npm_and_yarn/eslint-webpack-plugin-5.0.0
Bump eslint-webpack-plugin from 4.2.0 to 5.0.0
2025-04-01 00:18:51 +02:00
5809afd256 Bump eslint-webpack-plugin from 4.2.0 to 5.0.0
Bumps [eslint-webpack-plugin](https://github.com/webpack-contrib/eslint-webpack-plugin) from 4.2.0 to 5.0.0.
- [Release notes](https://github.com/webpack-contrib/eslint-webpack-plugin/releases)
- [Changelog](https://github.com/webpack-contrib/eslint-webpack-plugin/blob/master/CHANGELOG.md)
- [Commits](https://github.com/webpack-contrib/eslint-webpack-plugin/compare/v4.2.0...v5.0.0)

---
updated-dependencies:
- dependency-name: eslint-webpack-plugin
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-31 22:14:59 +00:00
2f9d95c2dd Merge pull request #8086 from wallabag/dependabot/composer/friendsofsymfony/jsrouting-bundle-3.5.2
Bump friendsofsymfony/jsrouting-bundle from 2.8.0 to 3.5.2
2025-04-01 00:12:16 +02:00
c860f4db6a Bump friendsofsymfony/jsrouting-bundle from 2.8.0 to 3.5.2
Bumps [friendsofsymfony/jsrouting-bundle](https://github.com/FriendsOfSymfony/FOSJsRoutingBundle) from 2.8.0 to 3.5.2.
- [Release notes](https://github.com/FriendsOfSymfony/FOSJsRoutingBundle/releases)
- [Changelog](https://github.com/FriendsOfSymfony/FOSJsRoutingBundle/blob/master/CHANGELOG.md)
- [Commits](https://github.com/FriendsOfSymfony/FOSJsRoutingBundle/compare/2.8.0...3.5.2)

---
updated-dependencies:
- dependency-name: friendsofsymfony/jsrouting-bundle
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-01 00:08:10 +02:00
ae8d7e2e37 Merge pull request #8084 from wallabag/dependabot/composer/doctrine/data-fixtures-2.0.2
Bump doctrine/data-fixtures from 1.8.1 to 2.0.2
2025-03-31 23:50:12 +02:00
67bd937619 Bump doctrine/data-fixtures from 1.8.1 to 2.0.2
Bumps [doctrine/data-fixtures](https://github.com/doctrine/data-fixtures) from 1.8.1 to 2.0.2.
- [Release notes](https://github.com/doctrine/data-fixtures/releases)
- [Upgrade guide](https://github.com/doctrine/data-fixtures/blob/2.0.x/UPGRADE.md)
- [Commits](https://github.com/doctrine/data-fixtures/compare/1.8.1...2.0.2)

---
updated-dependencies:
- dependency-name: doctrine/data-fixtures
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-31 23:46:13 +02:00
82e49ead7d Merge pull request #8106 from wallabag/dependabot/composer/doctrine/collections-2.3.0
Bump doctrine/collections from 1.8.0 to 2.3.0
2025-03-31 23:39:32 +02:00
a72f7930c4 Bump doctrine/collections from 1.8.0 to 2.3.0
Bumps [doctrine/collections](https://github.com/doctrine/collections) from 1.8.0 to 2.3.0.
- [Release notes](https://github.com/doctrine/collections/releases)
- [Upgrade guide](https://github.com/doctrine/collections/blob/2.3.x/UPGRADE.md)
- [Commits](https://github.com/doctrine/collections/compare/1.8.0...2.3.0)

---
updated-dependencies:
- dependency-name: doctrine/collections
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-31 21:30:46 +00:00
c75e4cf63a Merge pull request #8104 from wallabag/dependabot/composer/egulias/email-validator-4.0.4
Bump egulias/email-validator from 3.2.6 to 4.0.4
2025-03-31 23:29:38 +02:00
a9f9c9d513 Bump egulias/email-validator from 3.2.6 to 4.0.4
Bumps [egulias/email-validator](https://github.com/egulias/EmailValidator) from 3.2.6 to 4.0.4.
- [Release notes](https://github.com/egulias/EmailValidator/releases)
- [Commits](https://github.com/egulias/EmailValidator/compare/3.2.6...4.0.4)

---
updated-dependencies:
- dependency-name: egulias/email-validator
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-31 21:16:04 +00:00
08d2233882 Merge pull request #8082 from wallabag/dependabot/composer/pagerfanta/doctrine-orm-adapter-4.7.1
Bump pagerfanta/doctrine-orm-adapter from 3.8.0 to 4.7.1
2025-03-31 23:14:23 +02:00
2344a23be2 Bump pagerfanta/doctrine-orm-adapter from 3.8.0 to 4.7.1
Bumps [pagerfanta/doctrine-orm-adapter](https://github.com/Pagerfanta/doctrine-orm-adapter) from 3.8.0 to 4.7.1.
- [Commits](https://github.com/Pagerfanta/doctrine-orm-adapter/compare/v3.8.0...v4.7.1)

---
updated-dependencies:
- dependency-name: pagerfanta/doctrine-orm-adapter
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-31 21:04:24 +00:00
6e54f0d0ab Merge pull request #8081 from wallabag/dependabot/composer/pagerfanta/twig-4.7.1
Bump pagerfanta/twig from 3.8.0 to 4.7.1
2025-03-31 23:03:23 +02:00
d6e27feac0 Bump pagerfanta/twig from 3.8.0 to 4.7.1
Bumps [pagerfanta/twig](https://github.com/Pagerfanta/twig) from 3.8.0 to 4.7.1.
- [Commits](https://github.com/Pagerfanta/twig/compare/v3.8.0...v4.7.1)

---
updated-dependencies:
- dependency-name: pagerfanta/twig
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-31 20:49:17 +00:00
1382af1a5d Merge pull request #8085 from wallabag/dependabot/composer/babdev/pagerfanta-bundle-4.5.0
Bump babdev/pagerfanta-bundle from 3.8.0 to 4.5.0
2025-03-31 22:48:20 +02:00
04f29e4a6b Bump babdev/pagerfanta-bundle from 3.8.0 to 4.5.0
Bumps [babdev/pagerfanta-bundle](https://github.com/BabDev/PagerfantaBundle) from 3.8.0 to 4.5.0.
- [Changelog](https://github.com/BabDev/PagerfantaBundle/blob/4.x/CHANGELOG.md)
- [Commits](https://github.com/BabDev/PagerfantaBundle/compare/v3.8.0...v4.5.0)

---
updated-dependencies:
- dependency-name: babdev/pagerfanta-bundle
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-31 20:25:23 +00:00
8ac2e699e0 Merge pull request #8080 from wallabag/dependabot/composer/scssphp/scssphp-2.0.1
Bump scssphp/scssphp from 1.13.0 to 2.0.1
2025-03-31 22:23:37 +02:00
0d9cbcdfcf Merge pull request #8112 from weblate/weblate-wallabag-messages
Translations update from Hosted Weblate
2025-03-31 05:04:28 +02:00
bff0853021 Translated using Weblate (Norwegian Bokmål)
Currently translated at 99.1% (598 of 603 strings)
2025-03-31 04:58:53 +02:00
23565c0784 Merge pull request #8116 from wallabag/dependabot/npm_and_yarn/babel-dependencies-03e2e86deb
Bump @babel/eslint-parser from 7.26.10 to 7.27.0 in the babel-dependencies group
2025-03-31 02:58:49 +00:00
b7648f575e Merge pull request #8115 from wallabag/dependabot/composer/doctrine/migrations-3.9.0
Bump doctrine/migrations from 3.8.3 to 3.9.0
2025-03-31 04:56:50 +02:00
622ab8cf96 Bump @babel/eslint-parser in the babel-dependencies group
Bumps the babel-dependencies group with 1 update: [@babel/eslint-parser](https://github.com/babel/babel/tree/HEAD/eslint/babel-eslint-parser).


Updates `@babel/eslint-parser` from 7.26.10 to 7.27.0
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.27.0/eslint/babel-eslint-parser)

---
updated-dependencies:
- dependency-name: "@babel/eslint-parser"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: babel-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-31 02:53:59 +00:00
7a407160c1 Bump doctrine/migrations from 3.8.3 to 3.9.0
Bumps [doctrine/migrations](https://github.com/doctrine/migrations) from 3.8.3 to 3.9.0.
- [Release notes](https://github.com/doctrine/migrations/releases)
- [Commits](https://github.com/doctrine/migrations/compare/3.8.3...3.9.0)

---
updated-dependencies:
- dependency-name: doctrine/migrations
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-31 02:50:51 +00:00
985e81e017 Merge pull request #8114 from wallabag/dependabot/composer/friendsofphp/php-cs-fixer-3.74.0
Bump friendsofphp/php-cs-fixer from 3.73.1 to 3.74.0
2025-03-31 04:47:58 +02:00
5bf34d3c72 Bump friendsofphp/php-cs-fixer from 3.73.1 to 3.74.0
Bumps [friendsofphp/php-cs-fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer) from 3.73.1 to 3.74.0.
- [Release notes](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/releases)
- [Changelog](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/compare/v3.73.1...v3.74.0)

---
updated-dependencies:
- dependency-name: friendsofphp/php-cs-fixer
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-31 02:09:23 +00:00
4c52f71895 Add SameSite=lax to session cookie 2025-03-30 06:18:32 +02:00
677b2986bc Use 400 Bad Request errors for invalid CSRF everywhere 2025-03-30 06:18:32 +02:00
5ea5115a72 Protect mass_action with a CSRF token 2025-03-30 06:18:32 +02:00
27f0d94db7 Protect tag_delete with a CSRF token 2025-03-30 06:18:32 +02:00
cf49be6940 Protect tag_this_search with a CSRF token 2025-03-30 06:18:32 +02:00
ddf2e80842 Protect remove_tag with a CSRF token 2025-03-30 06:18:32 +02:00
d1e128900a Protect delete_share with a CSRF token 2025-03-30 06:18:32 +02:00
0d8429dfc7 Protect share with a CSRF token 2025-03-30 06:18:32 +02:00
eb8408b22f Protect delete_entry with a CSRF token 2025-03-30 06:18:32 +02:00
00d0e6f951 Protect star_entry with a CSRF token 2025-03-30 06:18:32 +02:00
edffef8375 Protect archive_entry with a CSRF token 2025-03-30 06:18:32 +02:00
3817010e29 Protect reload_entry with a CSRF token 2025-03-30 06:18:32 +02:00
ed1acf59e1 Protect changeLocale with a CSRF token 2025-03-30 06:18:29 +02:00
56ce98fb9a Merge pull request #8103 from weblate/weblate-wallabag-messages
Translations update from Hosted Weblate
2025-03-24 09:28:36 +01:00
d5aa680054 Translated using Weblate (Tamil)
Currently translated at 100.0% (6 of 6 strings)
2025-03-24 07:06:57 +01:00
6c183081df Merge pull request #8105 from wallabag/dependabot/composer/friendsofphp/php-cs-fixer-3.73.1 2025-03-24 07:06:52 +01:00
d965c25304 Merge pull request #8107 from wallabag/dependabot/composer/doctrine/migrations-3.8.3 2025-03-24 07:06:09 +01:00
8fade1416b Merge pull request #8108 from wallabag/dependabot/npm_and_yarn/sass-embedded-1.86.0
Bump sass-embedded from 1.85.1 to 1.86.0
2025-03-24 03:26:47 +00:00
4d7fdc00db Bump sass-embedded from 1.85.1 to 1.86.0
Bumps [sass-embedded](https://github.com/sass/embedded-host-node) from 1.85.1 to 1.86.0.
- [Changelog](https://github.com/sass/embedded-host-node/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sass/embedded-host-node/compare/1.85.1...1.86.0)

---
updated-dependencies:
- dependency-name: sass-embedded
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-24 03:23:22 +00:00
a60f8599d8 Bump doctrine/migrations from 3.8.2 to 3.8.3
Bumps [doctrine/migrations](https://github.com/doctrine/migrations) from 3.8.2 to 3.8.3.
- [Release notes](https://github.com/doctrine/migrations/releases)
- [Commits](https://github.com/doctrine/migrations/compare/3.8.2...3.8.3)

---
updated-dependencies:
- dependency-name: doctrine/migrations
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-24 03:11:48 +00:00
3a44ed7943 Bump friendsofphp/php-cs-fixer from 3.72.0 to 3.73.1
Bumps [friendsofphp/php-cs-fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer) from 3.72.0 to 3.73.1.
- [Release notes](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/releases)
- [Changelog](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/compare/v3.72.0...v3.73.1)

---
updated-dependencies:
- dependency-name: friendsofphp/php-cs-fixer
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-24 03:10:43 +00:00
e162408139 Protect switch_view_mode with a CSRF token 2025-03-23 19:13:21 +01:00
6fa61c0f9c Protect delete_ignore_origin_rule with a CSRF token 2025-03-23 19:13:17 +01:00
264f91126e Protect delete_tagging_rule with a CSRF token 2025-03-23 19:13:14 +01:00
ac5b5fb379 Protect revoke_token with a CSRF token 2025-03-23 19:13:09 +01:00
d703fa6a3a Protect generate_token with a CSRF token 2025-03-23 19:13:06 +01:00
2382140a12 Merge pull request #8101 from weblate/weblate-wallabag-messages
Translations update from Hosted Weblate
2025-03-19 11:24:41 +01:00
7ba55697b9 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 97.0% (585 of 603 strings)
2025-03-19 11:07:24 +01:00
2272d3da66 Merge branch '2.6'
# Conflicts:
#	src/Repository/EntryRepository.php
#	src/Twig/WallabagExtension.php
#	src/Wallabag/CoreBundle/Resources/views/Entry/_card_actions.html.twig
#	src/Wallabag/CoreBundle/Resources/views/Entry/_card_list.html.twig
#	tests/Twig/WallabagExtensionTest.php
2025-03-18 21:02:22 +01:00
7e9e179860 Merge pull request #8098 from wallabag/add-isgranted-to-entryrestcontroller
Add IsGranted to EntryRestController
2025-03-18 12:34:57 +01:00
31ba90b060 Merge pull request #8099 from wallabag/no-class-level-route-annotations
No class level route annotations
2025-03-18 06:27:29 +01:00
c20f37975b No class level route annotations 2025-03-18 01:22:55 +01:00
ecb8b8ff49 Add IsGranted to EntryRestController 2025-03-18 00:15:34 +01:00
67c359a6dd Replace entity manager clear by creating a new client 2025-03-18 00:03:35 +01:00
1393f78005 Merge pull request #8030 from wallabag/back-end-hide-show-of-export-and-filters
Back-end hide/show of random, export and filters
2025-03-17 22:41:01 +01:00
63cf403eaf Initialize filters and export sidenav with common ones 2025-03-17 13:54:33 +01:00
1e61a51e82 Use native form reset for filters 2025-03-17 13:54:33 +01:00
0330d01a49 Back-end hide/show of random, export and filters actions 2025-03-17 13:54:33 +01:00
595f35a1a5 Merge pull request #8093 from wallabag/add-isgranted-to-tagcontroller
Add IsGranted to TagController
2025-03-17 12:47:43 +01:00
943bfd9162 Add IsGranted to TagController 2025-03-17 10:47:57 +01:00
4a1598165f Merge pull request #8095 from wallabag/add-isgranted-to-staticcontroller
Add IsGranted to StaticController
2025-03-17 09:45:18 +01:00
fb11f5870e Merge pull request #8094 from wallabag/add-isgranted-to-configcontroller
Add IsGranted to ConfigController
2025-03-17 09:34:25 +01:00
4b4e021a04 Merge pull request #8074 from wallabag/add-isgranted-to-feedcontroller
Add IsGranted to FeedController
2025-03-17 09:33:49 +01:00
440d2d7c76 Merge pull request #8097 from wallabag/fix-display-thumbnails-checkbox
Fix display thumbnails checkbox
2025-03-17 09:33:23 +01:00
86e15954c5 Merge pull request #8092 from wallabag/add-isgranted-to-searchrestcontroller
Add IsGranted to SearchRestController
2025-03-17 09:22:32 +01:00
9a55f17b42 Merge pull request #8096 from wallabag/fix-tests-namespaces
Fix tests namespaces
2025-03-17 08:47:11 +01:00
7ae25f3cc6 Fix display thumbnails checkbox 2025-03-16 22:25:40 +01:00
787a812f8e Fix tests namespaces 2025-03-16 22:13:12 +01:00
c540bff62b Add IsGranted to StaticController 2025-03-16 22:09:26 +01:00
f3da3a42e8 Add IsGranted to ConfigController 2025-03-16 21:20:34 +01:00
f501c6206e Add IsGranted to SearchRestController 2025-03-14 22:33:59 +01:00
0aedbd7fd7 Add IsGranted to FeedController 2025-03-14 22:30:43 +01:00
f042e7e178 Merge pull request #8091 from wallabag/add-isgranted-to-import-controllers
Add IsGranted to import controllers
2025-03-14 22:29:31 +01:00
b39b361440 Merge pull request #8090 from wallabag/add-isgranted-to-annotationrestcontroller
Add IsGranted to AnnotationRestController
2025-03-14 22:28:11 +01:00
9499b062d0 Add IsGranted to import controllers 2025-03-14 22:24:31 +01:00
f9676270f2 Add IsGranted to AnnotationRestController 2025-03-14 22:00:13 +01:00
e3dc63f739 Merge pull request #8076 from wallabag/add-isgranted-to-exportcontroller
Add IsGranted to ExportController
2025-03-14 10:01:19 +01:00
d2dd7f78d3 Add IsGranted to ExportController 2025-03-14 09:51:17 +01:00
deae27bdae Merge pull request #8073 from wallabag/add-isgranted-to-annotationcontroller
Add IsGranted to AnnotationController
2025-03-14 09:49:23 +01:00
61e2cb37df Add IsGranted to AnnotationController 2025-03-14 09:30:34 +01:00
b9900c311d Merge pull request #8088 from wallabag/dependabot/npm_and_yarn/webpack-manifest-plugin-5.0.1
Bump webpack-manifest-plugin from 5.0.0 to 5.0.1
2025-03-14 09:07:58 +01:00
1afe48e732 Merge pull request #8075 from wallabag/convert-403-errors-to-404-errors
[BC BREAK] Convert 403 errors to 404 errors
2025-03-14 08:59:14 +01:00
198f0a64d0 Merge pull request #8083 from wallabag/dependabot/npm_and_yarn/babel-dependencies-cb0d452a55
Bump the babel-dependencies group with 2 updates
2025-03-14 08:58:14 +01:00
41fe283a94 Bump webpack-manifest-plugin from 5.0.0 to 5.0.1
Bumps [webpack-manifest-plugin](https://github.com/shellscape/webpack-manifest-plugin) from 5.0.0 to 5.0.1.
- [Release notes](https://github.com/shellscape/webpack-manifest-plugin/releases)
- [Commits](https://github.com/shellscape/webpack-manifest-plugin/compare/v5.0.0...v5.0.1)

---
updated-dependencies:
- dependency-name: webpack-manifest-plugin
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-14 07:48:57 +00:00
1f0d4723c6 Bump the babel-dependencies group with 2 updates
Bumps the babel-dependencies group with 2 updates: [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) and [@babel/eslint-parser](https://github.com/babel/babel/tree/HEAD/eslint/babel-eslint-parser).


Updates `@babel/core` from 7.26.9 to 7.26.10
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.26.10/packages/babel-core)

Updates `@babel/eslint-parser` from 7.26.8 to 7.26.10
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.26.10/eslint/babel-eslint-parser)

---
updated-dependencies:
- dependency-name: "@babel/core"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: babel-dependencies
- dependency-name: "@babel/eslint-parser"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: babel-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-14 07:48:11 +00:00
bc9bdc72f3 Bump scssphp/scssphp from 1.13.0 to 2.0.1
Bumps [scssphp/scssphp](https://github.com/scssphp/scssphp) from 1.13.0 to 2.0.1.
- [Release notes](https://github.com/scssphp/scssphp/releases)
- [Commits](https://github.com/scssphp/scssphp/compare/v1.13.0...v2.0.1)

---
updated-dependencies:
- dependency-name: scssphp/scssphp
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-14 07:47:31 +00:00
7bebe5fd4b Merge pull request #8079 from wallabag/update-dependabot-configuration
Update Dependabot configuration
2025-03-14 08:46:27 +01:00
3bd434091f Convert 403 errors to 404 errors 2025-03-14 06:41:28 +01:00
1acbc91484 Better Symfony ignore rule 2025-03-14 06:08:13 +01:00
b05fb21f2b Remove now invalid ignore rule for lcobucci/jwt 2025-03-14 06:01:52 +01:00
b61611ffd4 Make composer dependency check weekly instead of daily 2025-03-14 06:01:09 +01:00
1447c183a4 Merge pull request #8062 from wallabag/remove-rulerz-php-doctrine-orm
Remove rulerz-php/doctrine-orm
2025-03-14 05:46:17 +01:00
ed2ad4776b Remove rulerz-php/doctrine-orm 2025-03-14 05:40:15 +01:00
8542edc4f1 Merge pull request #8078 from wallabag/dependabot/composer/friendsofphp/php-cs-fixer-3.72.0
Bump friendsofphp/php-cs-fixer from 3.71.0 to 3.72.0
2025-03-14 05:27:04 +01:00
d5126c8a0e Bump friendsofphp/php-cs-fixer from 3.71.0 to 3.72.0
Bumps [friendsofphp/php-cs-fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer) from 3.71.0 to 3.72.0.
- [Release notes](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/releases)
- [Changelog](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/compare/v3.71.0...v3.72.0)

---
updated-dependencies:
- dependency-name: friendsofphp/php-cs-fixer
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-14 04:20:53 +00:00
939e8cf8df Merge pull request #8063 from wallabag/drop-php-7.4-8.0-and-8.1
Drop PHP 7.4, 8.0 and 8.1
2025-03-14 05:19:50 +01:00
991f11cdf2 Remove legacy PHP-CS-Fixer rule configuration 2025-03-13 01:42:02 +01:00
4fa015bddf Bump dependencies 2025-03-13 01:42:02 +01:00
39c71dfdbf Update dependencies 2025-03-13 01:42:02 +01:00
3b68d3ff62 Fix migration 2025-03-13 01:42:02 +01:00
27d07be2b7 Avoid installation of PHP polyfills 2025-03-13 01:42:02 +01:00
206a04bc05 Remove PHP polyfills 2025-03-13 01:42:02 +01:00
78ab273dab Remove PHP platform overrides 2025-03-13 01:42:02 +01:00
530bc71924 Drop PHP 7.4 and 8.0 2025-03-13 01:42:02 +01:00
d082def664 Upgrade PHP Docker base image to 8.2 2025-03-13 01:42:02 +01:00
a4a6eb580b Merge pull request #8066 from wallabag/add-methods-to-all-controllers
Add methods to all controllers
2025-03-10 09:12:26 +01:00
e4249b9ff2 Merge pull request #8067 from wallabag/dependabot/composer/friendsofphp/php-cs-fixer-3.71.0 2025-03-10 06:19:17 +01:00
39694f78b1 Merge pull request #8069 from wallabag/dependabot/npm_and_yarn/autoprefixer-10.4.21
Bump autoprefixer from 10.4.20 to 10.4.21
2025-03-10 03:35:39 +00:00
0ec9b74a98 Merge pull request #8068 from wallabag/dependabot/npm_and_yarn/terser-webpack-plugin-5.3.14
Bump terser-webpack-plugin from 5.3.12 to 5.3.14
2025-03-10 03:32:39 +00:00
9b9fa600bc Bump autoprefixer from 10.4.20 to 10.4.21
Bumps [autoprefixer](https://github.com/postcss/autoprefixer) from 10.4.20 to 10.4.21.
- [Release notes](https://github.com/postcss/autoprefixer/releases)
- [Changelog](https://github.com/postcss/autoprefixer/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/autoprefixer/compare/10.4.20...10.4.21)

---
updated-dependencies:
- dependency-name: autoprefixer
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-10 03:26:54 +00:00
ae2b72b5d2 Bump terser-webpack-plugin from 5.3.12 to 5.3.14
Bumps [terser-webpack-plugin](https://github.com/webpack-contrib/terser-webpack-plugin) from 5.3.12 to 5.3.14.
- [Release notes](https://github.com/webpack-contrib/terser-webpack-plugin/releases)
- [Changelog](https://github.com/webpack-contrib/terser-webpack-plugin/blob/master/CHANGELOG.md)
- [Commits](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v5.3.12...v5.3.14)

---
updated-dependencies:
- dependency-name: terser-webpack-plugin
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-10 03:26:41 +00:00
b8ae88b807 Bump friendsofphp/php-cs-fixer from 3.70.2 to 3.71.0
Bumps [friendsofphp/php-cs-fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer) from 3.70.2 to 3.71.0.
- [Release notes](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/releases)
- [Changelog](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/compare/v3.70.2...v3.71.0)

---
updated-dependencies:
- dependency-name: friendsofphp/php-cs-fixer
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-10 03:12:11 +00:00
24784768f5 Add methods to all controllers 2025-03-10 01:37:14 +01:00
a71b78531d Merge pull request #8064 from wallabag/fix-default-domain_name-to-avoid-cross-origin-issues
Fix default DOMAIN_NAME to avoid Cross-Origin issues
2025-03-08 09:49:37 +01:00
d988919448 Fix default DOMAIN_NAME to avoid Cross-Origin issues 2025-03-07 23:58:54 +01:00
a7130bd61a Merge pull request #8033 from wallabag/dependabot/composer/j0k3r/graby-2.4.6
Bump j0k3r/graby from 2.4.5 to 2.4.6
2025-03-04 11:11:49 +01:00
bfd23cdc14 Bump j0k3r/graby from 2.4.5 to 2.4.6
Bumps [j0k3r/graby](https://github.com/j0k3r/graby) from 2.4.5 to 2.4.6.
- [Release notes](https://github.com/j0k3r/graby/releases)
- [Commits](https://github.com/j0k3r/graby/compare/2.4.5...2.4.6)

---
updated-dependencies:
- dependency-name: j0k3r/graby
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-04 09:52:15 +00:00
c7c0ae9d8d Merge pull request #8060 from wallabag/dependabot/composer/sentry/sentry-symfony-5.2.0 2025-03-04 06:58:33 +01:00
c3927c6e10 Merge pull request #8061 from wallabag/dependabot/composer/friendsofphp/php-cs-fixer-3.70.2 2025-03-04 06:58:16 +01:00
8b4efe6cb8 Bump friendsofphp/php-cs-fixer from 3.70.1 to 3.70.2
Bumps [friendsofphp/php-cs-fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer) from 3.70.1 to 3.70.2.
- [Release notes](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/releases)
- [Changelog](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/compare/v3.70.1...v3.70.2)

---
updated-dependencies:
- dependency-name: friendsofphp/php-cs-fixer
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-04 03:17:10 +00:00
c1f6b6257d Bump sentry/sentry-symfony from 5.1.0 to 5.2.0
Bumps [sentry/sentry-symfony](https://github.com/getsentry/sentry-symfony) from 5.1.0 to 5.2.0.
- [Release notes](https://github.com/getsentry/sentry-symfony/releases)
- [Changelog](https://github.com/getsentry/sentry-symfony/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-symfony/compare/5.1.0...5.2.0)

---
updated-dependencies:
- dependency-name: sentry/sentry-symfony
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-04 03:16:17 +00:00
e7a70f1e46 Merge pull request #8053 from wallabag/dependabot/npm_and_yarn/annotator-082069d 2025-03-03 08:25:24 +01:00
7ac73407c0 Merge pull request #8050 from wallabag/dependabot/npm_and_yarn/babel-dependencies-8434337095 2025-03-03 08:20:42 +01:00
5505a0289b Merge pull request #8057 from wallabag/dependabot/composer/j0k3r/graby-site-config-1.0.197 2025-03-03 08:19:46 +01:00
8fa5bd2372 Merge pull request #8058 from wallabag/dependabot/composer/friendsofphp/php-cs-fixer-3.70.1 2025-03-03 08:19:30 +01:00
829e1661f4 Bump babel-loader from 9.2.1 to 10.0.0 in the babel-dependencies group
Bumps the babel-dependencies group with 1 update: [babel-loader](https://github.com/babel/babel-loader).


Updates `babel-loader` from 9.2.1 to 10.0.0
- [Release notes](https://github.com/babel/babel-loader/releases)
- [Changelog](https://github.com/babel/babel-loader/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel-loader/compare/v9.2.1...v10.0.0)

---
updated-dependencies:
- dependency-name: babel-loader
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: babel-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-03 03:30:16 +00:00
e3770399e0 Merge pull request #8056 from wallabag/dependabot/npm_and_yarn/core-js-3.41.0
Bump core-js from 3.40.0 to 3.41.0
2025-03-03 03:28:12 +00:00
defe421ffd Merge pull request #8055 from wallabag/dependabot/npm_and_yarn/terser-webpack-plugin-5.3.12
Bump terser-webpack-plugin from 5.3.11 to 5.3.12
2025-03-03 03:24:40 +00:00
03f8345246 Bump friendsofphp/php-cs-fixer from 3.70.0 to 3.70.1
Bumps [friendsofphp/php-cs-fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer) from 3.70.0 to 3.70.1.
- [Release notes](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/releases)
- [Changelog](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/compare/v3.70.0...v3.70.1)

---
updated-dependencies:
- dependency-name: friendsofphp/php-cs-fixer
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-03 03:24:28 +00:00
d73807a500 Bump j0k3r/graby-site-config from 1.0.196 to 1.0.197
Bumps [j0k3r/graby-site-config](https://github.com/j0k3r/graby-site-config) from 1.0.196 to 1.0.197.
- [Release notes](https://github.com/j0k3r/graby-site-config/releases)
- [Changelog](https://github.com/j0k3r/graby-site-config/blob/master/dallasnews.com.txt)
- [Commits](https://github.com/j0k3r/graby-site-config/compare/1.0.196...1.0.197)

---
updated-dependencies:
- dependency-name: j0k3r/graby-site-config
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-03 03:23:55 +00:00
1f822a826b Merge pull request #8052 from wallabag/dependabot/npm_and_yarn/sass-embedded-1.85.1
Bump sass-embedded from 1.85.0 to 1.85.1
2025-03-03 03:13:55 +00:00
35fe594743 Bump annotator from 3047fc2 to 082069d
Bumps [annotator](https://github.com/wallabag/annotator) from `3047fc2` to `082069d`.
- [Commits](3047fc22c8...082069d777)

---
updated-dependencies:
- dependency-name: annotator
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-03 03:11:46 +00:00
60e8c9399e Merge pull request #8051 from wallabag/dependabot/npm_and_yarn/fontsource-dependencies-524db9a575
Bump the fontsource-dependencies group with 4 updates
2025-03-03 03:10:22 +00:00
87bdac6eac Bump core-js from 3.40.0 to 3.41.0
Bumps [core-js](https://github.com/zloirock/core-js/tree/HEAD/packages/core-js) from 3.40.0 to 3.41.0.
- [Release notes](https://github.com/zloirock/core-js/releases)
- [Changelog](https://github.com/zloirock/core-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/zloirock/core-js/commits/v3.41.0/packages/core-js)

---
updated-dependencies:
- dependency-name: core-js
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-03 03:03:18 +00:00
41a30dfd20 Bump terser-webpack-plugin from 5.3.11 to 5.3.12
Bumps [terser-webpack-plugin](https://github.com/webpack-contrib/terser-webpack-plugin) from 5.3.11 to 5.3.12.
- [Release notes](https://github.com/webpack-contrib/terser-webpack-plugin/releases)
- [Changelog](https://github.com/webpack-contrib/terser-webpack-plugin/blob/master/CHANGELOG.md)
- [Commits](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v5.3.11...v5.3.12)

---
updated-dependencies:
- dependency-name: terser-webpack-plugin
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-03 03:03:09 +00:00
a3239bf416 Bump sass-embedded from 1.85.0 to 1.85.1
Bumps [sass-embedded](https://github.com/sass/embedded-host-node) from 1.85.0 to 1.85.1.
- [Changelog](https://github.com/sass/embedded-host-node/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sass/embedded-host-node/compare/1.85.0...1.85.1)

---
updated-dependencies:
- dependency-name: sass-embedded
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-03 03:02:39 +00:00
f16b276b63 Bump the fontsource-dependencies group with 4 updates
Bumps the fontsource-dependencies group with 4 updates: [@fontsource/atkinson-hyperlegible](https://github.com/fontsource/font-files/tree/HEAD/fonts/google/atkinson-hyperlegible), [@fontsource/eb-garamond](https://github.com/fontsource/font-files/tree/HEAD/fonts/google/eb-garamond), [@fontsource/montserrat](https://github.com/fontsource/font-files/tree/HEAD/fonts/google/montserrat) and [@fontsource/oswald](https://github.com/fontsource/font-files/tree/HEAD/fonts/google/oswald).


Updates `@fontsource/atkinson-hyperlegible` from 5.1.1 to 5.2.5
- [Changelog](https://github.com/fontsource/font-files/blob/main/CHANGELOG.md)
- [Commits](https://github.com/fontsource/font-files/commits/HEAD/fonts/google/atkinson-hyperlegible)

Updates `@fontsource/eb-garamond` from 5.1.2 to 5.2.5
- [Changelog](https://github.com/fontsource/font-files/blob/main/CHANGELOG.md)
- [Commits](https://github.com/fontsource/font-files/commits/HEAD/fonts/google/eb-garamond)

Updates `@fontsource/montserrat` from 5.1.1 to 5.2.5
- [Changelog](https://github.com/fontsource/font-files/blob/main/CHANGELOG.md)
- [Commits](https://github.com/fontsource/font-files/commits/HEAD/fonts/google/montserrat)

Updates `@fontsource/oswald` from 5.1.1 to 5.2.5
- [Changelog](https://github.com/fontsource/font-files/blob/main/CHANGELOG.md)
- [Commits](https://github.com/fontsource/font-files/commits/HEAD/fonts/google/oswald)

---
updated-dependencies:
- dependency-name: "@fontsource/atkinson-hyperlegible"
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: fontsource-dependencies
- dependency-name: "@fontsource/eb-garamond"
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: fontsource-dependencies
- dependency-name: "@fontsource/montserrat"
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: fontsource-dependencies
- dependency-name: "@fontsource/oswald"
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: fontsource-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-03 03:02:16 +00:00
f1ccc298ec Merge pull request #8043 from wallabag/fix-fab
Fix Floating Action Button
2025-03-02 04:21:42 +01:00
aa003054a5 Fix FAB 2025-03-01 22:55:56 +01:00
ee534a2415 Merge pull request #8040 from wallabag/remove-jquery-animations
Remove jQuery animations
2025-03-01 17:42:23 +01:00
b4b563f15d Merge pull request #8042 from wallabag/fix-toast
Fix toast since Materialize upgrade
2025-03-01 17:41:13 +01:00
43b4562ed2 Merge pull request #8041 from wallabag/fix-focus-card-in-dark-mode
Fix focus card in dark mode
2025-03-01 17:39:25 +01:00
00c618946c Fix toast since Materialize upgrade 2025-03-01 16:59:13 +01:00
cbdfd588fa Fix focus card in dark mode 2025-03-01 16:37:36 +01:00
0da398fd04 Remove jQuery animations 2025-03-01 16:23:08 +01:00
6165e61048 Merge pull request #8039 from wallabag/fix-checkboxes-from-form-type
Fix checkboxes from form type
2025-02-28 07:38:29 +01:00
3ebb4d7c8d Fix checkboxes from form type 2025-02-28 00:32:31 +01:00
9e02a69528 Merge pull request #8036 from ktx/master
Add 'application/vnd.ms-excel' to allowed MIME types config
2025-02-26 15:51:00 +01:00
674d6e7c95 Add 'application/vnd.ms-excel' to allowed MIME types config 2025-02-26 14:03:26 +01:00
5dc46b412c Merge pull request #8027 from yguedidi/update-annotator
Update Annotator
2025-02-24 08:30:45 +01:00
a6134a3e1f Merge pull request #8029 from wallabag/introduce-a-rabbitmq_url
Introduce a RABBITMQ_URL
2025-02-24 08:19:55 +01:00
bd1bcaa43f Update Annotator 2025-02-24 08:18:20 +01:00
f9847a0099 Introduce a RABBITMQ_URL 2025-02-24 08:14:47 +01:00
598515868c Merge pull request #8028 from wallabag/introduce-a-redis_url
Introduce a REDIS_URL
2025-02-24 08:04:50 +01:00
d857293372 Merge pull request #8032 from wallabag/dependabot/composer/friendsofphp/php-cs-fixer-3.70.0
Bump friendsofphp/php-cs-fixer from 3.69.1 to 3.70.0
2025-02-24 07:14:39 +01:00
e59b7b7552 Bump friendsofphp/php-cs-fixer from 3.69.1 to 3.70.0
Bumps [friendsofphp/php-cs-fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer) from 3.69.1 to 3.70.0.
- [Release notes](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/releases)
- [Changelog](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/compare/v3.69.1...v3.70.0)

---
updated-dependencies:
- dependency-name: friendsofphp/php-cs-fixer
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-24 03:54:05 +00:00
eec4a9ab72 Introduce a REDIS_URL 2025-02-22 13:43:45 +01:00
9a95f55b9c Use redis scheme for Redis 2025-02-22 13:34:09 +01:00
43a4f57798 Merge pull request #8025 from wallabag/dependabot/npm_and_yarn/symfony/webpack-encore-5.1.0
Bump @symfony/webpack-encore from 5.0.1 to 5.1.0
2025-02-20 14:37:30 +00:00
fc8029dd3a Merge pull request #8024 from wallabag/dependabot/npm_and_yarn/postcss-8.5.3
Bump postcss from 8.5.2 to 8.5.3
2025-02-20 14:34:17 +00:00
cd731a9520 Bump @symfony/webpack-encore from 5.0.1 to 5.1.0
Bumps [@symfony/webpack-encore](https://github.com/symfony/webpack-encore) from 5.0.1 to 5.1.0.
- [Release notes](https://github.com/symfony/webpack-encore/releases)
- [Changelog](https://github.com/symfony/webpack-encore/blob/main/CHANGELOG.md)
- [Commits](https://github.com/symfony/webpack-encore/compare/v5.0.1...v5.1.0)

---
updated-dependencies:
- dependency-name: "@symfony/webpack-encore"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-20 14:29:06 +00:00
7d3e90eba8 Bump postcss from 8.5.2 to 8.5.3
Bumps [postcss](https://github.com/postcss/postcss) from 8.5.2 to 8.5.3.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/8.5.2...8.5.3)

---
updated-dependencies:
- dependency-name: postcss
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-20 14:28:53 +00:00
15893fa8cd Merge pull request #8023 from wallabag/fix/dependabot-config-syntax
Fix dependabot file
2025-02-20 15:24:01 +01:00
1ebd1ce7ae Fix dependabot file
> (<unknown>): found character that cannot start any token while scanning for the next token at line 18 column 22
2025-02-20 15:03:26 +01:00
1b084f4faf Merge pull request #8015 from yguedidi/remove-unused-rss-limit-parameter
Remove unused RSS limit parameter
2025-02-20 11:15:56 +01:00
ac395cd492 Remove extra sentence in config.form_settings.display_thumbnails_label in ES 2025-02-20 10:29:54 +01:00
787c1ce2ab Remove legacy config.form_rss.* translations 2025-02-20 10:29:54 +01:00
d76465baf2 Rename rss_limit_too_high to feed_limit_too_high 2025-02-20 10:29:54 +01:00
f0cc7fdc27 Remove unused RSS limit parameter 2025-02-20 10:29:54 +01:00
72692dd298 Merge pull request #7920 from e-adrien/user-agent
Use Graby's http headers configuration for the authentication request
2025-02-20 10:24:23 +01:00
d58549472c Use Graby's http headers configuration for the authentication request 2025-02-20 08:47:19 +01:00
7070c075f5 Merge pull request #8019 from wallabag/make-all-parameters-configurable-with-environment-variables
Make all parameters configurable with environment variables
2025-02-20 08:46:46 +01:00
3e20d07f96 Merge pull request #8018 from wallabag/use-constructor-injection-for-registration-parameter
Use constructor injection for registration parameter
2025-02-20 08:46:26 +01:00
b905a2c856 Merge pull request #8017 from wallabag/make-wallabag_url-a-twig-global
Make wallabag_url a Twig global
2025-02-20 08:32:30 +01:00
21183a45be Merge pull request #8022 from wallabag/dependabot/composer/php-amqplib/php-amqplib-3.7.3 2025-02-20 07:05:29 +01:00
9ce9e2de00 Merge pull request #8021 from wallabag/dependabot/composer/friendsofphp/php-cs-fixer-3.69.1 2025-02-20 07:05:14 +01:00
ea03d1e2e6 Bump php-amqplib/php-amqplib from 3.7.2 to 3.7.3
Bumps [php-amqplib/php-amqplib](https://github.com/php-amqplib/php-amqplib) from 3.7.2 to 3.7.3.
- [Release notes](https://github.com/php-amqplib/php-amqplib/releases)
- [Changelog](https://github.com/php-amqplib/php-amqplib/blob/master/CHANGELOG.md)
- [Commits](https://github.com/php-amqplib/php-amqplib/compare/v3.7.2...v3.7.3)

---
updated-dependencies:
- dependency-name: php-amqplib/php-amqplib
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-20 03:32:02 +00:00
3959961bdd Bump friendsofphp/php-cs-fixer from 3.69.0 to 3.69.1
Bumps [friendsofphp/php-cs-fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer) from 3.69.0 to 3.69.1.
- [Release notes](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/releases)
- [Changelog](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/compare/v3.69.0...v3.69.1)

---
updated-dependencies:
- dependency-name: friendsofphp/php-cs-fixer
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-20 03:30:52 +00:00
5473a215ce Merge pull request #8013 from yguedidi/upgrade-materialize
Upgrade Materialize
2025-02-20 00:23:44 +01:00
0ecf990e79 Merge pull request #8020 from wallabag/fix-volatile-test
Fix volatile tests
2025-02-20 00:10:58 +01:00
0a432b0383 Merge pull request #8016 from wallabag/remove-legacy-translation-in-craueconfigbundle
Remove legacy translation in CraueConfigBundle
2025-02-20 00:10:01 +01:00
35251c0083 Make created at filters full width each 2025-02-19 23:01:06 +01:00
3bdd5713de Remove datepicker 2025-02-19 22:59:50 +01:00
3d0bd49730 Fix volatile tests 2025-02-19 21:41:53 +01:00
311675d30b Fix constructor call of AuthCodeMailer in AuthCodeMailerTest 2025-02-19 20:48:33 +01:00
460b509a1d Make all parameters configurable with environment variables 2025-02-19 20:42:37 +01:00
f0cc6ddb49 Use constructor injection for registration parameter 2025-02-19 20:39:26 +01:00
c5c9b130b0 Use wallabag_url in entries.xml 2025-02-19 20:36:20 +01:00
b921abf173 Make wallabag_url a Twig global 2025-02-19 20:36:13 +01:00
1f7fafa47a Remove legacy translation in CraueConfigBundle 2025-02-19 20:33:08 +01:00
f71d8332e0 Merge pull request #7999 from wallabag/fix/menu-entry-with-annotations
Fix entries counter for annotated entries in the menu
2025-02-10 10:12:45 +01:00
3dffcadc03 Fix entries counter for annotated entries in the menu
The query were badly made and return all annotations for the current user instead of the total of entries with annotation(s).
2025-02-10 08:42:06 +01:00
fab0c02ba0 Merge pull request #7993 from wallabag/fix/pocket-api-import 2025-02-07 21:26:07 +01:00
c4857564f3 Change NB_ELEMENTS in pocket importer to 30 to comply with Pocket API restriction. 2025-02-07 18:51:37 +01:00
c7c74de4b8 Merge pull request #7846 from wallabag/fix-title-tag-filter
Fix title tag filter
2024-11-22 14:05:14 +01:00
08b68d4d87 Display tag label instead of tag slug in page title 2024-11-22 13:49:08 +01:00
93e877f086 Merge pull request #7827 from wallabag/fix-redirection-action-search
Fix redirection after action in search results
2024-11-21 13:57:12 +01:00
82430b50c6 Fix redirection after action in search results 2024-11-21 13:36:20 +01:00
363 changed files with 6954 additions and 6843 deletions

View File

@ -24,7 +24,7 @@ If you want to test using an other database than SQLite, uncomment the `postgres
### Using your own PHP server
- Ensure you are running PHP >= 7.4.
- Ensure you are running PHP >= 8.2.
- Clone the repository
- Launch `composer install`
- If you got some errors, fix them (they might be related to some missing PHP extension from your machine)

View File

@ -15,13 +15,13 @@ updates:
patterns:
- "*fontsource*"
ignore:
- dependency-name: @materializecss/materialize
- dependency-name: "@materializecss/materialize"
versions:
- "> 1.2.2"
- package-ecosystem: composer
directory: "/"
schedule:
interval: daily
interval: weekly
time: "04:00"
timezone: Europe/Paris
open-pull-requests-limit: 10
@ -40,13 +40,8 @@ updates:
- yguedidi
- Kdecherf
ignore:
- dependency-name: lcobucci/jwt
versions:
- ">= 4.2.0"
# until we add support for Symfony 5+
- dependency-name: symfony/*
versions:
- ">= 5.0.0"
update-types: [ "version-update:semver-major" ]
- package-ecosystem: github-actions
directory: "/"
schedule:

View File

@ -13,7 +13,7 @@ permissions:
jobs:
coding-standards:
name: "CS Fixer, PHPStan & TwigCS"
runs-on: "ubuntu-20.04"
runs-on: ubuntu-latest
steps:
- name: "Checkout"
@ -23,7 +23,7 @@ jobs:
uses: "shivammathur/setup-php@v2"
with:
coverage: "none"
php-version: "7.4"
php-version: "8.2"
tools: cs2pr, pecl
extensions: pdo, pdo_mysql, pdo_sqlite, pdo_pgsql, curl, imagick, pgsql, gd, tidy
ini-values: "date.timezone=Europe/Paris"

View File

@ -16,7 +16,7 @@ env:
jobs:
phpunit:
name: "PHP ${{ matrix.php }} using ${{ matrix.database }}"
runs-on: "ubuntu-20.04"
runs-on: ubuntu-latest
services:
rabbitmq:
image: rabbitmq:3-alpine
@ -31,9 +31,6 @@ jobs:
fail-fast: false
matrix:
php:
- "7.4"
- "8.0"
- "8.1"
- "8.2"
- "8.3"
- "8.4"
@ -96,7 +93,7 @@ jobs:
phpunit_no_prefix:
name: "PHP ${{ matrix.php }} using ${{ matrix.database }} without prefix"
runs-on: "ubuntu-20.04"
runs-on: ubuntu-latest
services:
rabbitmq:
image: rabbitmq:3-alpine
@ -176,7 +173,7 @@ jobs:
phpunit-without-rmq-redis:
name: "PHP ${{ matrix.php }} using ${{ matrix.database }} without Rabbit & Redis"
runs-on: "ubuntu-20.04"
runs-on: ubuntu-latest
strategy:
fail-fast: false

View File

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

View File

@ -13,12 +13,12 @@ permissions:
jobs:
translations:
name: "Translations"
runs-on: "ubuntu-20.04"
runs-on: ubuntu-latest
strategy:
matrix:
php:
- "7.4"
- "8.2"
steps:
- name: "Checkout"

View File

@ -12,7 +12,7 @@ jobs:
strategy:
matrix:
php:
- "7.4"
- "8.2"
steps:
- name: "Checkout"

View File

@ -37,17 +37,6 @@ return $config
// 'psr_autoloading' => true,
'strict_comparison' => true,
'strict_param' => true,
// We override next rule because of current @Symfony ruleSet
// 'parameters' element is breaking PHP 7.4
// https://cs.symfony.com/doc/rules/control_structure/trailing_comma_in_multiline.html
// TODO: remove this configuration after dropping support of PHP 7.4
'trailing_comma_in_multiline' => [
'elements' => [
'arrays',
'array_destructuring',
'match',
],
],
'concat_space' => [
'spacing' => 'one',
],

View File

@ -2,8 +2,35 @@
## Upcoming changes
* **[BC BREAK]** Convert 403 errors to 404 errors by @yguedidi in https://github.com/wallabag/wallabag/pull/8075
* `wallassets/` folder renamed to `build/`
## [2.6.12](https://github.com/wallabag/wallabag/tree/2.6.12)
[Full Changelog](https://github.com/wallabag/wallabag/compare/2.6.11...2.6.12)
### Technical stuff
* Fix changelog by @yguedidi in [https://github.com/wallabag/wallabag/pull/8135](https://github.com/wallabag/wallabag/pull/8135)
* Update dependencies by @yguedidi in [https://github.com/wallabag/wallabag/pull/8136](https://github.com/wallabag/wallabag/pull/8136)
## [2.6.11](https://github.com/wallabag/wallabag/tree/2.6.11)
[Full Changelog](https://github.com/wallabag/wallabag/compare/2.6.10...2.6.11)
### Security fix
* Protect actions with a CSRF token by @yguedidi in https://github.com/wallabag/wallabag/commit/99c8a06594d6ee7480ce4d041ccff3025b353656
### Fixes
* Fix redirection after action in search results by @nicosomb in [https://github.com/wallabag/wallabag/pull/7827](https://github.com/wallabag/wallabag/pull/7827)
* Fix title tag filter by @nicosomb in [https://github.com/wallabag/wallabag/pull/7846](https://github.com/wallabag/wallabag/pull/7846)
* Change NB_ELEMENTS in pocket importer to 30 by @j0k3r in [https://github.com/wallabag/wallabag/pull/7993](https://github.com/wallabag/wallabag/pull/7993)
* Fix entries counter for annotated entries in the menu by @j0k3r in [https://github.com/wallabag/wallabag/pull/7999](https://github.com/wallabag/wallabag/pull/7999)
### Technical stuff
* Prepare 2.6.11 release by @yguedidi in [https://github.com/wallabag/wallabag/pull/8133](https://github.com/wallabag/wallabag/pull/8133)
## [2.6.10](https://github.com/wallabag/wallabag/tree/2.6.10)
[Full Changelog](https://github.com/wallabag/wallabag/compare/2.6.9...2.6.10)

View File

@ -52,6 +52,9 @@ fix-cs: ## Run PHP-CS-Fixer
phpstan: ## Run PHPStan
@$(PHP_NO_XDEBUG) bin/phpstan analyse
phpstan-baseline: ## Generate PHPStan baseline
@$(PHP_NO_XDEBUG) bin/phpstan analyse --generate-baseline
lint-js: ## Run ESLint
@$(YARN) lint:js

View File

@ -25,13 +25,13 @@ During this documentation, we assume the release is `$LAST_WALLABAG_RELEASE` (li
### Target PHP version
`composer.lock` is _always_ built for a particular version, by default the one it is generated (with `composer update`).
If the PHP version used to generate the .lock isn't a widely available one (like PHP 8), a more common one should
If the PHP version used to generate the .lock isn't a widely available one (like latest PHP versions), a more common one should
be locally specified in `composer.lock`:
```json
"config": {
"platform": {
"php": "7.4.29",
"php": "8.2.27",
"ext-something": "4.0"
}
}

View File

@ -1,8 +1,39 @@
<?php
use BabDev\PagerfantaBundle\BabDevPagerfantaBundle;
use Bazinga\Bundle\HateoasBundle\BazingaHateoasBundle;
use Craue\ConfigBundle\CraueConfigBundle;
use DAMA\DoctrineTestBundle\DAMADoctrineTestBundle;
use Doctrine\Bundle\DoctrineBundle\DoctrineBundle;
use Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle;
use Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle;
use FOS\JsRoutingBundle\FOSJsRoutingBundle;
use FOS\OAuthServerBundle\FOSOAuthServerBundle;
use FOS\RestBundle\FOSRestBundle;
use FOS\UserBundle\FOSUserBundle;
use JMS\SerializerBundle\JMSSerializerBundle;
use KPhoen\RulerZBundle\KPhoenRulerZBundle;
use Nelmio\ApiDocBundle\NelmioApiDocBundle;
use Nelmio\CorsBundle\NelmioCorsBundle;
use OldSound\RabbitMqBundle\OldSoundRabbitMqBundle;
use Scheb\TwoFactorBundle\SchebTwoFactorBundle;
use Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle;
use Sentry\SentryBundle\SentryBundle;
use Spiriit\Bundle\FormFilterBundle\SpiriitFormFilterBundle;
use Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle;
use Symfony\Bundle\DebugBundle\DebugBundle;
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
use Symfony\Bundle\MakerBundle\MakerBundle;
use Symfony\Bundle\MonologBundle\MonologBundle;
use Symfony\Bundle\SecurityBundle\SecurityBundle;
use Symfony\Bundle\TwigBundle\TwigBundle;
use Symfony\Bundle\WebProfilerBundle\WebProfilerBundle;
use Symfony\Bundle\WebServerBundle\WebServerBundle;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Kernel;
use Symfony\WebpackEncoreBundle\WebpackEncoreBundle;
use Twig\Extra\TwigExtraBundle\TwigExtraBundle;
use Wallabag\Import\ImportCompilerPass;
class AppKernel extends Kernel
@ -10,45 +41,45 @@ class AppKernel extends Kernel
public function registerBundles()
{
$bundles = [
new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
new Symfony\Bundle\SecurityBundle\SecurityBundle(),
new Symfony\Bundle\TwigBundle\TwigBundle(),
new Symfony\Bundle\MonologBundle\MonologBundle(),
new Doctrine\Bundle\DoctrineBundle\DoctrineBundle(),
new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(),
new FOS\RestBundle\FOSRestBundle(),
new FOS\UserBundle\FOSUserBundle(),
new JMS\SerializerBundle\JMSSerializerBundle(),
new Nelmio\ApiDocBundle\NelmioApiDocBundle(),
new Nelmio\CorsBundle\NelmioCorsBundle(),
new Bazinga\Bundle\HateoasBundle\BazingaHateoasBundle(),
new Spiriit\Bundle\FormFilterBundle\SpiriitFormFilterBundle(),
new FOS\OAuthServerBundle\FOSOAuthServerBundle(),
new Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle(),
new Scheb\TwoFactorBundle\SchebTwoFactorBundle(),
new KPhoen\RulerZBundle\KPhoenRulerZBundle(),
new Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle(),
new Craue\ConfigBundle\CraueConfigBundle(),
new BabDev\PagerfantaBundle\BabDevPagerfantaBundle(),
new FOS\JsRoutingBundle\FOSJsRoutingBundle(),
new OldSound\RabbitMqBundle\OldSoundRabbitMqBundle(),
new Sentry\SentryBundle\SentryBundle(),
new Twig\Extra\TwigExtraBundle\TwigExtraBundle(),
new Symfony\WebpackEncoreBundle\WebpackEncoreBundle(),
new FrameworkBundle(),
new SecurityBundle(),
new TwigBundle(),
new MonologBundle(),
new DoctrineBundle(),
new SensioFrameworkExtraBundle(),
new FOSRestBundle(),
new FOSUserBundle(),
new JMSSerializerBundle(),
new NelmioApiDocBundle(),
new NelmioCorsBundle(),
new BazingaHateoasBundle(),
new SpiriitFormFilterBundle(),
new FOSOAuthServerBundle(),
new StofDoctrineExtensionsBundle(),
new SchebTwoFactorBundle(),
new KPhoenRulerZBundle(),
new DoctrineMigrationsBundle(),
new CraueConfigBundle(),
new BabDevPagerfantaBundle(),
new FOSJsRoutingBundle(),
new OldSoundRabbitMqBundle(),
new SentryBundle(),
new TwigExtraBundle(),
new WebpackEncoreBundle(),
];
if (in_array($this->getEnvironment(), ['dev', 'test'], true)) {
$bundles[] = new Symfony\Bundle\DebugBundle\DebugBundle();
$bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle();
$bundles[] = new Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle();
$bundles[] = new DebugBundle();
$bundles[] = new WebProfilerBundle();
$bundles[] = new DoctrineFixturesBundle();
if ('test' === $this->getEnvironment()) {
$bundles[] = new DAMA\DoctrineTestBundle\DAMADoctrineTestBundle();
$bundles[] = new DAMADoctrineTestBundle();
}
if ('dev' === $this->getEnvironment()) {
$bundles[] = new Symfony\Bundle\MakerBundle\MakerBundle();
$bundles[] = new Symfony\Bundle\WebServerBundle\WebServerBundle();
$bundles[] = new MakerBundle();
$bundles[] = new WebServerBundle();
}
}
@ -69,14 +100,16 @@ class AppKernel extends Kernel
{
$loader->load($this->getProjectDir() . '/app/config/config_' . $this->getEnvironment() . '.yml');
$loader->load(function (ContainerBuilder $container) {
$loader->load(function (ContainerBuilder $container): void {
// $container->setParameter('container.autowiring.strict_mode', true);
// $container->setParameter('container.dumper.inline_class_loader', true);
$container->addObjectResource($this);
});
$loader->load(function (ContainerBuilder $container) {
$loader->load(function (ContainerBuilder $container): void {
$this->processDatabaseParameters($container);
$this->defineRedisUrlEnvVar($container);
$this->defineRabbitMqUrlEnvVar($container);
});
}
@ -87,19 +120,12 @@ class AppKernel extends Kernel
private function processDatabaseParameters(ContainerBuilder $container)
{
switch ($container->getParameter('database_driver')) {
case 'pdo_mysql':
$scheme = 'mysql';
break;
case 'pdo_pgsql':
$scheme = 'pgsql';
break;
case 'pdo_sqlite':
$scheme = 'sqlite';
break;
default:
throw new RuntimeException('Unsupported database driver: ' . $container->getParameter('database_driver'));
}
$scheme = match ($container->getParameter('database_driver')) {
'pdo_mysql' => 'mysql',
'pdo_pgsql' => 'pgsql',
'pdo_sqlite' => 'sqlite',
default => throw new RuntimeException('Unsupported database driver: ' . $container->getParameter('database_driver')),
};
$container->setParameter('database_scheme', $scheme);
@ -112,4 +138,45 @@ class AppKernel extends Kernel
$container->setParameter('database_port', (string) $container->getParameter('database_port'));
$container->setParameter('database_socket', (string) $container->getParameter('database_socket'));
}
private function defineRedisUrlEnvVar(ContainerBuilder $container)
{
$scheme = $container->getParameter('redis_scheme');
$host = $container->getParameter('redis_host');
$port = $container->getParameter('redis_port');
$path = $container->getParameter('redis_path');
$password = $container->getParameter('redis_password');
$url = $scheme . '://';
if ($password) {
$url .= $password . '@';
}
$url .= $host;
if ($port) {
$url .= ':' . $port;
}
$url .= '/' . ltrim($path, '/');
$container->setParameter('env(REDIS_URL)', $url);
}
private function defineRabbitMqUrlEnvVar(ContainerBuilder $container)
{
$host = $container->getParameter('rabbitmq_host');
$port = $container->getParameter('rabbitmq_port');
$user = $container->getParameter('rabbitmq_user');
$password = $container->getParameter('rabbitmq_password');
$url = 'amqp://' . $user . ':' . $password . '@' . $host;
if ($port) {
$url .= ':' . $port;
}
$container->setParameter('env(RABBITMQ_URL)', $url);
}
}

View File

@ -29,6 +29,8 @@ framework:
handler_id: session.handler.native_file
save_path: "%kernel.project_dir%/var/sessions/%kernel.environment%"
cookie_secure: auto
cookie_samesite: lax
storage_factory_id: session.storage.factory.native
fragments: ~
http_method_override: true
assets:
@ -60,6 +62,7 @@ twig:
form_themes:
- "@SpiriitFormFilter/Form/form_div_layout.html.twig"
globals:
wallabag_url: '%domain_name%'
registration_enabled: '%fosuser_registration%'
# Doctrine Configuration
@ -76,7 +79,7 @@ doctrine:
auto_mapping: true
mappings:
Wallabag:
type: annotation
type: attribute
is_bundle: false
dir: '%kernel.project_dir%/src/Entity'
prefix: 'Wallabag\Entity'
@ -196,7 +199,7 @@ fos_user:
address: "%from_email%"
sender_name: wallabag
service:
mailer: Wallabag\Mailer\UserMailer
mailer: fos_user.mailer.twig_symfony
fos_oauth_server:
db_driver: orm
@ -231,19 +234,11 @@ scheb_two_factor:
template: "Authentication/form.html.twig"
mailer: Wallabag\Mailer\AuthCodeMailer
rulerz:
targets:
doctrine: true
old_sound_rabbit_mq:
connections:
default:
host: "%rabbitmq_host%"
port: "%rabbitmq_port%"
user: "%rabbitmq_user%"
password: "%rabbitmq_password%"
vhost: /
lazy: true
url: "%env(RABBITMQ_URL)%"
lazy: true
producers:
import_pocket:
connection: default

View File

@ -10,7 +10,7 @@ parameters:
framework:
test: ~
session:
storage_id: session.storage.mock_file
storage_factory_id: session.storage.factory.mock_file
profiler:
collect: false
translator:

View File

@ -47,8 +47,6 @@ parameters:
from_email: no-reply@wallabag.org
rss_limit: 50
# RabbitMQ processing
rabbitmq_host: localhost
rabbitmq_port: 5672
@ -57,7 +55,7 @@ parameters:
rabbitmq_prefetch_count: 10
# Redis processing
redis_scheme: tcp
redis_scheme: redis
redis_host: localhost
redis_port: 6379
redis_path: null

View File

@ -13,6 +13,7 @@ doc-api-json:
homepage:
path: "/{page}"
methods: GET
defaults:
_controller: 'Wallabag\Controller\EntryController::showUnreadAction'
page : 1
@ -27,23 +28,27 @@ fos_oauth_server_token:
craue_config_settings_modify:
path: /settings
methods: [GET, POST]
defaults:
_controller: 'Craue\ConfigBundle\Controller\SettingsController::modifyAction'
fos_js_routing:
resource: "@FOSJsRoutingBundle/Resources/config/routing/routing.xml"
resource: "@FOSJsRoutingBundle/Resources/config/routing/routing-sf4.xml"
2fa_login:
path: /2fa
methods: GET
defaults:
_controller: "scheb_two_factor.form_controller:form"
2fa_login_check:
path: /2fa_check
methods: POST
# redirect RSS feed to Atom
rss_to_atom_unread:
path: /{username}/{token}/unread.xml
methods: GET
defaults:
_controller: 'Symfony\Bundle\FrameworkBundle\Controller\RedirectController::redirectAction'
route: unread_feed
@ -51,6 +56,7 @@ rss_to_atom_unread:
rss_to_atom_archive:
path: /{username}/{token}/archive.xml
methods: GET
defaults:
_controller: 'Symfony\Bundle\FrameworkBundle\Controller\RedirectController::redirectAction'
route: archive_feed
@ -58,6 +64,7 @@ rss_to_atom_archive:
rss_to_atom_starred:
path: /{username}/{token}/starred.xml
methods: GET
defaults:
_controller: 'Symfony\Bundle\FrameworkBundle\Controller\RedirectController::redirectAction'
route: starred_feed
@ -65,6 +72,7 @@ rss_to_atom_starred:
rss_to_atom_all:
path: /{username}/{token}/all.xml
methods: GET
defaults:
_controller: 'Symfony\Bundle\FrameworkBundle\Controller\RedirectController::redirectAction'
route: all_feed
@ -72,6 +80,7 @@ rss_to_atom_all:
rss_to_atom_tags:
path: /{username}/{token}/tags/{slug}.xml
methods: GET
defaults:
_controller: 'Symfony\Bundle\FrameworkBundle\Controller\RedirectController::redirectAction'
route: tag_feed

View File

@ -1,5 +1,5 @@
security:
encoders:
password_hashers:
FOS\UserBundle\Model\UserInterface: sha512
role_hierarchy:
@ -70,10 +70,9 @@ security:
- { path: /(unread|starred|archive|annotated|all).xml$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/locale, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: /tags/(.*).xml$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/feed, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/feed, roles: PUBLIC_ACCESS }
- { path: /(unread|starred|archive|annotated).xml$, roles: IS_AUTHENTICATED_ANONYMOUSLY } # For backwards compatibility
- { path: ^/share, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/settings, roles: ROLE_SUPER_ADMIN }
- { path: ^/annotations, roles: ROLE_USER }
- { path: ^/2fa, role: IS_AUTHENTICATED_2FA_IN_PROGRESS }
- { path: ^/, roles: ROLE_USER }

View File

@ -230,30 +230,17 @@ services:
tags:
- { name: rulerz.operator, target: native, operator: matches }
Wallabag\Operator\Doctrine\Matches:
tags:
- { name: rulerz.operator, target: doctrine, operator: matches, inline: true }
Wallabag\Operator\PHP\NotMatches:
tags:
- { name: rulerz.operator, target: native, operator: notmatches }
Wallabag\Operator\Doctrine\NotMatches:
tags:
- { name: rulerz.operator, target: doctrine, operator: notmatches, inline: true }
Wallabag\Operator\PHP\PatternMatches:
tags:
- { name: rulerz.operator, target: native, operator: "~" }
Predis\Client:
arguments:
$parameters:
scheme: '%redis_scheme%'
host: '%redis_host%'
port: '%redis_port%'
path: '%redis_path%'
password: '%redis_password%'
$parameters: '%env(REDIS_URL)%'
Wallabag\Event\Subscriber\SQLiteCascadeDeleteSubscriber:
tags:
@ -273,16 +260,6 @@ services:
$defaultSettings: '%wallabag.default_internal_settings%'
$defaultIgnoreOriginInstanceRules: '%wallabag.default_ignore_origin_instance_rules%'
Wallabag\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\Event\Listener\CreateConfigListener:
arguments:
$itemsOnPage: "%wallabag.items_on_page%"
@ -299,55 +276,80 @@ services:
Wallabag\Import\PocketImport:
calls:
- [ setEnabled, [ '@=service(''craue_config'').get(''pocket_enabled'')' ] ]
- [ setClient, [ '@Symfony\Contracts\HttpClient\HttpClientInterface $pocketClient' ] ]
tags:
- { name: wallabag.import, alias: pocket }
Wallabag\Import\WallabagV1Import:
calls:
- [ setEnabled, [ '@=service(''craue_config'').get(''wallabag_v1_enabled'')' ] ]
tags:
- { name: wallabag.import, alias: wallabag_v1 }
Wallabag\Import\WallabagV2Import:
calls:
- [ setEnabled, [ '@=service(''craue_config'').get(''wallabag_v2_enabled'')' ] ]
tags:
- { name: wallabag.import, alias: wallabag_v2 }
Wallabag\Import\ElcuratorImport:
calls:
- [ setEnabled, [ '@=service(''craue_config'').get(''elcurator_enabled'')' ] ]
tags:
- { name: wallabag.import, alias: elcurator }
Wallabag\Import\ReadabilityImport:
calls:
- [ setEnabled, [ '@=service(''craue_config'').get(''readability_enabled'')' ] ]
tags:
- { name: wallabag.import, alias: readability }
Wallabag\Import\InstapaperImport:
calls:
- [ setEnabled, [ '@=service(''craue_config'').get(''instapaper_enabled'')' ] ]
tags:
- { name: wallabag.import, alias: instapaper }
Wallabag\Import\PinboardImport:
calls:
- [ setEnabled, [ '@=service(''craue_config'').get(''pinboard_enabled'')' ] ]
tags:
- { name: wallabag.import, alias: pinboard }
Wallabag\Import\DeliciousImport:
calls:
- [ setEnabled, [ '@=service(''craue_config'').get(''delicious_enabled'')' ] ]
tags:
- { name: wallabag.import, alias: delicious }
Wallabag\Import\OmnivoreImport:
calls:
- [ setEnabled, [ '@=service(''craue_config'').get(''omnivore_enabled'')' ] ]
tags:
- { name: wallabag.import, alias: omnivore }
Wallabag\Import\FirefoxImport:
calls:
- [ setEnabled, [ '@=service(''craue_config'').get(''firefox_enabled'')' ] ]
tags:
- { name: wallabag.import, alias: firefox }
Wallabag\Import\ChromeImport:
calls:
- [ setEnabled, [ '@=service(''craue_config'').get(''chrome_enabled'')' ] ]
tags:
- { name: wallabag.import, alias: chrome }
Wallabag\Import\ShaarliImport:
calls:
- [ setEnabled, [ '@=service(''craue_config'').get(''shaarli_enabled'')' ] ]
tags:
- { name: wallabag.import, alias: shaarli }
Wallabag\Import\PocketHtmlImport:
calls:
- [ setEnabled, [ '@=service(''craue_config'').get(''pocket_html_enabled'')' ] ]
tags:
- { name: wallabag.import, alias: pocket_html }

View File

@ -1,5 +1,5 @@
parameters:
wallabag.version: 2.6.10
wallabag.version: 2.7.0-dev
wallabag.paypal_url: "https://liberapay.com/wallabag/donate"
wallabag.languages:
en: 'English'
@ -126,6 +126,58 @@ parameters:
name: import_with_rabbitmq
value: 0
section: import
-
name: pocket_enabled
value: 1
section: import
-
name: wallabag_v1_enabled
value: 1
section: import
-
name: wallabag_v2_enabled
value: 1
section: import
-
name: elcurator_enabled
value: 1
section: import
-
name: readability_enabled
value: 1
section: import
-
name: instapaper_enabled
value: 1
section: import
-
name: pinboard_enabled
value: 1
section: import
-
name: delicious_enabled
value: 1
section: import
-
name: omnivore_enabled
value: 1
section: import
-
name: firefox_enabled
value: 1
section: import
-
name: chrome_enabled
value: 1
section: import
-
name: shaarli_enabled
value: 1
section: import
-
name: pocket_html_enabled
value: 1
section: import
-
name: matomo_enabled
value: 0
@ -175,5 +227,11 @@ parameters:
- 'Montserrat'
- 'OpenDyslexicRegular'
- 'Oswald'
wallabag.allow_mimetypes: ['application/octet-stream', 'application/json', 'text/plain', 'text/csv', 'text/html']
wallabag.allow_mimetypes:
- 'application/octet-stream'
- 'application/json'
- 'text/plain'
- 'text/csv'
- 'text/html'
- 'application/vnd.ms-excel'
wallabag.resource_dir: "%kernel.project_dir%/web/uploads/import"

11
assets/bootstrap.js vendored Normal file
View File

@ -0,0 +1,11 @@
import { startStimulusApp } from '@symfony/stimulus-bridge';
// Registers Stimulus controllers from controllers.json and in the controllers/ directory
export default startStimulusApp(require.context(
'@symfony/stimulus-bridge/lazy-controller-loader!./controllers',
true,
/\.[jt]sx?$/,
));
// register any custom, 3rd party controllers here
// app.register('some_controller_name', SomeImportedController);

4
assets/controllers.json Normal file
View File

@ -0,0 +1,4 @@
{
"controllers": [],
"entrypoints": []
}

View File

@ -0,0 +1,13 @@
import { Controller } from '@hotwired/stimulus';
export default class extends Controller {
static targets = ['input'];
toggle() {
this.element.classList.toggle('hidden');
if (!this.element.classList.contains('hidden')) {
this.inputTarget.focus();
}
}
}

View File

@ -0,0 +1,57 @@
import { Controller } from '@hotwired/stimulus';
import annotator from 'annotator';
export default class extends Controller {
static values = {
entryId: Number,
createUrl: String,
updateUrl: String,
destroyUrl: String,
searchUrl: String,
};
connect() {
this.app = new annotator.App();
this.app.include(annotator.ui.main, {
element: this.element,
});
const authorization = {
permits() { return true; },
};
this.app.registry.registerUtility(authorization, 'authorizationPolicy');
this.app.include(annotator.storage.http, {
prefix: '',
urls: {
create: this.createUrlValue,
update: this.updateUrlValue,
destroy: this.destroyUrlValue,
search: this.searchUrlValue,
},
entryId: this.entryIdValue,
onError(msg, xhr) {
if (!Object.prototype.hasOwnProperty.call(xhr, 'responseJSON')) {
annotator.notification.banner('An error occurred', 'error');
return;
}
Object.values(xhr.responseJSON.children).forEach((v) => {
if (v.errors) {
Object.values(v.errors).forEach((errorText) => {
annotator.notification.banner(errorText, 'error');
});
}
});
},
});
this.app.start().then(() => {
this.app.annotations.load({ entry: this.entryIdValue });
});
}
disconnect() {
this.app.destroy();
}
}

View File

@ -0,0 +1,15 @@
import { Controller } from '@hotwired/stimulus';
export default class extends Controller {
static targets = ['item', 'tagAction'];
toggleSelection(e) {
this.itemTargets.forEach((item) => {
item.checked = e.currentTarget.checked; // eslint-disable-line no-param-reassign
});
}
tagSelection() {
this.element.requestSubmit(this.tagActionTarget);
}
}

View File

@ -0,0 +1,16 @@
import { Controller } from '@hotwired/stimulus';
import ClipboardJS from 'clipboard';
export default class extends Controller {
connect() {
this.clipboard = new ClipboardJS(this.element);
this.clipboard.on('success', (e) => {
e.clearSelection();
});
}
disconnect() {
this.clipboard.destroy();
}
}

View File

@ -0,0 +1,16 @@
import { Controller } from '@hotwired/stimulus';
export default class extends Controller {
static targets = ['previewArticle', 'previewContent', 'font', 'fontSize', 'lineHeight', 'maxWidth'];
connect() {
this.updatePreview();
}
updatePreview() {
this.previewArticleTarget.style.maxWidth = `${this.maxWidthTarget.value}em`;
this.previewContentTarget.style.fontFamily = this.fontTarget.value;
this.previewContentTarget.style.fontSize = `${this.fontSizeTarget.value}em`;
this.previewContentTarget.style.lineHeight = `${this.lineHeightTarget.value}em`;
}
}

View File

@ -0,0 +1,39 @@
import { Controller } from '@hotwired/stimulus';
export default class extends Controller {
connect() {
this.#choose();
this.mql = window.matchMedia('(prefers-color-scheme: dark)');
this.mql.addEventListener('change', this.#choose.bind(this));
}
useLight() {
this.element.classList.remove('dark-theme');
document.cookie = 'theme=light;samesite=Lax;path=/;max-age=31536000';
}
useDark() {
this.element.classList.add('dark-theme');
document.cookie = 'theme=dark;samesite=Lax;path=/;max-age=31536000';
}
useAuto() {
document.cookie = 'theme=auto;samesite=Lax;path=/;max-age=0';
this.#choose();
}
#choose() {
const themeCookieExists = document.cookie.split(';').some((cookie) => cookie.trim().startsWith('theme='));
if (themeCookieExists) {
return;
}
if (this.mql.matches) {
this.element.classList.add('dark-theme');
} else {
this.element.classList.remove('dark-theme');
}
}
}

View File

@ -0,0 +1,58 @@
import { Controller } from '@hotwired/stimulus';
export default class extends Controller {
static targets = ['card', 'paginationWrapper'];
connect() {
this.pagination = this.paginationWrapperTarget.querySelector('.pagination');
this.cardIndex = 0;
this.lastCardIndex = this.cardTargets.length - 1;
/* If we come from next page */
if (window.location.hash === '#prev') {
this.cardIndex = this.lastCardIndex;
}
this.currentCard = this.cardTargets[this.cardIndex];
this.currentCard.classList.add('z-depth-4');
}
selectRightCard() {
if (this.cardIndex >= 0 && this.cardIndex < this.lastCardIndex) {
this.currentCard.classList.remove('z-depth-4');
this.cardIndex += 1;
this.currentCard = this.cardTargets[this.cardIndex];
this.currentCard.classList.add('z-depth-4');
return;
}
if (this.pagination && this.pagination.querySelector('a[rel="next"]')) {
window.location.href = this.pagination.querySelector('a[rel="next"]').href;
}
}
selectLeftCard() {
if (this.cardIndex > 0 && this.cardIndex <= this.lastCardIndex) {
this.currentCard.classList.remove('z-depth-4');
this.cardIndex -= 1;
this.currentCard = this.cardTargets[this.cardIndex];
this.currentCard.classList.add('z-depth-4');
return;
}
if (this.pagination && this.pagination.querySelector('a[rel="prev"]')) {
window.location.href = `${this.pagination.querySelector('a[rel="prev"]').href}#prev`;
}
}
selectCurrentCard() {
const url = this.currentCard.querySelector('a.card-title').href;
if (url) {
window.location.href = url;
}
}
}

View File

@ -0,0 +1,13 @@
import { Controller } from '@hotwired/stimulus';
export default class extends Controller {
static targets = ['emailTwoFactor', 'googleTwoFactor'];
uncheckGoogle() {
this.googleTwoFactorTarget.checked = false;
}
uncheckEmail() {
this.emailTwoFactorTarget.checked = false;
}
}

View File

@ -0,0 +1,11 @@
import { Controller } from '@hotwired/stimulus';
import 'highlight.js/styles/atom-one-light.css';
import hljs from 'highlight.js';
export default class extends Controller {
connect() {
this.element.querySelectorAll('pre code').forEach((element) => {
hljs.highlightElement(element);
});
}
}

View File

@ -0,0 +1,7 @@
import { Controller } from '@hotwired/stimulus';
export default class extends Controller {
toggleAddTagForm() {
this.dispatch('toggleAddTagForm');
}
}

View File

@ -0,0 +1,16 @@
import { Controller } from '@hotwired/stimulus';
import M from '@materializecss/materialize';
export default class extends Controller {
static values = {
accordion: { type: Boolean, default: true },
};
connect() {
this.instance = M.Collapsible.init(this.element, { accordion: this.accordionValue });
}
disconnect() {
this.instance.destroy();
}
}

View File

@ -0,0 +1,16 @@
import { Controller } from '@hotwired/stimulus';
import M from '@materializecss/materialize';
export default class extends Controller {
connect() {
this.instance = M.Dropdown.init(this.element, {
hover: false,
coverTrigger: false,
constrainWidth: false,
});
}
disconnect() {
this.instance.destroy();
}
}

View File

@ -0,0 +1,32 @@
import { Controller } from '@hotwired/stimulus';
import M from '@materializecss/materialize';
export default class extends Controller {
static values = {
edge: { type: String, default: 'left' },
};
connect() {
this.instance = M.FloatingActionButton.init(this.element);
}
autoDisplay() {
const scrolled = (window.innerHeight + window.scrollY) >= document.body.offsetHeight;
if (scrolled) {
this.toggleScroll = true;
this.instance.open();
} else if (this.toggleScroll === true) {
this.toggleScroll = false;
this.instance.close();
}
}
click() {
this.dispatch('click');
}
disconnect() {
this.instance.destroy();
}
}

View File

@ -0,0 +1,12 @@
import { Controller } from '@hotwired/stimulus';
import M from '@materializecss/materialize';
export default class extends Controller {
connect() {
this.instance = M.FormSelect.init(this.element.querySelector('select'));
}
disconnect() {
this.instance.destroy();
}
}

View File

@ -0,0 +1,24 @@
import { Controller } from '@hotwired/stimulus';
import M from '@materializecss/materialize';
const mobileMaxWidth = 993;
export default class extends Controller {
static values = {
edge: { type: String, default: 'left' },
};
connect() {
this.instance = M.Sidenav.init(this.element, { edge: this.edgeValue });
}
close() {
if (window.innerWidth < mobileMaxWidth) {
this.instance.close();
}
}
disconnect() {
this.instance.destroy();
}
}

View File

@ -0,0 +1,12 @@
import { Controller } from '@hotwired/stimulus';
import M from '@materializecss/materialize';
export default class extends Controller {
connect() {
this.instance = M.Tabs.init(this.element);
}
disconnect() {
this.instance.destroy();
}
}

View File

@ -0,0 +1,12 @@
import { Controller } from '@hotwired/stimulus';
import M from '@materializecss/materialize';
export default class extends Controller {
connect() {
this.instance = M.toast({ text: this.element.innerText });
}
disconnect() {
this.instance.dismissAll();
}
}

View File

@ -0,0 +1,12 @@
import { Controller } from '@hotwired/stimulus';
import M from '@materializecss/materialize';
export default class extends Controller {
connect() {
this.instance = M.Tooltip.init(this.element);
}
disconnect() {
this.instance.destroy();
}
}

View File

@ -0,0 +1,10 @@
import { Controller } from '@hotwired/stimulus';
import jrQrcode from 'jr-qrcode';
export default class extends Controller {
static values = { url: String };
connect() {
this.element.setAttribute('src', jrQrcode.getQrBase64(this.urlValue));
}
}

View File

@ -0,0 +1,10 @@
import { Controller } from '@hotwired/stimulus';
export default class extends Controller {
updateWidth() {
const referenceHeight = document.body.offsetHeight - window.innerHeight;
const scrollPercent = (window.scrollY / referenceHeight) * 100;
this.element.style.width = `${scrollPercent}%`;
}
}

View File

@ -0,0 +1,19 @@
import { Controller } from '@hotwired/stimulus';
export default class extends Controller {
static values = { entryId: Number };
connect() {
window.scrollTo({
top: window.innerHeight * localStorage[`wallabag.article.${this.entryIdValue}.percent`],
behavior: 'smooth',
});
}
saveScroll() {
const scrollPercent = window.scrollY / window.innerHeight;
const scrollPercentRounded = Math.round(scrollPercent * 100) / 100;
localStorage[`wallabag.article.${this.entryIdValue}.percent`] = scrollPercentRounded;
}
}

View File

@ -0,0 +1,141 @@
import { Controller } from '@hotwired/stimulus';
import Mousetrap from 'mousetrap';
export default class extends Controller {
static targets = ['openOriginal', 'markAsFavorite', 'markAsRead', 'deleteEntry', 'showAddUrl', 'showSearch', 'showActions'];
static outlets = ['entries-navigation'];
connect() {
/* Go to */
Mousetrap.bind('g u', () => {
window.location.href = Routing.generate('homepage');
});
Mousetrap.bind('g s', () => {
window.location.href = Routing.generate('starred');
});
Mousetrap.bind('g r', () => {
window.location.href = Routing.generate('archive');
});
Mousetrap.bind('g a', () => {
window.location.href = Routing.generate('all');
});
Mousetrap.bind('g t', () => {
window.location.href = Routing.generate('tag');
});
Mousetrap.bind('g c', () => {
window.location.href = Routing.generate('config');
});
Mousetrap.bind('g i', () => {
window.location.href = Routing.generate('import');
});
Mousetrap.bind('g d', () => {
window.location.href = Routing.generate('developer');
});
Mousetrap.bind('?', () => {
window.location.href = Routing.generate('howto');
});
Mousetrap.bind('g l', () => {
window.location.href = Routing.generate('fos_user_security_logout');
});
/* open original article */
Mousetrap.bind('o', () => {
if (!this.hasOpenOriginalTarget) {
return;
}
this.openOriginalTarget.click();
});
/* mark as favorite */
Mousetrap.bind('f', () => {
if (!this.hasMarkAsFavoriteTarget) {
return;
}
this.markAsFavoriteTarget.click();
});
/* mark as read */
Mousetrap.bind('a', () => {
if (!this.hasMarkAsReadTarget) {
return;
}
this.markAsReadTarget.click();
});
/* delete */
Mousetrap.bind('del', () => {
if (!this.hasDeleteEntryTarget) {
return;
}
this.deleteEntryTarget.click();
});
/* Actions */
Mousetrap.bind('g n', (e) => {
if (!this.hasShowAddUrlTarget) {
return;
}
e.preventDefault();
this.showAddUrlTarget.click();
});
Mousetrap.bind('s', (e) => {
if (!this.hasShowSearchTarget) {
return;
}
e.preventDefault();
this.showSearchTarget.click();
});
Mousetrap.bind('esc', (e) => {
if (!this.hasShowActionsTarget) {
return;
}
e.preventDefault();
this.showActionsTarget.click();
});
const originalStopCallback = Mousetrap.prototype.stopCallback;
Mousetrap.prototype.stopCallback = (e, element, combo) => {
// allow esc key to be used in input fields of topbar
if (combo === 'esc' && element.dataset.topbarTarget !== undefined) {
return false;
}
return originalStopCallback(e, element);
};
Mousetrap.bind('right', () => {
if (!this.hasEntriesNavigationOutlet) {
return;
}
this.entriesNavigationOutlet.selectRightCard();
});
Mousetrap.bind('left', () => {
if (!this.hasEntriesNavigationOutlet) {
return;
}
this.entriesNavigationOutlet.selectLeftCard();
});
Mousetrap.bind('enter', () => {
if (!this.hasEntriesNavigationOutlet) {
return;
}
this.entriesNavigationOutlet.selectCurrentCard();
});
}
}

View File

@ -0,0 +1,7 @@
import { Controller } from '@hotwired/stimulus';
export default class extends Controller {
toggle() {
this.element.classList.toggle('entry-nav-top--sticky');
}
}

View File

@ -0,0 +1,12 @@
import { Controller } from '@hotwired/stimulus';
export default class extends Controller {
static targets = ['link', 'edit', 'form', 'input'];
showForm() {
this.formTarget.classList.remove('hidden');
this.editTarget.classList.add('hidden');
this.linkTarget.classList.add('hidden');
this.inputTarget.focus();
}
}

View File

@ -0,0 +1,31 @@
import { Controller } from '@hotwired/stimulus';
export default class extends Controller {
static targets = ['addUrl', 'addUrlInput', 'search', 'searchInput', 'actions'];
showAddUrl() {
this.actionsTarget.style.display = 'none';
this.addUrlTarget.style.display = 'flex';
this.searchTarget.style.display = 'none';
this.addUrlInputTarget.focus();
}
submittingUrl(e) {
e.currentTarget.disabled = true;
this.addUrlInputTarget.readOnly = true;
this.addUrlInputTarget.blur();
}
showSearch() {
this.actionsTarget.style.display = 'none';
this.addUrlTarget.style.display = 'none';
this.searchTarget.style.display = 'flex';
this.searchInputTarget.focus();
}
showActions() {
this.actionsTarget.style.display = 'flex';
this.addUrlTarget.style.display = 'none';
this.searchTarget.style.display = 'none';
}
}

View File

@ -1,18 +1,11 @@
import $ from 'jquery';
import './bootstrap';
/* Materialize imports */
import '@materializecss/materialize/dist/css/materialize.css';
import '@materializecss/materialize/dist/js/materialize';
/* Annotations */
import annotator from 'annotator';
import ClipboardJS from 'clipboard';
import 'mathjax/es5/tex-svg';
/* jrQrcode */
import jrQrcode from 'jr-qrcode';
/* Fonts */
import 'material-design-icons-iconfont/dist/material-design-icons.css';
import 'lato-font/css/lato-font.css';
@ -22,372 +15,5 @@ import '@fontsource/eb-garamond';
import '@fontsource/montserrat';
import '@fontsource/oswald';
/* Highlight */
import './js/highlight';
/* Tools */
import {
savePercent, retrievePercent, initExport, initFilters, initRandom, initPreviewText,
} from './js/tools';
/* Import shortcuts */
import './js/shortcuts/main';
import './js/shortcuts/entry';
/* Theme style */
import './scss/index.scss';
const mobileMaxWidth = 993;
/* ==========================================================================
Annotations & Remember position
========================================================================== */
$(document).ready(() => {
if ($('#article').length) {
const app = new annotator.App();
app.include(annotator.ui.main, {
element: document.querySelector('article'),
});
const authorization = {
permits() { return true; },
};
app.registry.registerUtility(authorization, 'authorizationPolicy');
const x = JSON.parse($('#annotationroutes').html());
app.include(annotator.storage.http, $.extend({}, x, {
onError(msg, xhr) {
if (!Object.prototype.hasOwnProperty.call(xhr, 'responseJSON')) {
annotator.notification.banner('An error occurred', 'error');
return;
}
$.each(xhr.responseJSON.children, (k, v) => {
if (v.errors) {
$.each(v.errors, (n, errorText) => {
annotator.notification.banner(errorText, 'error');
});
}
});
},
}));
app.start().then(() => {
app.annotations.load({ entry: x.entryId });
});
$(window).scroll(() => {
const scrollTop = $(window).scrollTop();
const docHeight = $(document).height();
const scrollPercent = (scrollTop) / (docHeight);
const scrollPercentRounded = Math.round(scrollPercent * 100) / 100;
savePercent(x.entryId, scrollPercentRounded);
});
retrievePercent(x.entryId);
$(window).resize(() => {
retrievePercent(x.entryId, true);
});
}
document.querySelectorAll('[data-handler=tag-rename]').forEach((item) => {
const current = item;
current.wallabag_edit_mode = false;
current.onclick = (event) => {
const target = event.currentTarget;
if (target.wallabag_edit_mode === false) {
$(target.parentNode.querySelector('[data-handle=tag-link]')).addClass('hidden');
$(target.parentNode.querySelector('[data-handle=tag-rename-form]')).removeClass('hidden');
target.parentNode.querySelector('[data-handle=tag-rename-form] input').focus();
target.querySelector('.material-icons').innerHTML = 'done';
target.wallabag_edit_mode = true;
} else {
target.parentNode.querySelector('[data-handle=tag-rename-form]').submit();
}
};
});
// mimic radio button because emailTwoFactor is a boolean
$('#update_user_googleTwoFactor').on('change', () => {
$('#update_user_emailTwoFactor').prop('checked', false);
});
$('#update_user_emailTwoFactor').on('change', () => {
$('#update_user_googleTwoFactor').prop('checked', false);
});
// same mimic for super admin
$('#user_googleTwoFactor').on('change', () => {
$('#user_emailTwoFactor').prop('checked', false);
});
$('#user_emailTwoFactor').on('change', () => {
$('#user_googleTwoFactor').prop('checked', false);
});
// handle copy to clipboard for developer stuff
const clipboard = new ClipboardJS('.btn');
clipboard.on('success', (e) => {
e.clearSelection();
});
});
(function darkTheme() {
const rootEl = document.querySelector('html');
const themeDom = {
darkClass: 'dark-theme',
toggleClass(el) {
return el.classList.toggle(this.darkClass);
},
addClass(el) {
return el.classList.add(this.darkClass);
},
removeClass(el) {
return el.classList.remove(this.darkClass);
},
};
const themeCookie = {
values: {
light: 'light',
dark: 'dark',
},
name: 'theme',
getValue(isDarkTheme) {
return isDarkTheme ? this.values.dark : this.values.light;
},
setCookie(isDarkTheme) {
const value = this.getValue(isDarkTheme);
document.cookie = `${this.name}=${value};samesite=Lax;path=/;max-age=31536000`;
},
removeCookie() {
document.cookie = `${this.name}=auto;samesite=Lax;path=/;max-age=0`;
},
exists() {
return document.cookie.split(';').some((cookie) => cookie.trim().startsWith(`${this.name}=`));
},
};
const preferedColorScheme = {
choose() {
const themeCookieExists = themeCookie.exists();
if (this.isAvailable() && !themeCookieExists) {
const isPreferedColorSchemeDark = window.matchMedia('(prefers-color-scheme: dark)').matches === true;
if (!themeCookieExists) {
themeDom[isPreferedColorSchemeDark ? 'addClass' : 'removeClass'](rootEl);
}
}
},
isAvailable() {
return typeof window.matchMedia === 'function';
},
init() {
if (!this.isAvailable()) {
return false;
}
this.choose();
window.matchMedia('(prefers-color-scheme: dark)').addListener(() => {
this.choose();
});
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();
addDarkThemeListeners();
}());
const stickyNav = () => {
const nav = $('.js-entry-nav-top');
$('[data-toggle="actions"]').click(() => {
nav.toggleClass('entry-nav-top--sticky');
});
};
const articleScroll = () => {
const articleEl = $('#article');
if (articleEl.length > 0) {
$(window).scroll(() => {
const s = $(window).scrollTop();
const d = $(document).height();
const c = $(window).height();
const articleElBottom = articleEl.offset().top + articleEl.height();
const scrollPercent = (s / (d - c)) * 100;
$('.progress .determinate').css('width', `${scrollPercent}%`);
const fixedActionBtn = $('.js-fixed-action-btn');
const toggleScrollDataName = 'toggle-auto';
if ((s + c) > articleElBottom) {
fixedActionBtn.data(toggleScrollDataName, true);
fixedActionBtn.openFAB();
} else if (fixedActionBtn.data(toggleScrollDataName) === true) {
fixedActionBtn.data(toggleScrollDataName, false);
fixedActionBtn.closeFAB();
}
});
}
};
$(document).ready(() => {
// sidenav
$('.sidenav').sidenav();
$('select').formSelect();
$('.collapsible[data-collapsible="accordion"]').collapsible();
$('.collapsible[data-collapsible="expandable"]').collapsible({
accordion: false,
});
$('.datepicker').datepicker({
selectMonths: true,
selectYears: 15,
formatSubmit: 'yyyy-mm-dd',
hiddenName: false,
format: 'yyyy-mm-dd',
container: 'body',
});
$('.dropdown-trigger').dropdown({ hover: false });
$('.dropdown-trigger[data-covertrigger="false"][data-constrainwidth="false"]').dropdown({
hover: false,
coverTrigger: false,
constrainWidth: false,
});
$('.tabs').tabs();
$('.tooltipped').tooltip();
initFilters();
initExport();
initRandom();
stickyNav();
articleScroll();
initPreviewText();
const toggleNav = (toShow, toFocus) => {
$('.nav-panel-actions').hide(100);
$(toShow).show(100);
$(toFocus).focus();
};
$('#nav-btn-add-tag').on('click', () => {
$('.nav-panel-add-tag').toggle(100);
$('.nav-panel-menu').addClass('hidden');
if (window.innerWidth < mobileMaxWidth) {
$('.sidenav').sidenav('close');
}
$('#tag_label').focus();
return false;
});
$('#nav-btn-add').on('click', () => {
toggleNav('.nav-panel-add', '#entry_url');
return false;
});
$('#config_fontsize').on('input', () => {
const value = $('#config_fontsize').val();
const css = `${value}em`;
$('#preview-content').css('font-size', css);
});
$('#config_font').on('change', () => {
const value = $('#config_font').val();
$('#preview-content').css('font-family', value);
});
$('#config_lineHeight').on('input', () => {
const value = $('#config_lineHeight').val();
const css = `${value}em`;
$('#preview-content').css('line-height', css);
});
$('#config_maxWidth').on('input', () => {
const value = $('#config_maxWidth').val();
const css = `${value}em`;
$('#preview-article').css('max-width', css);
});
const materialAddForm = $('.nav-panel-add');
materialAddForm.on('submit', () => {
materialAddForm.addClass('disabled');
$('input#entry_url', materialAddForm).prop('readonly', true).trigger('blur');
});
$('#nav-btn-search').on('click', () => {
toggleNav('.nav-panel-search', '#search_entry_term');
return false;
});
$('.close').on('click', (e) => {
$(e.target).parent('.nav-panel-item').hide(100);
$('.nav-panel-actions').show(100);
return false;
});
const mainCheckboxes = document.querySelectorAll('[data-js="checkboxes-toggle"]');
if (mainCheckboxes.length) {
[...mainCheckboxes].forEach((el) => {
el.addEventListener('click', () => {
const checkboxes = document.querySelectorAll(el.dataset.toggle);
[...checkboxes].forEach((checkbox) => {
const checkboxClone = checkbox;
checkboxClone.checked = el.checked;
});
});
});
}
$('form[name="form_mass_action"] input[name="tags"]').on('keydown', (e) => {
if (e.key === 'Enter') {
e.preventDefault();
$('form[name="form_mass_action"] button[name="tag"]').trigger('click');
}
});
document.querySelectorAll('img.jr-qrcode').forEach((qrcode) => {
const src = jrQrcode.getQrBase64(qrcode.getAttribute('data-url'));
qrcode.setAttribute('src', src);
});
});

View File

@ -1,8 +0,0 @@
import 'highlight.js/styles/atom-one-light.css';
import hljs from 'highlight.js';
window.addEventListener('load', () => {
document.querySelectorAll('pre').forEach((element) => {
hljs.highlightElement(element);
});
});

View File

@ -1,26 +0,0 @@
import Mousetrap from 'mousetrap';
import $ from 'jquery';
$(document).ready(() => {
if ($('#article').length > 0) {
/* open original article */
Mousetrap.bind('o', () => {
$('ul.sidenav a.original i')[0].click();
});
/* mark as favorite */
Mousetrap.bind('f', () => {
$('ul.sidenav a.favorite i')[0].click();
});
/* mark as read */
Mousetrap.bind('a', () => {
$('ul.sidenav a.markasread i')[0].click();
});
/* delete */
Mousetrap.bind('del', () => {
$('ul.sidenav a.delete i')[0].click();
});
}
});

View File

@ -1,104 +0,0 @@
import Mousetrap from 'mousetrap';
import $ from 'jquery';
/* Go to */
Mousetrap.bind('g u', () => { window.location.href = Routing.generate('homepage'); });
Mousetrap.bind('g s', () => { window.location.href = Routing.generate('starred'); });
Mousetrap.bind('g r', () => { window.location.href = Routing.generate('archive'); });
Mousetrap.bind('g a', () => { window.location.href = Routing.generate('all'); });
Mousetrap.bind('g t', () => { window.location.href = Routing.generate('tag'); });
Mousetrap.bind('g c', () => { window.location.href = Routing.generate('config'); });
Mousetrap.bind('g i', () => { window.location.href = Routing.generate('import'); });
Mousetrap.bind('g d', () => { window.location.href = Routing.generate('developer'); });
Mousetrap.bind('?', () => { window.location.href = Routing.generate('howto'); });
Mousetrap.bind('g l', () => { window.location.href = Routing.generate('fos_user_security_logout'); });
function toggleFocus(cardToToogleFocus) {
if (cardToToogleFocus) {
$(cardToToogleFocus).toggleClass('z-depth-4');
}
}
$(document).ready(() => {
const cards = $('#content').find('.card');
const cardNumber = cards.length;
let cardIndex = 0;
/* If we come from next page */
if (window.location.hash === '#prev') {
cardIndex = cardNumber - 1;
}
let card = cards[cardIndex];
const pagination = $('.pagination');
/* Show nothing on quickstart */
if ($('#content > div.quickstart').length > 0) {
return;
}
/* Show nothing on login/register page */
if ($('#username').length > 0 || $('#fos_user_registration_form_username').length > 0) {
return;
}
/* Show nothing on login/register page */
if ($('#username').length > 0 || $('#fos_user_registration_form_username').length > 0) {
return;
}
/* Focus current card */
toggleFocus(card);
/* Actions */
Mousetrap.bind('g n', () => {
$('#nav-btn-add').trigger('click');
return false;
});
Mousetrap.bind('s', () => {
$('#nav-btn-search').trigger('click');
return false;
});
Mousetrap.bind('esc', () => {
$('.close').trigger('click');
});
/* Select right card. If there's a next page, go to next page */
Mousetrap.bind('right', () => {
if (cardIndex >= 0 && cardIndex < cardNumber - 1) {
toggleFocus(card);
cardIndex += 1;
card = cards[cardIndex];
toggleFocus(card);
return;
}
if (pagination.length > 0 && pagination.find('li.next:not(.disabled)').length > 0 && cardIndex === cardNumber - 1) {
window.location.href = window.location.origin + $(pagination).find('li.next a').attr('href');
}
});
/* Select previous card. If there's a previous page, go to next page */
Mousetrap.bind('left', () => {
if (cardIndex > 0 && cardIndex < cardNumber) {
toggleFocus(card);
cardIndex -= 1;
card = cards[cardIndex];
toggleFocus(card);
return;
}
if (pagination.length > 0 && $(pagination).find('li.prev:not(.disabled)').length > 0 && cardIndex === 0) {
window.location.href = `${window.location.origin + $(pagination).find('li.prev a').attr('href')}#prev`;
}
});
Mousetrap.bind('enter', () => {
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

@ -1,83 +0,0 @@
import $ from 'jquery';
function supportsLocalStorage() {
try {
return 'localStorage' in window && window.localStorage !== null;
} catch (e) {
return false;
}
}
function savePercent(id, percent) {
if (!supportsLocalStorage()) { return false; }
localStorage[`wallabag.article.${id}.percent`] = percent;
return true;
}
function retrievePercent(id, resized) {
if (!supportsLocalStorage()) { return false; }
const bheight = $(document).height();
const percent = localStorage[`wallabag.article.${id}.percent`];
const scroll = bheight * percent;
if (!resized) {
$('html,body').animate({ scrollTop: scroll }, 'fast');
}
return true;
}
function initFilters() {
// no display if filters not available
if ($('div').is('#filters')) {
$('#button_filters').show();
$('#filters.sidenav').sidenav({ edge: 'right' });
$('#clear_form_filters').on('click', () => {
$('#filters input').val('');
$('#filters :checked').removeAttr('checked');
return false;
});
}
}
function initExport() {
// no display if export not available
if ($('div').is('#export')) {
$('#button_export').show();
$('#export.sidenav').sidenav({ edge: 'right' });
}
}
function initRandom() {
// no display if export (ie: entries) not available
if ($('div').is('#export')) {
$('#button_random').show();
}
}
function initPreviewText() {
// no display if preview_text not available
if ($('div').is('#preview-article')) {
const defaultFontFamily = $('#config_font').val();
const defaultFontSize = $('#config_fontsize').val();
const defaultLineHeight = $('#config_lineHeight').val();
const defaultMaxWidth = $('#config_maxWidth').val();
const previewContent = $('#preview-content');
previewContent.css('font-family', defaultFontFamily);
previewContent.css('font-size', `${defaultFontSize}em`);
previewContent.css('line-height', `${defaultLineHeight}em`);
$('#preview-article').css('max-width', `${defaultMaxWidth}em`);
}
}
export {
savePercent,
retrievePercent,
initExport,
initFilters,
initRandom,
initPreviewText,
};

View File

@ -154,6 +154,15 @@ a.original:not(.waves-effect) {
}
}
.card .card-content .card-title,
.card-stacked .card-content .card-title {
display: -webkit-box;
overflow: hidden;
text-overflow: ellipsis;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
.card-entry-labels li,
.card-tag-labels li {
margin: 10px 10px 10px auto;
@ -179,6 +188,7 @@ a.original:not(.waves-effect) {
.card-entry-tags a,
.card-entry-labels a,
.card-tag-labels a,
.card-tag-labels button,
.card-entry-labels-hidden a,
#list .chip a {
text-decoration: none;
@ -186,6 +196,14 @@ a.original:not(.waves-effect) {
color: #fff;
}
.card-tag-labels button {
background: transparent;
border: none;
font-weight: normal;
color: #fff;
cursor: pointer;
}
.card-tag-link {
width: calc(100% - 24px);
line-height: 1.3;
@ -196,6 +214,7 @@ a.original:not(.waves-effect) {
.card-tag-form {
display: flex;
align-items: center;
min-width: 100px;
flex-grow: 1;
}

View File

@ -63,7 +63,9 @@
.input-field input:focus,
.results-item,
.sidenav li > a,
.sidenav li > a > i.material-icons {
.sidenav li > a > i.material-icons,
.sidenav li button,
.sidenav li button > i.material-icons {
color: #dfdfdf;
}
@ -88,6 +90,7 @@
.mass-action-tags .mass-action-tags-input.mass-action-tags-input,
.sidenav li:not(.logo) > a:hover,
.sidenav li:not(.logo) button:hover,
.sidenav .collapsible-header:hover,
.sidenav.sidenav-fixed .collapsible-header:hover {
background-color: #1d1d1d;
@ -142,6 +145,12 @@
background-color: transparent;
}
.z-depth-4 {
box-shadow: 0 16px 24px 2px rgba(255 255 255 / 14%),
0 6px 30px 5px rgba(255 255 255 / 12%),
0 8px 10px -7px rgba(255 255 255 / 20%);
}
@media only screen and (min-width: 992px) {
#article {
background-color: #101010;

View File

@ -6,11 +6,32 @@ nav {
line-height: initial;
}
// adapted from anchor styles from node_modules/@materializecss/materialize/sass/components/_navbar.scss
nav ul button {
transition: background-color .3s;
font-size: 1rem;
color: #fff;
display: block;
padding: 0 15px;
cursor: pointer;
background: none;
border: 0;
&:focus {
background: none;
}
&:hover {
background-color: rgba(0 0 0 / 10%);
}
}
nav {
input {
color: #aaa;
}
ul button:hover,
ul a:hover {
background-color: initial;
}
@ -34,6 +55,7 @@ nav {
justify-content: space-between;
align-items: center;
button,
a {
padding: 10px 15px;
}
@ -143,14 +165,6 @@ nav {
margin: 0 1%;
}
.button-filters {
display: none;
}
.button-export {
display: none;
}
.entry-nav-top--sticky {
position: sticky;
top: 0;

View File

@ -12,6 +12,7 @@
background: initial;
}
& button > i.material-icons.theme-toggle-icon,
& > a > i.material-icons.theme-toggle-icon {
float: none;
margin-left: 0;
@ -22,6 +23,7 @@
margin: 0;
}
&.sidenav-fixed button,
&.sidenav-fixed a {
font-size: 13px;
line-height: 44px;
@ -41,7 +43,35 @@
}
}
.bold > a {
// adapted from anchor styles from node_modules/@materializecss/materialize/sass/components/_sidenav.scss
.sidenav li button {
color: rgba(0 0 0 / 87%);
display: block;
font-size: 14px;
font-weight: 500;
height: 48px;
line-height: 48px;
padding: 0 (16px * 2);
width: 100%;
text-align: left;
&:hover {
background-color: rgba(0 0 0 / 5%);
}
& > i,
& > i.material-icons {
float: left;
height: 48px;
line-height: 48px;
margin: 0 (16px * 2) 0 0;
width: 24px;
color: rgba(0 0 0 / 54%);
}
}
.bold > a,
.bold > button {
font-weight: bold;
}

View File

@ -1,3 +1,5 @@
@use "variables";
/* ==========================================================================
* Various
* ========================================================================== */
@ -38,3 +40,18 @@ nav .input-field input {
.tab {
flex: 1;
}
.btn-link {
background: none;
border: 0;
padding: 0;
color: variables.$blue-accent-color;
&:focus {
background: none;
}
}
.inline-block {
display: inline-block;
}

View File

@ -37,13 +37,11 @@ $config
'phpstan/phpstan-symfony',
'psr/http-client',
'psr/http-factory',
'rulerz-php/doctrine-orm',
'scheb/2fa-qr-code',
'rector/rector',
'scheb/2fa-trusted-device',
'shipmonk/composer-dependency-analyser',
'symfony/asset',
'symfony/css-selector',
'symfony/doctrine-bridge',
'symfony/google-mailer',
'symfony/intl',
'symfony/phpunit-bridge',
@ -64,10 +62,9 @@ $config
'symfony/web-profiler-bundle',
'symfony/web-server-bundle',
], [ErrorType::DEV_DEPENDENCY_IN_PROD])
->ignoreErrorsOnPackages([
'gedmo/doctrine-extensions',
], [ErrorType::SHADOW_DEPENDENCY])
;
if (\PHP_VERSION_ID >= 80000) {
$config->ignoreErrorsOnPackage('symfony/polyfill-php80', [ErrorType::UNUSED_DEPENDENCY]);
}
return $config;

View File

@ -38,7 +38,7 @@
"issues": "https://github.com/wallabag/wallabag/issues"
},
"require": {
"php": ">=7.4",
"php": ">=8.2",
"ext-ctype": "*",
"ext-curl": "*",
"ext-dom": "*",
@ -57,135 +57,146 @@
"ext-tidy": "*",
"ext-tokenizer": "*",
"ext-xml": "*",
"babdev/pagerfanta-bundle": "^3.8",
"babdev/pagerfanta-bundle": "^4.5",
"craue/config-bundle": "^2.7.0",
"defuse/php-encryption": "^2.4",
"doctrine/collections": "^1.8",
"doctrine/common": "^3.4.3",
"doctrine/dbal": "^3.8.2",
"doctrine/doctrine-bundle": "^2.11.3",
"doctrine/doctrine-migrations-bundle": "^3.3",
"doctrine/collections": "^2.3",
"doctrine/common": "^3.5.0",
"doctrine/dbal": "^3.9.4",
"doctrine/doctrine-bundle": "^2.13.2",
"doctrine/doctrine-migrations-bundle": "^3.4.1",
"doctrine/event-manager": "^1.2",
"doctrine/migrations": "^3.5.5",
"doctrine/orm": "^2.18.1",
"doctrine/persistence": "^3.2",
"egulias/email-validator": "^3.2.6",
"doctrine/migrations": "^3.8.2",
"doctrine/orm": "^2.20.2",
"doctrine/persistence": "^3.4",
"egulias/email-validator": "^4.0.4",
"enshrined/svg-sanitize": "^0.21",
"friendsofsymfony/jsrouting-bundle": "^2.8",
"friendsofsymfony/jsrouting-bundle": "^3.5",
"friendsofsymfony/oauth-server-bundle": "dev-master#dc8ff343363cf794d30eb1a123610d186a43f162",
"friendsofsymfony/rest-bundle": "^3.6",
"friendsofsymfony/user-bundle": "^3.2.1",
"guzzlehttp/psr7": "^2.6.2",
"html2text/html2text": "^4.3.1",
"friendsofsymfony/rest-bundle": "^3.8",
"friendsofsymfony/user-bundle": "^3.4.0",
"guzzlehttp/psr7": "^2.7.0",
"html2text/html2text": "^4.3.2",
"incenteev/composer-parameter-handler": "^2.2",
"j0k3r/graby": "^2.4.5",
"j0k3r/graby-site-config": "^1.0",
"j0k3r/graby": "^2.4.6",
"j0k3r/graby-site-config": "^1.0.197",
"javibravo/simpleue": "^2.1",
"jms/serializer": "^3.29.1",
"jms/serializer-bundle": "^5.4",
"laminas/laminas-code": "^4.7.1",
"jms/serializer": "^3.32.3",
"jms/serializer-bundle": "^5.5.1",
"laminas/laminas-code": "^4.16",
"lcobucci/jwt": "^4.3",
"league/html-to-markdown": "^5.1",
"league/html-to-markdown": "^5.1.1",
"mgargano/simplehtmldom": "^1.5",
"mnapoli/piwik-twig-extension": "^3.0",
"monolog/monolog": "^2.9",
"nelmio/api-doc-bundle": "^4.20.0",
"nelmio/cors-bundle": "^2.4",
"monolog/monolog": "^2.10",
"nelmio/api-doc-bundle": "^4.38.1",
"nelmio/cors-bundle": "^2.5",
"ocramius/proxy-manager": "^2.1.1",
"pagerfanta/core": "^3.8",
"pagerfanta/doctrine-orm-adapter": "^3.8",
"pagerfanta/twig": "^3.8",
"php-amqplib/php-amqplib": "^3.6.1",
"php-amqplib/rabbitmq-bundle": "^2.14.0",
"pagerfanta/doctrine-orm-adapter": "^4.7",
"pagerfanta/twig": "^4.7",
"php-amqplib/php-amqplib": "^3.7.3",
"php-amqplib/rabbitmq-bundle": "^2.17.3",
"pragmarx/recovery": "^0.2.1",
"predis/predis": "^2.2.2",
"predis/predis": "^2.3.0",
"psr/http-client": "^1.0.3",
"psr/http-factory": "^1.0.2",
"psr/http-factory": "^1.1.0",
"psr/http-message": "^2.0",
"psr/log": "^1.1.4",
"rulerz-php/doctrine-orm": "dev-master",
"scheb/2fa-backup-code": "^5.13.2",
"scheb/2fa-bundle": "^5.13.2",
"scheb/2fa-email": "^5.13.2",
"scheb/2fa-google-authenticator": "^5.13.2",
"scheb/2fa-qr-code": "^5.13.2",
"scheb/2fa-trusted-device": "^5.13.2",
"scssphp/scssphp": "^1.12.1",
"scssphp/scssphp": "^2.0.1",
"sensio/framework-extra-bundle": "^6.2.10",
"sentry/sentry-symfony": "^5.0.1",
"spiriitlabs/form-filter-bundle": "^10.0",
"stof/doctrine-extensions-bundle": "^1.11.0",
"symfony/asset": "^5.4.35",
"symfony/browser-kit": "^5.4.35",
"symfony/config": "^5.4.35",
"symfony/console": "^5.4.35",
"symfony/dependency-injection": "^5.4.35",
"symfony/doctrine-bridge": "^5.4.35",
"symfony/dom-crawler": "^5.4.35",
"symfony/error-handler": "^5.4.35",
"symfony/event-dispatcher": "^5.4.35",
"symfony/event-dispatcher-contracts": "^2.5.2",
"symfony/expression-language": "^5.4.35",
"symfony/filesystem": "^5.4",
"symfony/finder": "^5.4.35",
"symfony/form": "^5.4.35",
"symfony/framework-bundle": "^5.4.35",
"symfony/google-mailer": "^5.4.35",
"symfony/http-client": "^5.4.35",
"symfony/http-client-contracts": "^2.5",
"symfony/http-foundation": "^5.4.35",
"symfony/http-kernel": "^5.4.35",
"symfony/intl": "^5.4.35",
"symfony/mailer": "^5.4.35",
"symfony/mime": "^5.4.35",
"sentry/sentry-symfony": "^5.2.0",
"spiriitlabs/form-filter-bundle": "^10.0.2",
"stof/doctrine-extensions-bundle": "^1.13.0",
"symfony/asset": "^5.4.45",
"symfony/browser-kit": "^5.4.45",
"symfony/config": "^5.4.46",
"symfony/console": "^5.4.47",
"symfony/dependency-injection": "^5.4.48",
"symfony/doctrine-bridge": "^5.4.48",
"symfony/dom-crawler": "^5.4.48",
"symfony/error-handler": "^5.4.46",
"symfony/event-dispatcher": "^5.4.45",
"symfony/event-dispatcher-contracts": "^2.5.4",
"symfony/expression-language": "^5.4.45",
"symfony/filesystem": "^5.4.45",
"symfony/finder": "^5.4.45",
"symfony/form": "^5.4.45",
"symfony/framework-bundle": "^5.4.45",
"symfony/google-mailer": "^5.4.45",
"symfony/http-client": "^5.4.49",
"symfony/http-client-contracts": "^2.5.5",
"symfony/http-foundation": "^5.4.48",
"symfony/http-kernel": "^5.4.48",
"symfony/intl": "^5.4.47",
"symfony/mailer": "^5.4.45",
"symfony/mime": "^5.4.45",
"symfony/monolog-bundle": "^3.10",
"symfony/options-resolver": "^5.4.21",
"symfony/polyfill-php80": "^1.29",
"symfony/proxy-manager-bridge": "^5.4.21",
"symfony/routing": "^5.4.35",
"symfony/security-bundle": "^5.4.35",
"symfony/security-core": "^5.4.35",
"symfony/security-http": "^5.4.35",
"symfony/templating": "^5.4.35",
"symfony/translation-contracts": "^2.5.2",
"symfony/twig-bundle": "^5.4.35",
"symfony/validator": "^5.4.35",
"symfony/webpack-encore-bundle": "^1.17",
"tecnickcom/tcpdf": "^6.6.5",
"twig/extra-bundle": "^3.8",
"twig/string-extra": "^3.8",
"twig/twig": "^3.8.0",
"symfony/options-resolver": "^5.4.45",
"symfony/proxy-manager-bridge": "^5.4.45",
"symfony/routing": "^5.4.48",
"symfony/security-bundle": "^5.4.45",
"symfony/security-core": "^5.4.48",
"symfony/security-http": "^5.4.47",
"symfony/templating": "^5.4.45",
"symfony/translation-contracts": "^2.5.4",
"symfony/twig-bundle": "^5.4.45",
"symfony/validator": "^5.4.48",
"symfony/webpack-encore-bundle": "^1.17.2",
"tecnickcom/tcpdf": "^6.8.2",
"twig/extra-bundle": "^3.20",
"twig/string-extra": "^3.20",
"twig/twig": "^3.20.0",
"wallabag/phpepub": "^4.0.10",
"wallabag/rulerz": "dev-master",
"wallabag/rulerz-bundle": "dev-master",
"willdurand/hateoas": "^3.10",
"willdurand/hateoas-bundle": "^2.6"
"willdurand/hateoas": "^3.12",
"willdurand/hateoas-bundle": "^2.7"
},
"require-dev": {
"dama/doctrine-test-bundle": "^8.0.2",
"doctrine/data-fixtures": "^1.7",
"doctrine/doctrine-fixtures-bundle": "^3.5.1",
"ergebnis/composer-normalize": "^2.42.0",
"friendsofphp/php-cs-fixer": "^3.49",
"friendsoftwig/twigcs": "^6.1",
"dama/doctrine-test-bundle": "^8.2.2",
"doctrine/data-fixtures": "^2.0.2",
"doctrine/doctrine-fixtures-bundle": "^3.7.1",
"ergebnis/composer-normalize": "^2.45.0",
"friendsofphp/php-cs-fixer": "^3.70.2",
"friendsoftwig/twigcs": "^6.5",
"m6web/redis-mock": "^5.6",
"php-http/mock-client": "^1.6",
"phpstan/extension-installer": "^1.3.1",
"phpstan/phpstan": "^1.10.59",
"phpstan/phpstan-doctrine": "^1.3.62",
"phpstan/phpstan-phpunit": "^1.3.16",
"phpstan/phpstan-symfony": "^1.3.7",
"phpunit/phpunit": "^9.6.17",
"shipmonk/composer-dependency-analyser": "^1.7",
"symfony/css-selector": "^5.4.35",
"symfony/debug-bundle": "^5.4.35",
"symfony/maker-bundle": "^1.43",
"symfony/phpunit-bridge": "^7.0.3",
"symfony/process": "^5.4",
"symfony/var-dumper": "^5.4.35",
"symfony/web-profiler-bundle": "^5.4.35",
"php-http/mock-client": "^1.6.1",
"phpstan/extension-installer": "^1.4.3",
"phpstan/phpstan": "^1.12.20",
"phpstan/phpstan-doctrine": "^1.5.7",
"phpstan/phpstan-phpunit": "^1.4.2",
"phpstan/phpstan-symfony": "^1.4.13",
"phpunit/phpunit": "^9.6.22",
"rector/rector": "^1.2",
"shipmonk/composer-dependency-analyser": "^1.8.2",
"symfony/css-selector": "^5.4.45",
"symfony/debug-bundle": "^5.4.45",
"symfony/maker-bundle": "^1.50",
"symfony/phpunit-bridge": "^7.2.0",
"symfony/process": "^5.4.47",
"symfony/var-dumper": "^5.4.48",
"symfony/web-profiler-bundle": "^5.4.48",
"symfony/web-server-bundle": "^4.4.44"
},
"replace": {
"symfony/polyfill-php54": "*",
"symfony/polyfill-php55": "*",
"symfony/polyfill-php56": "*",
"symfony/polyfill-php70": "*",
"symfony/polyfill-php71": "*",
"symfony/polyfill-php72": "*",
"symfony/polyfill-php73": "*",
"symfony/polyfill-php74": "*",
"symfony/polyfill-php80": "*",
"symfony/polyfill-php81": "*",
"symfony/polyfill-php82": "*"
},
"suggest": {
"ext-imagick": "To keep GIF animation when downloading image is enabled"
},
@ -216,9 +227,6 @@
"phpstan/extension-installer": true
},
"bin-dir": "bin",
"platform": {
"php": "7.4.29"
},
"sort-packages": true
},
"extra": {

2878
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
FROM php:8.1-fpm AS rootless
FROM php:8.2-fpm AS rootless
ARG DEBIAN_FRONTEND=noninteractive
ARG NODE_VERSION=20
@ -50,14 +50,13 @@ RUN docker-php-ext-install -j "$(nproc)" \
tidy \
zip
RUN pecl install redis; \
pecl install imagick; \
pecl install xdebug-3.1.6; \
docker-php-ext-enable \
RUN pecl install redis-6.1.0 \
&& pecl install imagick-3.7.0 \
&& pecl install xdebug-3.4.1 \
&& docker-php-ext-enable \
redis \
imagick \
xdebug \
;
xdebug
RUN version=$(php -r "echo PHP_MAJOR_VERSION.PHP_MINOR_VERSION;") \
&& architecture=$(uname -m) \

View File

@ -7,7 +7,7 @@ parameters:
database_password: ${DATABASE_PASSWORD:-~}
database_path: ${DATABASE_PATH:-"%kernel.project_dir%/data/db/wallabag.sqlite"}
database_table_prefix: ${DATABASE_TABLE_PREFIX:-wallabag_}
database_socket: null
database_socket: ${DATABASE_SOCKET:-~}
database_charset: ${DATABASE_CHARSET:-utf8}
domain_name: ${DOMAIN_NAME:-https://www.example.com}
@ -27,22 +27,20 @@ parameters:
fosuser_registration: ${FOSUSER_REGISTRATION:-false}
fosuser_confirmation: ${FOSUSER_CONFIRMATION:-true}
fos_oauth_server_access_token_lifetime: 3600
fos_oauth_server_refresh_token_lifetime: 1209600
fos_oauth_server_access_token_lifetime: ${FOS_OAUTH_SERVER_ACCESS_TOKEN_LIFETIME:-3600}
fos_oauth_server_refresh_token_lifetime: ${FOS_OAUTH_SERVER_REFRESH_TOKEN_LIFETIME:-1209600}
from_email: ${FROM_EMAIL:-wallabag@example.com}
rss_limit: 50
# RabbitMQ processing
rabbitmq_host: ${RABBITMQ_HOST:-rabbitmq}
rabbitmq_port: ${RABBITMQ_PORT:-5672}
rabbitmq_user: ${RABBITMQ_USER:-guest}
rabbitmq_password: ${RABBITMQ_PASSWORD:-guest}
rabbitmq_prefetch_count: 10
rabbitmq_prefetch_count: ${RABBITMQ_PREFETCH_COUNT:-10}
# Redis processing
redis_scheme: ${REDIS_SCHEME:-tcp}
redis_scheme: ${REDIS_SCHEME:-redis}
redis_host: ${REDIS_HOST:-redis}
redis_port: ${REDIS_PORT:-6379}
redis_path: ${REDIS_PATH:-~}

View File

@ -5,8 +5,8 @@ DATABASE_NAME=symfony
DATABASE_USER=root
DATABASE_PASSWORD=~
DATABASE_PATH='"%kernel.project_dir%/data/db/wallabag.sqlite"'
DOMAIN_NAME=http://localhost:8000
DOMAIN_NAME=http://127.0.0.1:8000
SECRET=ch4n63m31fy0uc4n
PHP_SESSION_SAVE_PATH=tcp://redis:6379?database=2
PHP_SESSION_SAVE_PATH=redis://redis:6379?database=2
PHP_SESSION_HANDLER=redis
TRUSTED_PROXIES=0.0.0.0/0

View File

@ -43,7 +43,7 @@ class AnnotationFixtures extends Fixture implements DependentFixtureInterface
$manager->flush();
}
public function getDependencies()
public function getDependencies(): array
{
return [
EntryFixtures::class,

View File

@ -55,7 +55,7 @@ class ConfigFixtures extends Fixture implements DependentFixtureInterface
$manager->flush();
}
public function getDependencies()
public function getDependencies(): array
{
return [
UserFixtures::class,

View File

@ -155,7 +155,7 @@ class EntryFixtures extends Fixture implements DependentFixtureInterface
$manager->flush();
}
public function getDependencies()
public function getDependencies(): array
{
return [
UserFixtures::class,

View File

@ -8,11 +8,9 @@ use Wallabag\Entity\IgnoreOriginInstanceRule;
class IgnoreOriginInstanceRuleFixtures extends Fixture
{
private array $defaultIgnoreOriginInstanceRules;
public function __construct(array $defaultIgnoreOriginInstanceRules)
{
$this->defaultIgnoreOriginInstanceRules = $defaultIgnoreOriginInstanceRules;
public function __construct(
private readonly array $defaultIgnoreOriginInstanceRules,
) {
}
public function load(ObjectManager $manager): void

View File

@ -21,7 +21,7 @@ class IgnoreOriginUserRuleFixtures extends Fixture implements DependentFixtureIn
$manager->flush();
}
public function getDependencies()
public function getDependencies(): array
{
return [
UserFixtures::class,

View File

@ -8,11 +8,9 @@ use Wallabag\Entity\InternalSetting;
class InternalSettingFixtures extends Fixture
{
private array $defaultInternalSettings;
public function __construct(array $defaultInternalSettings)
{
$this->defaultInternalSettings = $defaultInternalSettings;
public function __construct(
private readonly array $defaultInternalSettings,
) {
}
public function load(ObjectManager $manager): void

View File

@ -11,11 +11,9 @@ use Wallabag\Helper\CryptoProxy;
class SiteCredentialFixtures extends Fixture implements DependentFixtureInterface
{
private CryptoProxy $cryptoProxy;
public function __construct(CryptoProxy $cryptoProxy)
{
$this->cryptoProxy = $cryptoProxy;
public function __construct(
private readonly CryptoProxy $cryptoProxy,
) {
}
public function load(ObjectManager $manager): void
@ -37,7 +35,7 @@ class SiteCredentialFixtures extends Fixture implements DependentFixtureInterfac
$manager->flush();
}
public function getDependencies()
public function getDependencies(): array
{
return [
UserFixtures::class,

View File

@ -58,7 +58,7 @@ class TaggingRuleFixtures extends Fixture implements DependentFixtureInterface
$manager->flush();
}
public function getDependencies()
public function getDependencies(): array
{
return [
ConfigFixtures::class,

View File

@ -27,7 +27,7 @@ class Version20161001072726 extends WallabagMigration
// remove all FK from entry_tag
switch (true) {
case $platform instanceof MySQLPlatform:
$query = $this->connection->query("
$query = $this->connection->executeQuery("
SELECT CONSTRAINT_NAME
FROM information_schema.key_column_usage
WHERE TABLE_NAME = '" . $this->getTable('entry_tag', WallabagMigration::UN_ESCAPED_TABLE) . "' AND CONSTRAINT_NAME LIKE 'FK_%'
@ -40,7 +40,7 @@ class Version20161001072726 extends WallabagMigration
break;
case $platform instanceof PostgreSQLPlatform:
// http://dba.stackexchange.com/questions/36979/retrieving-all-pk-and-fk
$query = $this->connection->query("
$query = $this->connection->executeQuery("
SELECT conrelid::regclass AS table_from
,conname
,pg_get_constraintdef(c.oid)
@ -64,7 +64,7 @@ class Version20161001072726 extends WallabagMigration
switch (true) {
case $platform instanceof MySQLPlatform:
$query = $this->connection->query("
$query = $this->connection->executeQuery("
SELECT CONSTRAINT_NAME
FROM information_schema.key_column_usage
WHERE TABLE_NAME = '" . $this->getTable('annotation', WallabagMigration::UN_ESCAPED_TABLE) . "'
@ -79,7 +79,7 @@ class Version20161001072726 extends WallabagMigration
break;
case $platform instanceof PostgreSQLPlatform:
// http://dba.stackexchange.com/questions/36979/retrieving-all-pk-and-fk
$query = $this->connection->query("
$query = $this->connection->executeQuery("
SELECT conrelid::regclass AS table_from
,conname
,pg_get_constraintdef(c.oid)

View File

@ -20,7 +20,7 @@ class Version20170719231144 extends WallabagMigration
}
// Find tags which need to be merged
$dupTags = $this->connection->query('
$dupTags = $this->connection->executeQuery('
SELECT LOWER(label) AS lower_label
FROM ' . $this->getTable('tag') . '
GROUP BY LOWER(label)
@ -31,7 +31,7 @@ class Version20170719231144 extends WallabagMigration
$label = $duplicates['lower_label'];
// Retrieve all duplicate tags for a given tag
$tags = $this->connection->query('
$tags = $this->connection->executeQuery('
SELECT id
FROM ' . $this->getTable('tag') . '
WHERE LOWER(label) = :label

View File

@ -50,7 +50,7 @@ final class Version20190826204730 extends WallabagMigration
->fetchOne('SELECT * FROM ' . $this->getTable('ignore_origin_instance_rule') . " WHERE rule = '" . $entity['rule'] . "'");
if (false === $previous_rule) {
$this->addSql('INSERT INTO ' . $this->getTable('ignore_origin_instance_rule') . " (rule) VALUES ('" . $entity['rule'] . "');");
$this->connection->executeQuery('INSERT INTO ' . $this->getTable('ignore_origin_instance_rule') . " (rule) VALUES ('" . $entity['rule'] . "');");
}
}
}

View File

@ -0,0 +1,106 @@
<?php
declare(strict_types=1);
namespace Application\Migrations;
use Doctrine\DBAL\Schema\Schema;
use Wallabag\Doctrine\WallabagMigration;
/**
* Add setting to enable or disable each importer.
*/
final class Version20250526113708 extends WallabagMigration
{
private $settings = [
[
'name' => 'pocket_enabled',
'value' => '1',
'section' => 'import',
],
[
'name' => 'wallabag_v1_enabled',
'value' => '1',
'section' => 'import',
],
[
'name' => 'wallabag_v2_enabled',
'value' => '1',
'section' => 'import',
],
[
'name' => 'elcura_enabled',
'value' => '1',
'section' => 'import',
],
[
'name' => 'readability_enabled',
'value' => '1',
'section' => 'import',
],
[
'name' => 'instapaper_enabled',
'value' => '1',
'section' => 'import',
],
[
'name' => 'pinboard_enabled',
'value' => '1',
'section' => 'import',
],
[
'name' => 'delicious_enabled',
'value' => '1',
'section' => 'import',
],
[
'name' => 'omnivore_enabled',
'value' => '1',
'section' => 'import',
],
[
'name' => 'firefox_enabled',
'value' => '1',
'section' => 'import',
],
[
'name' => 'chrome_enabled',
'value' => '1',
'section' => 'import',
],
[
'name' => 'shaarli_enabled',
'value' => '1',
'section' => 'import',
],
[
'name' => 'pocket_html_enabled',
'value' => '1',
'section' => 'import',
],
[
'name' => 'elcurator_enabled',
'value' => '1',
'section' => 'import',
],
];
public function up(Schema $schema): void
{
foreach ($this->settings as $setting) {
$settingEnabled = $this->connection
->fetchOne('SELECT * FROM ' . $this->getTable('internal_setting') . " WHERE name = '" . $setting['name'] . "'");
if (false !== $settingEnabled) {
continue;
}
$this->addSql('INSERT INTO ' . $this->getTable('internal_setting') . " (name, value, section) VALUES ('" . $setting['name'] . "', '" . $setting['value'] . "', '" . $setting['section'] . "');");
}
}
public function down(Schema $schema): void
{
$this->skipIf(true, 'These settings are required and should not be removed.');
}
}

View File

@ -41,53 +41,53 @@
"url": "https://github.com/wallabag/wallabag/issues"
},
"devDependencies": {
"@babel/core": "^7.26.9",
"@babel/eslint-parser": "^7.26.8",
"@babel/preset-env": "^7.26.9",
"@symfony/webpack-encore": "^5.0.1",
"autoprefixer": "^10.4.20",
"babel-loader": "^9.2.1",
"core-js": "^3.23.0",
"@babel/core": "^7.27.1",
"@babel/eslint-parser": "^7.27.1",
"@babel/preset-env": "^7.27.2",
"@symfony/webpack-encore": "^5.1.0",
"autoprefixer": "^10.4.21",
"babel-loader": "^10.0.0",
"core-js": "^3.42.0",
"css-loader": "^7.1.2",
"eslint": "^8.57.1",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-plugin-import": "^2.31.0",
"eslint-webpack-plugin": "^4.2.0",
"eslint-webpack-plugin": "^5.0.1",
"file-loader": "^6.2.0",
"lato-font": "^3.0.0",
"mini-css-extract-plugin": "^2.9.2",
"postcss": "^8.5.2",
"postcss": "^8.5.3",
"postcss-loader": "^8.1.1",
"postcss-scss": "^4.0.9",
"regenerator-runtime": "^0.14.1",
"sass-embedded": "^1.85.0",
"sass-embedded": "^1.89.0",
"sass-loader": "^16.0.5",
"style-loader": "^4.0.0",
"stylelint": "^15.11.0",
"stylelint-config-standard": "^34.0.0",
"stylelint-config-standard-scss": "^11.1.0",
"stylelint-scss": "^5.3.2",
"terser-webpack-plugin": "^5.3.11",
"terser-webpack-plugin": "^5.3.14",
"url-loader": "^4.1.1",
"webpack": "^5.98.0",
"webpack": "^5.99.9",
"webpack-cli": "^5.1.4",
"webpack-manifest-plugin": "^5.0.0",
"webpack-manifest-plugin": "^5.0.1",
"webpack-merge": "^6.0.1",
"webpack-notifier": "^1.15.0"
},
"dependencies": {
"@fontsource/atkinson-hyperlegible": "^5.1.1",
"@fontsource/eb-garamond": "^5.1.2",
"@fontsource/montserrat": "^5.1.1",
"@fontsource/oswald": "^5.1.1",
"@fontsource/atkinson-hyperlegible": "^5.2.5",
"@fontsource/eb-garamond": "^5.2.5",
"@fontsource/montserrat": "^5.2.5",
"@fontsource/oswald": "^5.2.5",
"@hotwired/stimulus": "^3.2.2",
"@materializecss/materialize": "^1.2.2",
"@symfony/stimulus-bridge": "^4.0.1",
"annotator": "wallabag/annotator#master",
"clipboard": "^2.0.11",
"hammerjs": "^2.0.8",
"highlight.js": "^11.11.1",
"icomoon-free-npm": "^0.0.0",
"jquery": "^3.7.1",
"jquery.cookie": "^1.4.1",
"jr-qrcode": "^1.2.1",
"material-design-icons-iconfont": "^6.7.0",
"mathjax": "^3.2.2",
@ -100,7 +100,7 @@
"build:dev": "encore dev",
"watch": "encore dev --watch",
"build:prod": "encore production --progress",
"lint:js": "eslint assets/*.js assets/js/*.js assets/js/**/*.js",
"lint:js": "eslint assets/*.js assets/controllers/*.js",
"lint:scss": "stylelint assets/scss/*.scss assets/scss/**/*.scss"
}
}

View File

@ -1,76 +1,6 @@
parameters:
ignoreErrors:
-
message: "#^Method Wallabag\\\\Controller\\\\AnnotationController\\:\\:postAnnotationAction\\(\\) should return Symfony\\\\Component\\\\HttpFoundation\\\\JsonResponse but returns Symfony\\\\Component\\\\Form\\\\FormInterface\\<mixed\\>\\.$#"
message: "#^Strict comparison using \\=\\=\\= between null and string will always evaluate to false\\.$#"
count: 1
path: src/Controller/AnnotationController.php
-
message: "#^Method Wallabag\\\\Controller\\\\AnnotationController\\:\\:putAnnotationAction\\(\\) should return Symfony\\\\Component\\\\HttpFoundation\\\\JsonResponse but returns Symfony\\\\Component\\\\Form\\\\FormInterface\\<null\\>\\.$#"
count: 1
path: src/Controller/AnnotationController.php
-
message: "#^Call to an undefined method Wallabag\\\\Entity\\\\RuleInterface\\:\\:getConfig\\(\\)\\.$#"
count: 1
path: src/Controller/ConfigController.php
-
message: "#^Method FOS\\\\UserBundle\\\\Model\\\\UserManagerInterface\\:\\:updateUser\\(\\) invoked with 2 parameters, 1 required\\.$#"
count: 6
path: src/Controller/ConfigController.php
-
message: "#^Call to an undefined method Wallabag\\\\Import\\\\ImportInterface\\:\\:setFilepath\\(\\)\\.$#"
count: 1
path: src/Controller/Import/BrowserController.php
-
message: "#^Call to an undefined method Wallabag\\\\Import\\\\ImportInterface\\:\\:setUser\\(\\)\\.$#"
count: 1
path: src/Controller/Import/BrowserController.php
-
message: "#^Call to an undefined method Wallabag\\\\Import\\\\ImportInterface\\:\\:setFilepath\\(\\)\\.$#"
count: 1
path: src/Controller/Import/HtmlController.php
-
message: "#^Call to an undefined method Wallabag\\\\Import\\\\ImportInterface\\:\\:setUser\\(\\)\\.$#"
count: 1
path: src/Controller/Import/HtmlController.php
-
message: "#^Call to an undefined method Wallabag\\\\Import\\\\ImportInterface\\:\\:setFilepath\\(\\)\\.$#"
count: 1
path: src/Controller/Import/WallabagController.php
-
message: "#^Call to an undefined method Wallabag\\\\Import\\\\ImportInterface\\:\\:setUser\\(\\)\\.$#"
count: 1
path: src/Controller/Import/WallabagController.php
-
message: "#^Call to an undefined method Spiriit\\\\Bundle\\\\FormFilterBundle\\\\Filter\\\\Query\\\\QueryInterface\\:\\:getExpressionBuilder\\(\\)\\.$#"
count: 1
path: src/Event/Subscriber/CustomDoctrineORMSubscriber.php
-
message: "#^Call to an undefined method Spiriit\\\\Bundle\\\\FormFilterBundle\\\\Filter\\\\Query\\\\QueryInterface\\:\\:getExpr\\(\\)\\.$#"
count: 10
path: src/Form/Type/EntryFilterType.php
-
message: "#^Call to an undefined method Scheb\\\\TwoFactorBundle\\\\Model\\\\Email\\\\TwoFactorInterface\\:\\:getName\\(\\)\\.$#"
count: 2
path: src/Mailer/AuthCodeMailer.php
-
message: "#^PHPDoc type Symfony\\\\Component\\\\Mailer\\\\MailerInterface of property Wallabag\\\\Mailer\\\\UserMailer\\:\\:\\$mailer is not covariant with PHPDoc type Swift_Mailer of overridden property FOS\\\\UserBundle\\\\Mailer\\\\TwigSwiftMailer\\:\\:\\$mailer\\.$#"
count: 1
path: src/Mailer/UserMailer.php
-
message: "#^Call to an undefined method DOMNode\\:\\:getAttribute\\(\\)\\.$#"
count: 1
path: tests/Controller/FeedControllerTest.php
path: src/ParamConverter/UsernameFeedTokenConverter.php

View File

@ -2,7 +2,7 @@ includes:
- phpstan-baseline.neon
parameters:
level: 3
level: 5
paths:
- src
- tests

28
rector.php Normal file
View File

@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
use Rector\Config\RectorConfig;
use Rector\Php80\Rector\Class_\ClassPropertyAssignToConstructorPromotionRector;
return RectorConfig::configure()
->withPaths([
__DIR__ . '/app',
__DIR__ . '/fixtures',
__DIR__ . '/src',
__DIR__ . '/tests',
__DIR__ . '/web',
])
->withRootFiles()
->withImportNames(importShortClasses: false)
->withAttributesSets(symfony: true, doctrine: true, gedmo: true, jms: true, sensiolabs: true)
->withConfiguredRule(ClassPropertyAssignToConstructorPromotionRector::class, [
'inline_public' => true,
])
->withSkip([
ClassPropertyAssignToConstructorPromotionRector::class => [
__DIR__ . '/src/Entity/*',
],
])
->withPhpSets()
->withTypeCoverageLevel(0);

View File

@ -16,14 +16,10 @@ class CleanDownloadedImagesCommand extends Command
protected static $defaultName = 'wallabag:clean-downloaded-images';
protected static $defaultDescription = 'Cleans downloaded images which are no more associated to an entry';
private EntryRepository $entryRepository;
private DownloadImages $downloadImages;
public function __construct(EntryRepository $entryRepository, DownloadImages $downloadImages)
{
$this->entryRepository = $entryRepository;
$this->downloadImages = $downloadImages;
public function __construct(
private readonly EntryRepository $entryRepository,
private readonly DownloadImages $downloadImages,
) {
parent::__construct();
}

View File

@ -21,16 +21,12 @@ class CleanDuplicatesCommand extends Command
protected SymfonyStyle $io;
protected int $duplicates = 0;
private EntityManagerInterface $entityManager;
private EntryRepository $entryRepository;
private UserRepository $userRepository;
public function __construct(EntityManagerInterface $entityManager, EntryRepository $entryRepository, UserRepository $userRepository)
{
$this->entityManager = $entityManager;
$this->entryRepository = $entryRepository;
$this->userRepository = $userRepository;
public function __construct(
private readonly EntityManagerInterface $entityManager,
private readonly EntryRepository $entryRepository,
private readonly UserRepository $userRepository,
) {
parent::__construct();
}
@ -55,7 +51,7 @@ class CleanDuplicatesCommand extends Command
try {
$user = $this->getUser($username);
$this->cleanDuplicates($user);
} catch (NoResultException $e) {
} catch (NoResultException) {
$this->io->error(\sprintf('User "%s" not found.', $username));
return 1;
@ -104,8 +100,8 @@ class CleanDuplicatesCommand extends Command
private function similarUrl($url)
{
if (\in_array(substr($url, -1), ['/', '#'], true)) { // get rid of "/" and "#" and the end of urls
return substr($url, 0, \strlen($url));
if (\in_array(substr((string) $url, -1), ['/', '#'], true)) { // get rid of "/" and "#" and the end of urls
return substr((string) $url, 0, \strlen((string) $url));
}
return $url;

View File

@ -17,18 +17,12 @@ class ExportCommand extends Command
protected static $defaultName = 'wallabag:export';
protected static $defaultDescription = 'Export all entries for an user';
private EntryRepository $entryRepository;
private UserRepository $userRepository;
private EntriesExport $entriesExport;
private string $projectDir;
public function __construct(EntryRepository $entryRepository, UserRepository $userRepository, EntriesExport $entriesExport, string $projectDir)
{
$this->entryRepository = $entryRepository;
$this->userRepository = $userRepository;
$this->entriesExport = $entriesExport;
$this->projectDir = $projectDir;
public function __construct(
private readonly EntryRepository $entryRepository,
private readonly UserRepository $userRepository,
private readonly EntriesExport $entriesExport,
private readonly string $projectDir,
) {
parent::__construct();
}

View File

@ -19,16 +19,12 @@ class GenerateUrlHashesCommand extends Command
protected static $defaultDescription = 'Generates hashed urls for each entry';
protected OutputInterface $output;
private EntityManagerInterface $entityManager;
private EntryRepository $entryRepository;
private UserRepository $userRepository;
public function __construct(EntityManagerInterface $entityManager, EntryRepository $entryRepository, UserRepository $userRepository)
{
$this->entityManager = $entityManager;
$this->entryRepository = $entryRepository;
$this->userRepository = $userRepository;
public function __construct(
private readonly EntityManagerInterface $entityManager,
private readonly EntryRepository $entryRepository,
private readonly UserRepository $userRepository,
) {
parent::__construct();
}
@ -49,7 +45,7 @@ class GenerateUrlHashesCommand extends Command
try {
$user = $this->getUser($username);
$this->generateHashedUrls($user);
} catch (NoResultException $e) {
} catch (NoResultException) {
$output->writeln(\sprintf('<error>User "%s" not found.</error>', $username));
return 1;

View File

@ -33,55 +33,23 @@ class ImportCommand extends Command
protected static $defaultName = 'wallabag:import';
protected static $defaultDescription = 'Import entries from a JSON export';
private EntityManagerInterface $entityManager;
private TokenStorageInterface $tokenStorage;
private UserRepository $userRepository;
private WallabagV2Import $wallabagV2Import;
private FirefoxImport $firefoxImport;
private ChromeImport $chromeImport;
private ReadabilityImport $readabilityImport;
private InstapaperImport $instapaperImport;
private PinboardImport $pinboardImport;
private DeliciousImport $deliciousImport;
private OmnivoreImport $omnivoreImport;
private WallabagV1Import $wallabagV1Import;
private ElcuratorImport $elcuratorImport;
private ShaarliImport $shaarliImport;
private PocketHtmlImport $pocketHtmlImport;
public function __construct(
EntityManagerInterface $entityManager,
TokenStorageInterface $tokenStorage,
UserRepository $userRepository,
WallabagV2Import $wallabagV2Import,
FirefoxImport $firefoxImport,
ChromeImport $chromeImport,
ReadabilityImport $readabilityImport,
InstapaperImport $instapaperImport,
PinboardImport $pinboardImport,
DeliciousImport $deliciousImport,
WallabagV1Import $wallabagV1Import,
ElcuratorImport $elcuratorImport,
ShaarliImport $shaarliImport,
PocketHtmlImport $pocketHtmlImport,
OmnivoreImport $omnivoreImport
private readonly EntityManagerInterface $entityManager,
private readonly TokenStorageInterface $tokenStorage,
private readonly UserRepository $userRepository,
private readonly WallabagV2Import $wallabagV2Import,
private readonly FirefoxImport $firefoxImport,
private readonly ChromeImport $chromeImport,
private readonly ReadabilityImport $readabilityImport,
private readonly InstapaperImport $instapaperImport,
private readonly PinboardImport $pinboardImport,
private readonly DeliciousImport $deliciousImport,
private readonly WallabagV1Import $wallabagV1Import,
private readonly ElcuratorImport $elcuratorImport,
private readonly ShaarliImport $shaarliImport,
private readonly PocketHtmlImport $pocketHtmlImport,
private readonly OmnivoreImport $omnivoreImport,
) {
$this->entityManager = $entityManager;
$this->tokenStorage = $tokenStorage;
$this->userRepository = $userRepository;
$this->wallabagV2Import = $wallabagV2Import;
$this->firefoxImport = $firefoxImport;
$this->chromeImport = $chromeImport;
$this->readabilityImport = $readabilityImport;
$this->instapaperImport = $instapaperImport;
$this->pinboardImport = $pinboardImport;
$this->deliciousImport = $deliciousImport;
$this->omnivoreImport = $omnivoreImport;
$this->wallabagV1Import = $wallabagV1Import;
$this->elcuratorImport = $elcuratorImport;
$this->shaarliImport = $shaarliImport;
$this->pocketHtmlImport = $pocketHtmlImport;
parent::__construct();
}
@ -107,9 +75,7 @@ class ImportCommand extends Command
// Turning off doctrine default logs queries for saving memory
$middlewares = $this->entityManager->getConnection()->getConfiguration()->getMiddlewares();
$middlewaresWithoutLogging = array_filter($middlewares, function (Middleware $middleware) {
return !$middleware instanceof LoggingMiddleware;
});
$middlewaresWithoutLogging = array_filter($middlewares, fn (Middleware $middleware) => !$middleware instanceof LoggingMiddleware);
$this->entityManager->getConnection()->getConfiguration()->setMiddlewares($middlewaresWithoutLogging);
if ($input->getOption('useUserId')) {
@ -130,44 +96,22 @@ class ImportCommand extends Command
$this->tokenStorage->setToken($token);
$user = $this->tokenStorage->getToken()->getUser();
\assert($user instanceof User);
switch ($input->getOption('importer')) {
case 'v2':
$import = $this->wallabagV2Import;
break;
case 'firefox':
$import = $this->firefoxImport;
break;
case 'chrome':
$import = $this->chromeImport;
break;
case 'readability':
$import = $this->readabilityImport;
break;
case 'instapaper':
$import = $this->instapaperImport;
break;
case 'pinboard':
$import = $this->pinboardImport;
break;
case 'delicious':
$import = $this->deliciousImport;
break;
case 'elcurator':
$import = $this->elcuratorImport;
break;
case 'shaarli':
$import = $this->shaarliImport;
break;
case 'pocket':
$import = $this->pocketHtmlImport;
break;
case 'omnivore':
$import = $this->omnivoreImport;
break;
default:
$import = $this->wallabagV1Import;
}
$import = match ($input->getOption('importer')) {
'v2' => $this->wallabagV2Import,
'firefox' => $this->firefoxImport,
'chrome' => $this->chromeImport,
'readability' => $this->readabilityImport,
'instapaper' => $this->instapaperImport,
'pinboard' => $this->pinboardImport,
'delicious' => $this->deliciousImport,
'elcurator' => $this->elcuratorImport,
'shaarli' => $this->shaarliImport,
'pocket' => $this->pocketHtmlImport,
'omnivore' => $this->omnivoreImport,
default => $this->wallabagV1Import,
};
$import->setMarkAsRead($input->getOption('markAsRead'));
$import->setDisableContentUpdate($input->getOption('disableContentUpdate'));

View File

@ -16,12 +16,9 @@ class RedisWorkerCommand extends Command
protected static $defaultName = 'wallabag:import:redis-worker';
protected static $defaultDescription = 'Launch Redis worker';
private $container;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
public function __construct(
private readonly ContainerInterface $container,
) {
parent::__construct();
}

View File

@ -37,24 +37,15 @@ class InstallCommand extends Command
'curl_multi_init',
];
private EntityManagerInterface $entityManager;
private EventDispatcherInterface $dispatcher;
private UserManagerInterface $userManager;
private TableMetadataStorageConfiguration $tableMetadataStorageConfiguration;
private string $databaseDriver;
private array $defaultSettings;
private array $defaultIgnoreOriginInstanceRules;
public function __construct(EntityManagerInterface $entityManager, EventDispatcherInterface $dispatcher, UserManagerInterface $userManager, TableMetadataStorageConfiguration $tableMetadataStorageConfiguration, string $databaseDriver, array $defaultSettings, array $defaultIgnoreOriginInstanceRules)
{
$this->entityManager = $entityManager;
$this->dispatcher = $dispatcher;
$this->userManager = $userManager;
$this->tableMetadataStorageConfiguration = $tableMetadataStorageConfiguration;
$this->databaseDriver = $databaseDriver;
$this->defaultSettings = $defaultSettings;
$this->defaultIgnoreOriginInstanceRules = $defaultIgnoreOriginInstanceRules;
public function __construct(
private readonly EntityManagerInterface $entityManager,
private readonly EventDispatcherInterface $dispatcher,
private readonly UserManagerInterface $userManager,
private readonly TableMetadataStorageConfiguration $tableMetadataStorageConfiguration,
private readonly string $databaseDriver,
private readonly array $defaultSettings,
private readonly array $defaultIgnoreOriginInstanceRules,
) {
parent::__construct();
}
@ -138,7 +129,7 @@ class InstallCommand extends Command
// now check if MySQL isn't too old to handle utf8mb4
if ($conn->isConnected() && $conn->getDatabasePlatform() instanceof MySQLPlatform) {
$version = $conn->query('select version()')->fetchOne();
$version = $conn->executeQuery('select version()')->fetchOne();
$minimalVersion = '5.5.4';
if (false === version_compare($version, $minimalVersion, '>')) {
@ -151,9 +142,9 @@ class InstallCommand extends Command
// testing if PostgreSQL > 9.1
if ($conn->isConnected() && $conn->getDatabasePlatform() instanceof PostgreSQLPlatform) {
// return version should be like "PostgreSQL 9.5.4 on x86_64-apple-darwin15.6.0, compiled by Apple LLVM version 8.0.0 (clang-800.0.38), 64-bit"
$version = $conn->query('SELECT version();')->fetchOne();
$version = $conn->executeQuery('SELECT version();')->fetchOne();
preg_match('/PostgreSQL ([0-9\.]+)/i', $version, $matches);
preg_match('/PostgreSQL ([0-9\.]+)/i', (string) $version, $matches);
if (isset($matches[1]) & version_compare($matches[1], '9.2.0', '<')) {
$fulfilled = false;
@ -411,7 +402,7 @@ class InstallCommand extends Command
try {
return \in_array($databaseName, $schemaManager->listDatabases(), true);
} catch (DriverException $e) {
} catch (DriverException) {
// it means we weren't able to get database list, assume the database doesn't exist
return false;

View File

@ -15,12 +15,9 @@ class ListUserCommand extends Command
protected static $defaultName = 'wallabag:user:list';
protected static $defaultDescription = 'List all users';
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
public function __construct(
private readonly UserRepository $userRepository,
) {
parent::__construct();
}

View File

@ -21,20 +21,13 @@ class ReloadEntryCommand extends Command
protected static $defaultName = 'wallabag:entry:reload';
protected static $defaultDescription = 'Reload entries';
private EntryRepository $entryRepository;
private UserRepository $userRepository;
private EntityManagerInterface $entityManager;
private ContentProxy $contentProxy;
private EventDispatcherInterface $dispatcher;
public function __construct(EntryRepository $entryRepository, UserRepository $userRepository, EntityManagerInterface $entityManager, ContentProxy $contentProxy, EventDispatcherInterface $dispatcher)
{
$this->entryRepository = $entryRepository;
$this->userRepository = $userRepository;
$this->entityManager = $entityManager;
$this->contentProxy = $contentProxy;
$this->dispatcher = $dispatcher;
public function __construct(
private readonly EntryRepository $entryRepository,
private readonly UserRepository $userRepository,
private readonly EntityManagerInterface $entityManager,
private readonly ContentProxy $contentProxy,
private readonly EventDispatcherInterface $dispatcher,
) {
parent::__construct();
}
@ -62,7 +55,7 @@ class ReloadEntryCommand extends Command
$userId = $this->userRepository
->findOneByUserName($username)
->getId();
} catch (NoResultException $e) {
} catch (NoResultException) {
$io->error(\sprintf('User "%s" not found.', $username));
return 1;

View File

@ -17,12 +17,10 @@ class ShowUserCommand extends Command
protected static $defaultDescription = 'Show user details';
protected SymfonyStyle $io;
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
public function __construct(
private readonly UserRepository $userRepository,
) {
parent::__construct();
}
@ -46,7 +44,7 @@ class ShowUserCommand extends Command
try {
$user = $this->getUser($username);
$this->showUser($user);
} catch (NoResultException $e) {
} catch (NoResultException) {
$this->io->error(\sprintf('User "%s" not found.', $username));
return 1;

View File

@ -18,16 +18,11 @@ class TagAllCommand extends Command
protected static $defaultName = 'wallabag:tag:all';
protected static $defaultDescription = 'Tag all entries using the tagging rules.';
private EntityManagerInterface $entityManager;
private RuleBasedTagger $ruleBasedTagger;
private UserRepository $userRepository;
public function __construct(EntityManagerInterface $entityManager, RuleBasedTagger $ruleBasedTagger, UserRepository $userRepository)
{
$this->entityManager = $entityManager;
$this->ruleBasedTagger = $ruleBasedTagger;
$this->userRepository = $userRepository;
public function __construct(
private readonly EntityManagerInterface $entityManager,
private readonly RuleBasedTagger $ruleBasedTagger,
private readonly UserRepository $userRepository,
) {
parent::__construct();
}
@ -48,7 +43,7 @@ class TagAllCommand extends Command
try {
$user = $this->getUser($input->getArgument('username'));
} catch (NoResultException $e) {
} catch (NoResultException) {
$io->error(\sprintf('User "%s" not found.', $input->getArgument('username')));
return 1;

View File

@ -15,15 +15,11 @@ class UpdatePicturesPathCommand extends Command
protected static $defaultName = 'wallabag:update-pictures-path';
protected static $defaultDescription = 'Update the path of the pictures for each entry when you changed your wallabag instance URL.';
private EntityManagerInterface $entityManager;
private EntryRepository $entryRepository;
private string $wallabagUrl;
public function __construct(EntityManagerInterface $entityManager, EntryRepository $entryRepository, $wallabagUrl)
{
$this->entityManager = $entityManager;
$this->entryRepository = $entryRepository;
$this->wallabagUrl = $wallabagUrl;
public function __construct(
private readonly EntityManagerInterface $entityManager,
private readonly EntryRepository $entryRepository,
private readonly string $wallabagUrl,
) {
parent::__construct();
}

View File

@ -7,8 +7,8 @@ use PhpAmqpLib\Message\AMQPMessage;
class AMQPEntryConsumer extends AbstractConsumer implements ConsumerInterface
{
public function execute(AMQPMessage $msg)
public function execute(AMQPMessage $msg): int|bool
{
return $this->handleMessage($msg->body);
return $this->handleMessage($msg->getBody());
}
}

View File

@ -7,25 +7,19 @@ use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Wallabag\Entity\Entry;
use Wallabag\Entity\Tag;
use Wallabag\Event\EntrySavedEvent;
use Wallabag\Import\AbstractImport;
use Wallabag\Repository\UserRepository;
abstract class AbstractConsumer
{
protected $em;
protected $userRepository;
protected $import;
protected $eventDispatcher;
protected $logger;
public function __construct(EntityManagerInterface $em, UserRepository $userRepository, AbstractImport $import, EventDispatcherInterface $eventDispatcher, ?LoggerInterface $logger = null)
{
$this->em = $em;
$this->userRepository = $userRepository;
$this->import = $import;
$this->eventDispatcher = $eventDispatcher;
public function __construct(
protected EntityManagerInterface $em,
protected UserRepository $userRepository,
protected AbstractImport $import,
protected EventDispatcherInterface $eventDispatcher,
protected ?LoggerInterface $logger = null,
) {
$this->logger = $logger ?: new NullLogger();
}
@ -74,9 +68,7 @@ abstract class AbstractConsumer
// entry saved, dispatch event about it!
$this->eventDispatcher->dispatch(new EntrySavedEvent($entry), EntrySavedEvent::NAME);
// clear only affected entities
$this->em->clear(Entry::class);
$this->em->clear(Tag::class);
$this->em->clear();
} catch (\Exception $e) {
$this->logger->warning('Unable to save entry', ['entry' => $storedEntry, 'exception' => $e]);

View File

@ -10,48 +10,21 @@ use OldSound\RabbitMqBundle\RabbitMq\Consumer;
*/
class RabbitMQConsumerTotalProxy
{
private Consumer $pocketConsumer;
private Consumer $readabilityConsumer;
private Consumer $wallabagV1Consumer;
private Consumer $wallabagV2Consumer;
private Consumer $firefoxConsumer;
private Consumer $chromeConsumer;
private Consumer $instapaperConsumer;
private Consumer $pinboardConsumer;
private Consumer $deliciousConsumer;
private Consumer $elcuratorConsumer;
private Consumer $shaarliConsumer;
private Consumer $pocketHtmlConsumer;
private Consumer $omnivoreConsumer;
public function __construct(
Consumer $pocketConsumer,
Consumer $readabilityConsumer,
Consumer $wallabagV1Consumer,
Consumer $wallabagV2Consumer,
Consumer $firefoxConsumer,
Consumer $chromeConsumer,
Consumer $instapaperConsumer,
Consumer $pinboardConsumer,
Consumer $deliciousConsumer,
Consumer $elcuratorConsumer,
Consumer $shaarliConsumer,
Consumer $pocketHtmlConsumer,
Consumer $omnivoreConsumer
private readonly Consumer $pocketConsumer,
private readonly Consumer $readabilityConsumer,
private readonly Consumer $wallabagV1Consumer,
private readonly Consumer $wallabagV2Consumer,
private readonly Consumer $firefoxConsumer,
private readonly Consumer $chromeConsumer,
private readonly Consumer $instapaperConsumer,
private readonly Consumer $pinboardConsumer,
private readonly Consumer $deliciousConsumer,
private readonly Consumer $elcuratorConsumer,
private readonly Consumer $shaarliConsumer,
private readonly Consumer $pocketHtmlConsumer,
private readonly Consumer $omnivoreConsumer,
) {
$this->pocketConsumer = $pocketConsumer;
$this->readabilityConsumer = $readabilityConsumer;
$this->wallabagV1Consumer = $wallabagV1Consumer;
$this->wallabagV2Consumer = $wallabagV2Consumer;
$this->firefoxConsumer = $firefoxConsumer;
$this->chromeConsumer = $chromeConsumer;
$this->instapaperConsumer = $instapaperConsumer;
$this->pinboardConsumer = $pinboardConsumer;
$this->deliciousConsumer = $deliciousConsumer;
$this->elcuratorConsumer = $elcuratorConsumer;
$this->shaarliConsumer = $shaarliConsumer;
$this->pocketHtmlConsumer = $pocketHtmlConsumer;
$this->omnivoreConsumer = $omnivoreConsumer;
}
/**
@ -115,6 +88,6 @@ class RabbitMQConsumerTotalProxy
return 0;
}
return $message->delivery_info['message_count'] + 1;
return $message->getMessageCount() + 1;
}
}

View File

@ -5,6 +5,7 @@ namespace Wallabag\Controller;
use Doctrine\ORM\EntityManagerInterface;
use FOS\RestBundle\Controller\AbstractFOSRestController;
use JMS\Serializer\SerializerInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
@ -19,15 +20,11 @@ use Wallabag\Repository\AnnotationRepository;
class AnnotationController 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;
public function __construct(
protected EntityManagerInterface $entityManager,
protected SerializerInterface $serializer,
protected FormFactoryInterface $formFactory,
) {
}
/**
@ -35,10 +32,10 @@ class AnnotationController extends AbstractFOSRestController
*
* @see Api\WallabagRestController
*
* @Route("/annotations/{entry}.{_format}", methods={"GET"}, name="annotations_get_annotations", defaults={"_format": "json"})
*
* @return JsonResponse
*/
#[Route(path: '/annotations/{entry}.{_format}', name: 'annotations_get_annotations', methods: ['GET'], defaults: ['_format' => 'json'])]
#[IsGranted('LIST_ANNOTATIONS', subject: 'entry')]
public function getAnnotationsAction(Entry $entry, AnnotationRepository $annotationRepository)
{
$annotationRows = $annotationRepository->findByEntryIdAndUserId($entry->getId(), $this->getUser()->getId());
@ -56,10 +53,10 @@ class AnnotationController extends AbstractFOSRestController
*
* @see Api\WallabagRestController
*
* @Route("/annotations/{entry}.{_format}", methods={"POST"}, name="annotations_post_annotation", defaults={"_format": "json"})
*
* @return JsonResponse
*/
#[Route(path: '/annotations/{entry}.{_format}', name: 'annotations_post_annotation', methods: ['POST'], defaults: ['_format' => 'json'])]
#[IsGranted('CREATE_ANNOTATIONS', subject: 'entry')]
public function postAnnotationAction(Request $request, Entry $entry)
{
$data = json_decode($request->getContent(), true);
@ -82,7 +79,7 @@ class AnnotationController extends AbstractFOSRestController
return JsonResponse::fromJsonString($json);
}
return $form;
return new JsonResponse(status: 400);
}
/**
@ -90,15 +87,13 @@ class AnnotationController extends AbstractFOSRestController
*
* @see Api\WallabagRestController
*
* @Route("/annotations/{annotation}.{_format}", methods={"PUT"}, name="annotations_put_annotation", defaults={"_format": "json"})
*
* @return JsonResponse
*/
public function putAnnotationAction(Request $request, AnnotationRepository $annotationRepository, int $annotation)
#[Route(path: '/annotations/{annotation}.{_format}', name: 'annotations_put_annotation', methods: ['PUT'], defaults: ['_format' => 'json'])]
#[IsGranted('EDIT', subject: 'annotation')]
public function putAnnotationAction(Request $request, Annotation $annotation)
{
try {
$annotation = $this->validateAnnotation($annotationRepository, $annotation, $this->getUser()->getId());
$data = json_decode($request->getContent(), true, 512, \JSON_THROW_ON_ERROR);
$form = $this->formFactory->createNamed('', EditAnnotationType::class, $annotation, [
@ -116,7 +111,7 @@ class AnnotationController extends AbstractFOSRestController
return JsonResponse::fromJsonString($json);
}
return $form;
return new JsonResponse(status: 400);
} catch (\InvalidArgumentException $e) {
throw new NotFoundHttpException($e);
}
@ -127,15 +122,13 @@ class AnnotationController extends AbstractFOSRestController
*
* @see Api\WallabagRestController
*
* @Route("/annotations/{annotation}.{_format}", methods={"DELETE"}, name="annotations_delete_annotation", defaults={"_format": "json"})
*
* @return JsonResponse
*/
public function deleteAnnotationAction(AnnotationRepository $annotationRepository, int $annotation)
#[Route(path: '/annotations/{annotation}.{_format}', name: 'annotations_delete_annotation', methods: ['DELETE'], defaults: ['_format' => 'json'])]
#[IsGranted('DELETE', subject: 'annotation')]
public function deleteAnnotationAction(Annotation $annotation)
{
try {
$annotation = $this->validateAnnotation($annotationRepository, $annotation, $this->getUser()->getId());
$this->entityManager->remove($annotation);
$this->entityManager->flush();
@ -157,15 +150,4 @@ class AnnotationController extends AbstractFOSRestController
return $user;
}
private function validateAnnotation(AnnotationRepository $annotationRepository, int $annotationId, int $userId)
{
$annotation = $annotationRepository->findOneByIdAndUserId($annotationId, $userId);
if (null === $annotation) {
throw new NotFoundHttpException();
}
return $annotation;
}
}

View File

@ -4,6 +4,7 @@ namespace Wallabag\Controller\Api;
use Nelmio\ApiDocBundle\Annotation\Operation;
use OpenApi\Annotations as OA;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
@ -34,14 +35,12 @@ class AnnotationRestController extends WallabagRestController
* )
* )
*
* @Route("/api/annotations/{entry}.{_format}", methods={"GET"}, name="api_get_annotations", defaults={"_format": "json"})
*
* @return Response
*/
#[Route(path: '/api/annotations/{entry}.{_format}', name: 'api_get_annotations', methods: ['GET'], defaults: ['_format' => 'json'])]
#[IsGranted('LIST_ANNOTATIONS', subject: 'entry')]
public function getAnnotationsAction(Entry $entry)
{
$this->validateAuthentication();
return $this->forward('Wallabag\Controller\AnnotationController::getAnnotationsAction', [
'entry' => $entry,
]);
@ -100,14 +99,12 @@ class AnnotationRestController extends WallabagRestController
* )
* )
*
* @Route("/api/annotations/{entry}.{_format}", methods={"POST"}, name="api_post_annotation", defaults={"_format": "json"})
*
* @return Response
*/
#[Route(path: '/api/annotations/{entry}.{_format}', name: 'api_post_annotation', methods: ['POST'], defaults: ['_format' => 'json'])]
#[IsGranted('CREATE_ANNOTATIONS', subject: 'entry')]
public function postAnnotationAction(Request $request, Entry $entry)
{
$this->validateAuthentication();
return $this->forward('Wallabag\Controller\AnnotationController::postAnnotationAction', [
'request' => $request,
'entry' => $entry,
@ -136,14 +133,12 @@ class AnnotationRestController extends WallabagRestController
* )
* )
*
* @Route("/api/annotations/{annotation}.{_format}", methods={"PUT"}, name="api_put_annotation", defaults={"_format": "json"})
*
* @return Response
*/
public function putAnnotationAction(int $annotation, Request $request)
#[Route(path: '/api/annotations/{annotation}.{_format}', name: 'api_put_annotation', methods: ['PUT'], defaults: ['_format' => 'json'])]
#[IsGranted('EDIT', subject: 'annotation')]
public function putAnnotationAction(Annotation $annotation, Request $request)
{
$this->validateAuthentication();
return $this->forward('Wallabag\Controller\AnnotationController::putAnnotationAction', [
'annotation' => $annotation,
'request' => $request,
@ -172,14 +167,12 @@ class AnnotationRestController extends WallabagRestController
* )
* )
*
* @Route("/api/annotations/{annotation}.{_format}", methods={"DELETE"}, name="api_delete_annotation", defaults={"_format": "json"})
*
* @return Response
*/
public function deleteAnnotationAction(int $annotation)
#[Route(path: '/api/annotations/{annotation}.{_format}', name: 'api_delete_annotation', methods: ['DELETE'], defaults: ['_format' => 'json'])]
#[IsGranted('DELETE', subject: 'annotation')]
public function deleteAnnotationAction(Annotation $annotation)
{
$this->validateAuthentication();
return $this->forward('Wallabag\Controller\AnnotationController::deleteAnnotationAction', [
'annotation' => $annotation,
]);

View File

@ -23,10 +23,9 @@ class ConfigRestController extends WallabagRestController
* )
* )
*
* @Route("/api/config.{_format}", methods={"GET"}, name="api_get_config", defaults={"_format": "json"})
*
* @return JsonResponse
*/
#[Route(path: '/api/config.{_format}', name: 'api_get_config', methods: ['GET'], defaults: ['_format' => 'json'])]
public function getConfigAction(SerializerInterface $serializer)
{
$this->validateAuthentication();

View File

@ -6,6 +6,7 @@ use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Contracts\Translation\TranslatorInterface;
use Wallabag\Controller\AbstractController;
@ -18,10 +19,9 @@ class DeveloperController extends AbstractController
/**
* List all clients and link to create a new one.
*
* @Route("/developer", name="developer")
*
* @return Response
*/
#[Route(path: '/developer', name: 'developer', methods: ['GET'])]
public function indexAction(ClientRepository $repo)
{
$clients = $repo->findByUser($this->getUser()->getId());
@ -34,10 +34,9 @@ class DeveloperController extends AbstractController
/**
* Create a client (an app).
*
* @Route("/developer/client/create", name="developer_create_client")
*
* @return Response
*/
#[Route(path: '/developer/client/create', name: 'developer_create_client', methods: ['GET', 'POST'])]
public function createClientAction(Request $request, EntityManagerInterface $entityManager, TranslatorInterface $translator)
{
$client = new Client($this->getUser());
@ -69,14 +68,13 @@ class DeveloperController extends AbstractController
/**
* Remove a client.
*
* @Route("/developer/client/delete/{id}", requirements={"id" = "\d+"}, name="developer_delete_client", methods={"POST"})
*
* @return RedirectResponse
*/
#[Route(path: '/developer/client/delete/{id}', name: 'developer_delete_client', methods: ['POST'], requirements: ['id' => '\d+'])]
public function deleteClientAction(Request $request, Client $client, EntityManagerInterface $entityManager, TranslatorInterface $translator)
{
if (!$this->isCsrfTokenValid('delete-client', $request->request->get('token'))) {
throw $this->createAccessDeniedException('Bad CSRF token.');
throw new BadRequestHttpException('Bad CSRF token.');
}
if (null === $this->getUser() || $client->getUser()->getId() !== $this->getUser()->getId()) {
@ -97,14 +95,11 @@ class DeveloperController extends AbstractController
/**
* Display developer how to use an existing app.
*
* @Route("/developer/howto/first-app", name="developer_howto_firstapp")
*
* @return Response
*/
#[Route(path: '/developer/howto/first-app', name: 'developer_howto_firstapp', methods: ['GET'])]
public function howtoFirstAppAction()
{
return $this->render('Developer/howto_app.html.twig', [
'wallabag_url' => $this->getParameter('domain_name'),
]);
return $this->render('Developer/howto_app.html.twig');
}
}

View File

@ -8,6 +8,7 @@ use Nelmio\ApiDocBundle\Annotation\Operation;
use OpenApi\Annotations as OA;
use Pagerfanta\Pagerfanta;
use Psr\Log\LoggerInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
@ -84,14 +85,12 @@ class EntryRestController extends WallabagRestController
* )
* )
*
* @Route("/api/entries/exists.{_format}", methods={"GET"}, name="api_get_entries_exists", defaults={"_format": "json"})
*
* @return JsonResponse
*/
#[Route(path: '/api/entries/exists.{_format}', name: 'api_get_entries_exists', methods: ['GET'], defaults: ['_format' => 'json'])]
#[IsGranted('LIST_ENTRIES')]
public function getEntriesExistsAction(Request $request, EntryRepository $entryRepository)
{
$this->validateAuthentication();
$returnId = (null === $request->query->get('return_id')) ? false : (bool) $request->query->get('return_id');
$hashedUrls = $request->query->all('hashed_urls');
@ -132,9 +131,7 @@ class EntryRestController extends WallabagRestController
}
if (false === $returnId) {
$results = array_map(function ($v) {
return null !== $v;
}, $results);
$results = array_map(fn ($v) => null !== $v, $results);
}
$results = $this->replaceUrlHashes($results, $urlHashMap);
@ -299,24 +296,22 @@ class EntryRestController extends WallabagRestController
* )
* )
*
* @Route("/api/entries.{_format}", methods={"GET"}, name="api_get_entries", defaults={"_format": "json"})
*
* @return JsonResponse
*/
#[Route(path: '/api/entries.{_format}', name: 'api_get_entries', methods: ['GET'], defaults: ['_format' => 'json'])]
#[IsGranted('LIST_ENTRIES')]
public function getEntriesAction(Request $request, EntryRepository $entryRepository)
{
$this->validateAuthentication();
$isArchived = (null === $request->query->get('archive')) ? null : (bool) $request->query->get('archive');
$isStarred = (null === $request->query->get('starred')) ? null : (bool) $request->query->get('starred');
$isPublic = (null === $request->query->get('public')) ? null : (bool) $request->query->get('public');
$isNotParsed = (null === $request->query->get('notParsed')) ? null : (bool) $request->query->get('notParsed');
$sort = strtolower($request->query->get('sort', 'created'));
$order = strtolower($request->query->get('order', 'desc'));
$page = (int) $request->query->get('page', 1);
$perPage = (int) $request->query->get('perPage', 30);
$page = $request->query->getInt('page', 1);
$perPage = $request->query->getInt('perPage', 30);
$tags = \is_array($request->query->all()['tags'] ?? '') ? '' : (string) $request->query->get('tags', '');
$since = $request->query->get('since', 0);
$since = $request->query->getInt('since');
$detail = strtolower($request->query->get('detail', 'full'));
$domainName = (null === $request->query->get('domain_name')) ? '' : (string) $request->query->get('domain_name');
$httpStatus = (!\array_key_exists((int) $request->query->get('http_status'), Response::$statusTexts)) ? null : (int) $request->query->get('http_status');
@ -391,15 +386,12 @@ class EntryRestController extends WallabagRestController
* )
* )
*
* @Route("/api/entries/{entry}.{_format}", methods={"GET"}, name="api_get_entry", defaults={"_format": "json"})
*
* @return JsonResponse
*/
#[Route(path: '/api/entries/{entry}.{_format}', name: 'api_get_entry', methods: ['GET'], defaults: ['_format' => 'json'])]
#[IsGranted('VIEW', subject: 'entry')]
public function getEntryAction(Entry $entry)
{
$this->validateAuthentication();
$this->validateUserAccess($entry->getUser()->getId());
return $this->sendResponse($entry);
}
@ -435,15 +427,12 @@ class EntryRestController extends WallabagRestController
* )
* )
*
* @Route("/api/entries/{entry}/export.{_format}", methods={"GET"}, name="api_get_entry_export", defaults={"_format": "json"})
*
* @return Response
*/
#[Route(path: '/api/entries/{entry}/export.{_format}', name: 'api_get_entry_export', methods: ['GET'], defaults: ['_format' => 'json'])]
#[IsGranted('VIEW', subject: 'entry')]
public function getEntryExportAction(Entry $entry, Request $request, EntriesExport $entriesExport)
{
$this->validateAuthentication();
$this->validateUserAccess($entry->getUser()->getId());
return $entriesExport
->setEntries($entry)
->updateTitle('entry')
@ -470,14 +459,12 @@ class EntryRestController extends WallabagRestController
* )
* )
*
* @Route("/api/entries/list.{_format}", methods={"DELETE"}, name="api_delete_entries_list", defaults={"_format": "json"})
*
* @return JsonResponse
*/
#[Route(path: '/api/entries/list.{_format}', name: 'api_delete_entries_list', methods: ['DELETE'], defaults: ['_format' => 'json'])]
#[IsGranted('DELETE_ENTRIES')]
public function deleteEntriesListAction(Request $request, EntryRepository $entryRepository, EventDispatcherInterface $eventDispatcher)
{
$this->validateAuthentication();
$urls = json_decode($request->query->get('urls', '[]'));
if (empty($urls)) {
@ -495,7 +482,7 @@ class EntryRestController extends WallabagRestController
$results[$key]['url'] = $url;
if (false !== $entry) {
if (false !== $entry && $this->authorizationChecker->isGranted('DELETE', $entry)) {
// entry deleted, dispatch event about it!
$eventDispatcher->dispatch(new EntryDeletedEvent($entry), EntryDeletedEvent::NAME);
@ -528,16 +515,14 @@ class EntryRestController extends WallabagRestController
* )
* )
*
* @Route("/api/entries/lists.{_format}", methods={"POST"}, name="api_post_entries_list", defaults={"_format": "json"})
*
* @throws HttpException When limit is reached
*
* @return JsonResponse
*/
#[Route(path: '/api/entries/lists.{_format}', name: 'api_post_entries_list', methods: ['POST'], defaults: ['_format' => 'json'])]
#[IsGranted('CREATE_ENTRIES')]
public function postEntriesListAction(Request $request, EntryRepository $entryRepository, EventDispatcherInterface $eventDispatcher, ContentProxy $contentProxy)
{
$this->validateAuthentication();
$urls = json_decode($request->query->get('urls', '[]'));
$limit = $this->getParameter('wallabag.api_limit_mass_actions');
@ -569,7 +554,7 @@ class EntryRestController extends WallabagRestController
$this->entityManager->persist($entry);
$this->entityManager->flush();
$results[$key]['entry'] = $entry instanceof Entry ? $entry->getId() : false;
$results[$key]['entry'] = $entry->getId();
// entry saved, dispatch event about it!
$eventDispatcher->dispatch(new EntrySavedEvent($entry), EntrySavedEvent::NAME);
@ -713,10 +698,10 @@ class EntryRestController extends WallabagRestController
* )
* )
*
* @Route("/api/entries.{_format}", methods={"POST"}, name="api_post_entries", defaults={"_format": "json"})
*
* @return JsonResponse
*/
#[Route(path: '/api/entries.{_format}', name: 'api_post_entries', methods: ['POST'], defaults: ['_format' => 'json'])]
#[IsGranted('CREATE_ENTRIES')]
public function postEntriesAction(
Request $request,
EntryRepository $entryRepository,
@ -724,10 +709,8 @@ class EntryRestController extends WallabagRestController
LoggerInterface $logger,
TagsAssigner $tagsAssigner,
EventDispatcherInterface $eventDispatcher,
ValidatorInterface $validator
ValidatorInterface $validator,
) {
$this->validateAuthentication();
$url = $request->request->get('url');
$entry = $entryRepository->findByUrlAndUserId(
@ -751,7 +734,7 @@ class EntryRestController extends WallabagRestController
'html' => !empty($data['content']) ? $data['content'] : $entry->getContent(),
'url' => $entry->getUrl(),
'language' => !empty($data['language']) ? $data['language'] : $entry->getLanguage(),
'date' => !empty($data['publishedAt']) ? $data['publishedAt'] : $entry->getPublishedAt(),
'date' => !empty($data['publishedAt']) ? $data['publishedAt'] : $entry->getPublishedAt()?->format('Y-m-d H:i:s') ?? '',
// faking the open graph preview picture
'image' => !empty($data['picture']) ? $data['picture'] : $entry->getPreviewPicture(),
'authors' => \is_string($data['authors']) ? explode(',', $data['authors']) : $entry->getPublishedBy(),
@ -938,15 +921,12 @@ class EntryRestController extends WallabagRestController
* )
* )
*
* @Route("/api/entries/{entry}.{_format}", methods={"PATCH"}, name="api_patch_entries", defaults={"_format": "json"})
*
* @return JsonResponse
*/
#[Route(path: '/api/entries/{entry}.{_format}', name: 'api_patch_entries', methods: ['PATCH'], defaults: ['_format' => 'json'])]
#[IsGranted('EDIT', subject: 'entry')]
public function patchEntriesAction(Entry $entry, Request $request, ContentProxy $contentProxy, LoggerInterface $logger, TagsAssigner $tagsAssigner, EventDispatcherInterface $eventDispatcher)
{
$this->validateAuthentication();
$this->validateUserAccess($entry->getUser()->getId());
$data = $this->retrieveValueFromRequest($request);
// this is a special case where user want to manually update the entry content
@ -1055,15 +1035,12 @@ class EntryRestController extends WallabagRestController
* )
* )
*
* @Route("/api/entries/{entry}/reload.{_format}", methods={"PATCH"}, name="api_patch_entries_reload", defaults={"_format": "json"})
*
* @return JsonResponse
*/
#[Route(path: '/api/entries/{entry}/reload.{_format}', name: 'api_patch_entries_reload', methods: ['PATCH'], defaults: ['_format' => 'json'])]
#[IsGranted('RELOAD', subject: 'entry')]
public function patchEntriesReloadAction(Entry $entry, ContentProxy $contentProxy, LoggerInterface $logger, EventDispatcherInterface $eventDispatcher)
{
$this->validateAuthentication();
$this->validateUserAccess($entry->getUser()->getId());
try {
$contentProxy->updateEntry($entry, $entry->getUrl());
} catch (\Exception $e) {
@ -1112,18 +1089,16 @@ class EntryRestController extends WallabagRestController
* )
* )
*
* @Route("/api/entries/{entry}.{_format}", methods={"DELETE"}, name="api_delete_entries", defaults={"_format": "json"})
*
* @return JsonResponse
*/
#[Route(path: '/api/entries/{entry}.{_format}', name: 'api_delete_entries', methods: ['DELETE'], defaults: ['_format' => 'json'])]
#[IsGranted('DELETE', subject: 'entry')]
public function deleteEntriesAction(Entry $entry, Request $request, EventDispatcherInterface $eventDispatcher)
{
$expect = $request->query->get('expect', 'entry');
if (!\in_array($expect, ['id', 'entry'], true)) {
throw new BadRequestHttpException(\sprintf("expect: 'id' or 'entry' expected, %s given", $expect));
}
$this->validateAuthentication();
$this->validateUserAccess($entry->getUser()->getId());
$response = $this->sendResponse([
'id' => $entry->getId(),
@ -1165,15 +1140,12 @@ class EntryRestController extends WallabagRestController
* )
* )
*
* @Route("/api/entries/{entry}/tags.{_format}", methods={"GET"}, name="api_get_entries_tags", defaults={"_format": "json"})
*
* @return JsonResponse
*/
#[Route(path: '/api/entries/{entry}/tags.{_format}', name: 'api_get_entries_tags', methods: ['GET'], defaults: ['_format' => 'json'])]
#[IsGranted('LIST_TAGS', subject: 'entry')]
public function getEntriesTagsAction(Entry $entry)
{
$this->validateAuthentication();
$this->validateUserAccess($entry->getUser()->getId());
return $this->sendResponse($entry->getTags());
}
@ -1209,15 +1181,12 @@ class EntryRestController extends WallabagRestController
* )
* )
*
* @Route("/api/entries/{entry}/tags.{_format}", methods={"POST"}, name="api_post_entries_tags", defaults={"_format": "json"})
*
* @return JsonResponse
*/
#[Route(path: '/api/entries/{entry}/tags.{_format}', name: 'api_post_entries_tags', methods: ['POST'], defaults: ['_format' => 'json'])]
#[IsGranted('TAG', subject: 'entry')]
public function postEntriesTagsAction(Request $request, Entry $entry, TagsAssigner $tagsAssigner)
{
$this->validateAuthentication();
$this->validateUserAccess($entry->getUser()->getId());
$tags = $request->request->get('tags', '');
if (!empty($tags)) {
$tagsAssigner->assignTagsToEntry($entry, $tags);
@ -1261,15 +1230,12 @@ class EntryRestController extends WallabagRestController
* )
* )
*
* @Route("/api/entries/{entry}/tags/{tag}.{_format}", methods={"DELETE"}, name="api_delete_entries_tags", defaults={"_format": "json"})
*
* @return JsonResponse
*/
#[Route(path: '/api/entries/{entry}/tags/{tag}.{_format}', name: 'api_delete_entries_tags', methods: ['DELETE'], defaults: ['_format' => 'json'])]
#[IsGranted('UNTAG', subject: 'entry')]
public function deleteEntriesTagsAction(Entry $entry, Tag $tag)
{
$this->validateAuthentication();
$this->validateUserAccess($entry->getUser()->getId());
$entry->removeTag($tag);
$this->entityManager->persist($entry);
@ -1297,14 +1263,12 @@ class EntryRestController extends WallabagRestController
* )
* )
*
* @Route("/api/entries/tags/list.{_format}", methods={"DELETE"}, name="api_delete_entries_tags_list", defaults={"_format": "json"})
*
* @return JsonResponse
*/
#[Route(path: '/api/entries/tags/list.{_format}', name: 'api_delete_entries_tags_list', methods: ['DELETE'], defaults: ['_format' => 'json'])]
#[IsGranted('DELETE_TAGS')]
public function deleteEntriesTagsListAction(Request $request, TagRepository $tagRepository, EntryRepository $entryRepository)
{
$this->validateAuthentication();
$list = json_decode($request->query->get('list', '[]'));
if (empty($list)) {
@ -1325,7 +1289,7 @@ class EntryRestController extends WallabagRestController
$tags = $element->tags;
if (false !== $entry && !(empty($tags))) {
if (false !== $entry && !(empty($tags)) && $this->authorizationChecker->isGranted('UNTAG', $entry)) {
$tags = explode(',', $tags);
foreach ($tags as $label) {
$label = trim($label);
@ -1364,14 +1328,12 @@ class EntryRestController extends WallabagRestController
* )
* )
*
* @Route("/api/entries/tags/lists.{_format}", methods={"POST"}, name="api_post_entries_tags_list", defaults={"_format": "json"})
*
* @return JsonResponse
*/
#[Route(path: '/api/entries/tags/lists.{_format}', name: 'api_post_entries_tags_list', methods: ['POST'], defaults: ['_format' => 'json'])]
#[IsGranted('CREATE_TAGS')]
public function postEntriesTagsListAction(Request $request, EntryRepository $entryRepository, TagsAssigner $tagsAssigner)
{
$this->validateAuthentication();
$list = json_decode($request->query->get('list', '[]'));
if (empty($list)) {
@ -1392,7 +1354,7 @@ class EntryRestController extends WallabagRestController
$tags = $element->tags;
if (false !== $entry && !(empty($tags))) {
if (false !== $entry && !(empty($tags)) && $this->authorizationChecker->isGranted('TAG', $entry)) {
$tagsAssigner->assignTagsToEntry($entry, $tags);
$this->entityManager->persist($entry);

View File

@ -8,6 +8,7 @@ use Nelmio\ApiDocBundle\Annotation\Operation;
use OpenApi\Annotations as OA;
use Pagerfanta\Doctrine\ORM\QueryAdapter as DoctrineORMAdapter;
use Pagerfanta\Pagerfanta;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
@ -54,17 +55,15 @@ class SearchRestController extends WallabagRestController
* )
* )
*
* @Route("/api/search.{_format}", methods={"GET"}, name="api_get_search", defaults={"_format": "json"})
*
* @return JsonResponse
*/
#[Route(path: '/api/search.{_format}', name: 'api_get_search', methods: ['GET'], defaults: ['_format' => 'json'])]
#[IsGranted('LIST_ENTRIES')]
public function getSearchAction(Request $request, EntryRepository $entryRepository)
{
$this->validateAuthentication();
$term = $request->query->get('term');
$page = (int) $request->query->get('page', 1);
$perPage = (int) $request->query->get('perPage', 30);
$page = $request->query->getInt('page', 1);
$perPage = $request->query->getInt('perPage', 30);
$qb = $entryRepository->getBuilderForSearchByUser(
$this->getUser()->getId(),

View File

@ -26,10 +26,9 @@ class TagRestController extends WallabagRestController
* )
* )
*
* @Route("/api/tags.{_format}", methods={"GET"}, name="api_get_tags", defaults={"_format": "json"})
*
* @return JsonResponse
*/
#[Route(path: '/api/tags.{_format}', name: 'api_get_tags', methods: ['GET'], defaults: ['_format' => 'json'])]
public function getTagsAction(TagRepository $tagRepository)
{
$this->validateAuthentication();
@ -63,10 +62,9 @@ class TagRestController extends WallabagRestController
* )
* )
*
* @Route("/api/tag/label.{_format}", methods={"DELETE"}, name="api_delete_tag_label", defaults={"_format": "json"})
*
* @return JsonResponse
*/
#[Route(path: '/api/tag/label.{_format}', name: 'api_delete_tag_label', methods: ['DELETE'], defaults: ['_format' => 'json'])]
public function deleteTagLabelAction(Request $request, TagRepository $tagRepository, EntryRepository $entryRepository)
{
$this->validateAuthentication();
@ -111,10 +109,9 @@ class TagRestController extends WallabagRestController
* )
* )
*
* @Route("/api/tags/label.{_format}", methods={"DELETE"}, name="api_delete_tags_label", defaults={"_format": "json"})
*
* @return JsonResponse
*/
#[Route(path: '/api/tags/label.{_format}', name: 'api_delete_tags_label', methods: ['DELETE'], defaults: ['_format' => 'json'])]
public function deleteTagsLabelAction(Request $request, TagRepository $tagRepository, EntryRepository $entryRepository)
{
$this->validateAuthentication();
@ -158,10 +155,9 @@ class TagRestController extends WallabagRestController
* )
* )
*
* @Route("/api/tags/{tag}.{_format}", methods={"DELETE"}, name="api_delete_tag", defaults={"_format": "json"})
*
* @return JsonResponse
*/
#[Route(path: '/api/tags/{tag}.{_format}', name: 'api_delete_tag', methods: ['DELETE'], defaults: ['_format' => 'json'])]
public function deleteTagAction(Tag $tag, TagRepository $tagRepository, EntryRepository $entryRepository)
{
$this->validateAuthentication();

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