mirror of
https://github.com/wallabag/wallabag.git
synced 2025-12-26 11:07:33 +01:00
Compare commits
389 Commits
parameters
...
articles-w
| Author | SHA1 | Date | |
|---|---|---|---|
| ba550268c5 | |||
| fcdcd5dfe3 | |||
| 25eeb24960 | |||
| edfb821c44 | |||
| bd4b474981 | |||
| ffe6ad1819 | |||
| 2a06a4412d | |||
| 9721fd9c63 | |||
| 0ade0f0112 | |||
| c2c4e46294 | |||
| 2a042a7735 | |||
| b340a581c9 | |||
| 98a8adc6f8 | |||
| 244c238aff | |||
| 1efed23313 | |||
| 2bef2a09c1 | |||
| 8fd5a5273d | |||
| 30a22e690b | |||
| 4f34cfa6fc | |||
| 661fbadbcb | |||
| 8e90c0f320 | |||
| 6ffd7382c7 | |||
| 46d6e4d923 | |||
| 09af127446 | |||
| 4c23196304 | |||
| 42746f418e | |||
| 35c4feedd8 | |||
| d4472a1684 | |||
| cdb1a6fad5 | |||
| c451cc96e5 | |||
| c4240c866b | |||
| 27d66d9e1d | |||
| c1397f43ac | |||
| 52a16bb75f | |||
| f82c87b520 | |||
| 9ec448ab07 | |||
| f33a11d387 | |||
| 4a56e00ea6 | |||
| a083e1f1fd | |||
| 2cc4c483ae | |||
| bd5d504b39 | |||
| e8ce4b4e1a | |||
| 910b057032 | |||
| 46ab120a46 | |||
| 47d9d92c69 | |||
| 37e519f2c0 | |||
| e874b5d2bc | |||
| 13909a8054 | |||
| bbed48e25f | |||
| 0691d2445d | |||
| cfcdbcd1e9 | |||
| e51e5c624b | |||
| ebeb2b105e | |||
| 81a4b52841 | |||
| 47a374270a | |||
| c01408981a | |||
| 772a802596 | |||
| 29162bde9d | |||
| 2e95ae76c2 | |||
| 50b3be776a | |||
| cad5a24fb6 | |||
| 2cd1df4722 | |||
| 843d177d80 | |||
| b1614e9267 | |||
| 95ff88dae8 | |||
| 34740694fe | |||
| 1f3c8eeb61 | |||
| d3c448c858 | |||
| f57280a247 | |||
| 366adf0770 | |||
| 29e43a809d | |||
| 8c91ff613c | |||
| 33ab6a8b9c | |||
| 2d7f2e84be | |||
| 0b0724cc95 | |||
| 3037c374c1 | |||
| 2a70f6c1b5 | |||
| 046cdb978b | |||
| dcaf6b0713 | |||
| c2d35a35e3 | |||
| 48bdeb930d | |||
| c60d237fb2 | |||
| 94ccfff72a | |||
| ab51a65319 | |||
| f4b089e679 | |||
| db21570517 | |||
| 38a18f644b | |||
| 5d3d639d3c | |||
| e6fc4e038a | |||
| 50853f2ad4 | |||
| 14af4f356d | |||
| de630c6050 | |||
| 9559492524 | |||
| ba1020abd5 | |||
| 394ef8f935 | |||
| cb1d340fca | |||
| 478e10ba4a | |||
| 72a3477a83 | |||
| 36eb513e1b | |||
| 3ef7064ada | |||
| 1f8a30f56d | |||
| a03da9414e | |||
| 885e042097 | |||
| 03873e5ac9 | |||
| 1393656e56 | |||
| 16c6f191db | |||
| c554bf7d6d | |||
| 9fba643094 | |||
| dab0bc520b | |||
| 1f89bed117 | |||
| fed449b1e2 | |||
| fe4474869c | |||
| 6937241226 | |||
| 00ad4e0a78 | |||
| ef00122edc | |||
| ae2a867cdd | |||
| 7ffcd8f7f6 | |||
| 96dea32650 | |||
| 70999075a6 | |||
| 262f674245 | |||
| a3ac567c31 | |||
| e7668eabd1 | |||
| df12d66564 | |||
| 8b53d3c9c5 | |||
| 260beeec68 | |||
| 01ffc6c3d5 | |||
| 5586930376 | |||
| b45116b73e | |||
| c2e38cedac | |||
| 35dcc43366 | |||
| de8f859536 | |||
| e6ce9c524c | |||
| 5cdac6c0bb | |||
| 466cd17d5b | |||
| 14cdd123ce | |||
| bdb420b13f | |||
| 99c8a06594 | |||
| 387224f830 | |||
| e4fb100163 | |||
| e28e1bddb4 | |||
| b266d6ca2f | |||
| 8b0e6319e4 | |||
| 7eaaf5d38c | |||
| a8cb9f4f77 | |||
| c9cfae11f7 | |||
| 2054be7bd4 | |||
| f7c8466231 | |||
| e438b5e63f | |||
| 1fd861078d | |||
| a06da68e72 | |||
| 9da9e6b004 | |||
| ffeca7f94d | |||
| d515e11fe4 | |||
| 019d252446 | |||
| 503b82ea13 | |||
| 3125eb43ad | |||
| e5042074a2 | |||
| 76c101938d | |||
| a7a4c5fefb | |||
| 1b683dbb05 | |||
| a69ea46945 | |||
| 2a2172037e | |||
| 0589066ed1 | |||
| 1f76184d02 | |||
| 66c6a25941 | |||
| 46f505f69f | |||
| b4483023e6 | |||
| 31e1be4191 | |||
| 63dc69d70f | |||
| 4e177e1778 | |||
| a766826a69 | |||
| a1440dffda | |||
| 2a60d8473d | |||
| 6a3780ce81 | |||
| 42a63be61a | |||
| 9e2720cddc | |||
| ca018c77e3 | |||
| a107773c11 | |||
| 1d5674a230 | |||
| 4168727f36 | |||
| ce8ed589d5 | |||
| f8c8bb7d93 | |||
| 241cddc899 | |||
| 745fef44f4 | |||
| 99a49bfc96 | |||
| 84eb99c59b | |||
| a679117736 | |||
| eadb6838c0 | |||
| 5fca2db1e5 | |||
| b56d3fef87 | |||
| 4b652b416c | |||
| 528650b525 | |||
| 5597f527d5 | |||
| c79d4449bd | |||
| 07d888a71e | |||
| 10e80a7b9a | |||
| 967ac9f9ac | |||
| be9b1ef60a | |||
| d29e757a09 | |||
| 8a15feb730 | |||
| d4fbb80dd5 | |||
| 27a93cc281 | |||
| e63d473032 | |||
| 41767e8fbc | |||
| c0bb737200 | |||
| 0d93add058 | |||
| 3f2f57e0c0 | |||
| 412352ff03 | |||
| 4ab26a1902 | |||
| a7f7022229 | |||
| 95730754e8 | |||
| 402d80cd30 | |||
| c9301bd0b3 | |||
| 47d3bd4b69 | |||
| f7f5c714ac | |||
| 069c09d8d9 | |||
| 1127b147c0 | |||
| c50265c1eb | |||
| f3e88ec461 | |||
| 5809afd256 | |||
| 2f9d95c2dd | |||
| c860f4db6a | |||
| ae8d7e2e37 | |||
| 67bd937619 | |||
| 82e49ead7d | |||
| a72f7930c4 | |||
| c75e4cf63a | |||
| a9f9c9d513 | |||
| 08d2233882 | |||
| 2344a23be2 | |||
| 6e54f0d0ab | |||
| d6e27feac0 | |||
| 1382af1a5d | |||
| 04f29e4a6b | |||
| 8ac2e699e0 | |||
| 0d9cbcdfcf | |||
| bff0853021 | |||
| 23565c0784 | |||
| b7648f575e | |||
| 622ab8cf96 | |||
| 7a407160c1 | |||
| 985e81e017 | |||
| 5bf34d3c72 | |||
| 4c52f71895 | |||
| 677b2986bc | |||
| 5ea5115a72 | |||
| 27f0d94db7 | |||
| cf49be6940 | |||
| ddf2e80842 | |||
| d1e128900a | |||
| 0d8429dfc7 | |||
| eb8408b22f | |||
| 00d0e6f951 | |||
| edffef8375 | |||
| 3817010e29 | |||
| ed1acf59e1 | |||
| 56ce98fb9a | |||
| d5aa680054 | |||
| 6c183081df | |||
| d965c25304 | |||
| 8fade1416b | |||
| 4d7fdc00db | |||
| a60f8599d8 | |||
| 3a44ed7943 | |||
| e162408139 | |||
| 6fa61c0f9c | |||
| 264f91126e | |||
| ac5b5fb379 | |||
| d703fa6a3a | |||
| 2382140a12 | |||
| 7ba55697b9 | |||
| 2272d3da66 | |||
| 7e9e179860 | |||
| 31ba90b060 | |||
| c20f37975b | |||
| ecb8b8ff49 | |||
| 67c359a6dd | |||
| 1393f78005 | |||
| 63cf403eaf | |||
| 1e61a51e82 | |||
| 0330d01a49 | |||
| 595f35a1a5 | |||
| 943bfd9162 | |||
| 4a1598165f | |||
| fb11f5870e | |||
| 4b4e021a04 | |||
| 440d2d7c76 | |||
| 86e15954c5 | |||
| 9a55f17b42 | |||
| 7ae25f3cc6 | |||
| 787a812f8e | |||
| c540bff62b | |||
| f3da3a42e8 | |||
| f501c6206e | |||
| 0aedbd7fd7 | |||
| f042e7e178 | |||
| b39b361440 | |||
| 9499b062d0 | |||
| f9676270f2 | |||
| e3dc63f739 | |||
| d2dd7f78d3 | |||
| deae27bdae | |||
| 61e2cb37df | |||
| b9900c311d | |||
| 1afe48e732 | |||
| 198f0a64d0 | |||
| 41fe283a94 | |||
| 1f0d4723c6 | |||
| bc9bdc72f3 | |||
| 7bebe5fd4b | |||
| 3bd434091f | |||
| 1acbc91484 | |||
| b05fb21f2b | |||
| b61611ffd4 | |||
| 1447c183a4 | |||
| ed2ad4776b | |||
| 8542edc4f1 | |||
| d5126c8a0e | |||
| 939e8cf8df | |||
| 991f11cdf2 | |||
| 4fa015bddf | |||
| 39c71dfdbf | |||
| 3b68d3ff62 | |||
| 27d07be2b7 | |||
| 206a04bc05 | |||
| 78ab273dab | |||
| 530bc71924 | |||
| d082def664 | |||
| a4a6eb580b | |||
| e4249b9ff2 | |||
| 39694f78b1 | |||
| 0ec9b74a98 | |||
| 9b9fa600bc | |||
| ae2b72b5d2 | |||
| b8ae88b807 | |||
| 24784768f5 | |||
| a71b78531d | |||
| d988919448 | |||
| a7130bd61a | |||
| bfd23cdc14 | |||
| c7c0ae9d8d | |||
| c3927c6e10 | |||
| 8b4efe6cb8 | |||
| c1f6b6257d | |||
| e7a70f1e46 | |||
| 7ac73407c0 | |||
| 5505a0289b | |||
| 8fa5bd2372 | |||
| 829e1661f4 | |||
| e3770399e0 | |||
| defe421ffd | |||
| 03f8345246 | |||
| d73807a500 | |||
| 1f822a826b | |||
| 35fe594743 | |||
| 60e8c9399e | |||
| 87bdac6eac | |||
| 41a30dfd20 | |||
| a3239bf416 | |||
| f16b276b63 | |||
| f1ccc298ec | |||
| aa003054a5 | |||
| ee534a2415 | |||
| b4b563f15d | |||
| 43b4562ed2 | |||
| 00c618946c | |||
| cbdfd588fa | |||
| 0da398fd04 | |||
| 6165e61048 | |||
| 3ebb4d7c8d | |||
| 9e02a69528 | |||
| 674d6e7c95 | |||
| 5dc46b412c | |||
| a6134a3e1f | |||
| bd1bcaa43f | |||
| f9847a0099 | |||
| 598515868c | |||
| d857293372 | |||
| e59b7b7552 | |||
| eec4a9ab72 | |||
| 9a95f55b9c | |||
| f71d8332e0 | |||
| 3dffcadc03 | |||
| fab0c02ba0 | |||
| c4857564f3 | |||
| c7c74de4b8 | |||
| 08b68d4d87 | |||
| 93e877f086 | |||
| 82430b50c6 |
34
.env
34
.env
@ -1,34 +0,0 @@
|
||||
SECRET="ch4n63m31fy0uc4n"
|
||||
LOCALE=en
|
||||
|
||||
SERVER_NAME="Your wallabag instance"
|
||||
DOMAIN_NAME=http://127.0.0.1:8000
|
||||
|
||||
DATABASE_URL=sqlite:///%kernel.project_dir%/data/db/wallabag.sqlite?charset=utf8
|
||||
#DATABASE_URL=mysql://root:wallaroot@mariadb:3306/wallabag?charset=utf8mb4
|
||||
#DATABASE_URL=postgres://wallabag:wallapass@postgres:5432/wallabag?charset=utf8
|
||||
DATABASE_TABLE_PREFIX=wallabag_
|
||||
|
||||
FOSUSER_REGISTRATION=false
|
||||
FOSUSER_CONFIRMATION=true
|
||||
|
||||
FOS_OAUTH_SERVER_ACCESS_TOKEN_LIFETIME=3600
|
||||
FOS_OAUTH_SERVER_REFRESH_TOKEN_LIFETIME=1209600
|
||||
TWOFACTOR_SENDER=no-reply@wallabag.org
|
||||
|
||||
MAILER_DSN=smtp://127.0.0.1
|
||||
FROM_EMAIL=wallabag@example.com
|
||||
|
||||
RABBITMQ_HOST=rabbitmq
|
||||
RABBITMQ_PORT=5672
|
||||
RABBITMQ_USER=guest
|
||||
RABBITMQ_PASSWORD=guest
|
||||
|
||||
REDIS_SCHEME=tcp
|
||||
REDIS_HOST=redis
|
||||
REDIS_PORT=6379
|
||||
REDIS_PATH=
|
||||
REDIS_PASSWORD=
|
||||
RABBITMQ_PREFETCH_COUNT=10
|
||||
|
||||
SENTRY_DSN=
|
||||
@ -1,4 +0,0 @@
|
||||
DATABASE_URL=sqlite:///%kernel.project_dir%/data/db/wallabag_test.sqlite?charset=utf8
|
||||
#DATABASE_URL=mysql://root:wallaroot@mariadb:3306/wallabag_test?charset=utf8mb4
|
||||
#DATABASE_URL=postgres://wallabag:wallapass@postgres:5432/wallabag_test?charset=utf8
|
||||
FOSUSER_REGISTRATION=true
|
||||
2
.github/CONTRIBUTING.md
vendored
2
.github/CONTRIBUTING.md
vendored
@ -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)
|
||||
|
||||
33
.github/ISSUE_TEMPLATE/2-bug-report.md
vendored
33
.github/ISSUE_TEMPLATE/2-bug-report.md
vendored
@ -17,7 +17,7 @@ Installation: How did you install wallabag? Using git clone, the docker image, a
|
||||
PHP version: The version of PHP you are using
|
||||
OS: The host running wallabag
|
||||
Database: The storage system your instance is using (SQLite, MySQL/MariaDB or PostgreSQL) with the version
|
||||
Parameters: Put the content of your environment variables (hide sensitive stuff if you want)
|
||||
Parameters: Paste the content of your app/config/parameters.yml (hide sensitive stuff if you want)
|
||||
-->
|
||||
### Environment
|
||||
|
||||
@ -29,37 +29,10 @@ Parameters: Put the content of your environment variables (hide sensitive stuf
|
||||
* **Parameters**:
|
||||
|
||||
<details>
|
||||
<summary>My environment variables are:</summary>
|
||||
<summary>My <code>app/config/parameters.yml</code> is:</summary>
|
||||
|
||||
```
|
||||
LOCALE=
|
||||
|
||||
# Make sure to hide username and password below, if any
|
||||
DATABASE_URL=
|
||||
DATABASE_TABLE_PREFIX=
|
||||
|
||||
FOSUSER_REGISTRATION=
|
||||
FOSUSER_CONFIRMATION=
|
||||
|
||||
FOS_OAUTH_SERVER_ACCESS_TOKEN_LIFETIME=
|
||||
FOS_OAUTH_SERVER_REFRESH_TOKEN_LIFETIME=
|
||||
TWOFACTOR_SENDER=
|
||||
|
||||
# Make sure to hide username and password below, if any
|
||||
MAILER_DSN=
|
||||
FROM_EMAIL=
|
||||
|
||||
RABBITMQ_HOST=
|
||||
RABBITMQ_PORT=
|
||||
|
||||
REDIS_SCHEME=
|
||||
REDIS_HOST=
|
||||
REDIS_PORT=
|
||||
REDIS_PATH=
|
||||
RABBITMQ_PREFETCH_COUNT=
|
||||
|
||||
# Make sure to hide username and password below, if any
|
||||
SENTRY_DSN=
|
||||
PASTE HERE
|
||||
```
|
||||
</details>
|
||||
|
||||
|
||||
9
.github/dependabot.yml
vendored
9
.github/dependabot.yml
vendored
@ -21,7 +21,7 @@ updates:
|
||||
- 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:
|
||||
|
||||
6
.github/workflows/coding-standards.yml
vendored
6
.github/workflows/coding-standards.yml
vendored
@ -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"
|
||||
@ -40,7 +40,7 @@ jobs:
|
||||
run: |
|
||||
sudo systemctl start mysql.service
|
||||
sudo mysql -u root -proot -h 127.0.0.1 -e "CREATE DATABASE wallabag_test"
|
||||
cp app/config/tests/.env.mysql .env.test.local
|
||||
cp app/config/tests/parameters_test.mysql.yml app/config/parameters_test.yml
|
||||
|
||||
- name: "Install dependencies with Composer"
|
||||
id: composer-install
|
||||
|
||||
18
.github/workflows/continuous-integration.yml
vendored
18
.github/workflows/continuous-integration.yml
vendored
@ -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"
|
||||
@ -89,14 +86,14 @@ jobs:
|
||||
run: yarn build:dev
|
||||
|
||||
- name: "Prepare database configuration"
|
||||
run: cp app/config/tests/.env.${{ matrix.database }} .env.test.local
|
||||
run: cp app/config/tests/parameters_test.${{ matrix.database }}.yml app/config/parameters_test.yml
|
||||
|
||||
- name: "Run PHPUnit"
|
||||
run: "php bin/phpunit -v"
|
||||
|
||||
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
|
||||
@ -140,7 +137,8 @@ jobs:
|
||||
|
||||
- name: "Remove database prefix"
|
||||
run: |
|
||||
sed -i 's/DATABASE_TABLE_PREFIX=wallabag_/DATABASE_TABLE_PREFIX=/' .env
|
||||
pip install --user yq
|
||||
yq -Y --in-place '.parameters.database_table_prefix = ""' app/config/parameters.yml.dist
|
||||
|
||||
- name: "Setup MySQL"
|
||||
if: "${{ matrix.database == 'mysql' }}"
|
||||
@ -168,14 +166,14 @@ jobs:
|
||||
run: yarn build:dev
|
||||
|
||||
- name: "Prepare database configuration"
|
||||
run: cp app/config/tests/.env.${{ matrix.database }} .env.test.local
|
||||
run: cp app/config/tests/parameters_test.${{ matrix.database }}.yml app/config/parameters_test.yml
|
||||
|
||||
- name: "Run PHPUnit"
|
||||
run: "php bin/phpunit -v"
|
||||
|
||||
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
|
||||
@ -234,7 +232,7 @@ jobs:
|
||||
run: yarn build:dev
|
||||
|
||||
- name: "Prepare database configuration"
|
||||
run: cp app/config/tests/.env.${{ matrix.database }} .env.test.local
|
||||
run: cp app/config/tests/parameters_test.${{ matrix.database }}.yml app/config/parameters_test.yml
|
||||
|
||||
- name: "Run PHPUnit"
|
||||
run: "php bin/phpunit -v"
|
||||
|
||||
@ -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
|
||||
|
||||
4
.github/workflows/translations.yml
vendored
4
.github/workflows/translations.yml
vendored
@ -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"
|
||||
|
||||
2
.github/workflows/upload-release-package.yml
vendored
2
.github/workflows/upload-release-package.yml
vendored
@ -12,7 +12,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
php:
|
||||
- "7.4"
|
||||
- "8.2"
|
||||
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@ -17,6 +17,9 @@
|
||||
phpunit.xml
|
||||
compose.override.yaml
|
||||
|
||||
# Parameters
|
||||
/app/config/parameters.yml
|
||||
|
||||
# Managed by Composer
|
||||
/vendor/
|
||||
|
||||
|
||||
@ -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',
|
||||
],
|
||||
|
||||
42
CHANGELOG.md
42
CHANGELOG.md
@ -2,8 +2,50 @@
|
||||
|
||||
## 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.13](https://github.com/wallabag/wallabag/tree/2.6.13)
|
||||
[Full Changelog](https://github.com/wallabag/wallabag/compare/2.6.12...2.6.13)
|
||||
|
||||
### Improvements
|
||||
|
||||
* Add support of Pocket CSV import by @kdecherf and @nicosomb in [https://github.com/wallabag/wallabag/pull/8240](https://github.com/wallabag/wallabag/pull/8240)
|
||||
* Backport Pocket and Shaarli HTML imports from master by @nicosomb in [https://github.com/wallabag/wallabag/pull/8193](https://github.com/wallabag/wallabag/pull/8193)
|
||||
|
||||
### Fixes
|
||||
|
||||
* Avoid non-validated OTP to be enabled #8139 by @j0k3r in [https://github.com/wallabag/wallabag/pull/8139](https://github.com/wallabag/wallabag/pull/8139)
|
||||
|
||||
### Technical stuff
|
||||
|
||||
* Update j0k3r/php-readability:1.2.13 to fix regression (about latin1 instead of UTF-8 used for entries) by @nicosomb [https://github.com/wallabag/wallabag/pull/8194](https://github.com/wallabag/wallabag/pull/8194)
|
||||
|
||||
## [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)
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,26 +98,19 @@ class AppKernel extends Kernel
|
||||
|
||||
public function registerContainerConfiguration(LoaderInterface $loader)
|
||||
{
|
||||
if (file_exists($this->getProjectDir() . '/app/config/parameters.yml')) {
|
||||
$loader->load($this->getProjectDir() . '/app/config/parameters.yml');
|
||||
|
||||
@trigger_error('The "app/config/parameters.yml" file is deprecated and will not be supported in a future version. Move your configuration to environment variables and remove the file.', \E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
$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);
|
||||
});
|
||||
|
||||
if (file_exists($this->getProjectDir() . '/app/config/parameters.yml')) {
|
||||
$loader->load(function (ContainerBuilder $container) {
|
||||
$this->loadEnvVarsFromParameters($container);
|
||||
$this->defineDatabaseUrlEnvVar($container);
|
||||
});
|
||||
}
|
||||
$loader->load(function (ContainerBuilder $container): void {
|
||||
$this->processDatabaseParameters($container);
|
||||
$this->defineRedisUrlEnvVar($container);
|
||||
$this->defineRabbitMqUrlEnvVar($container);
|
||||
});
|
||||
}
|
||||
|
||||
protected function build(ContainerBuilder $container)
|
||||
@ -94,93 +118,65 @@ class AppKernel extends Kernel
|
||||
$container->addCompilerPass(new ImportCompilerPass());
|
||||
}
|
||||
|
||||
private function loadEnvVarsFromParameters(ContainerBuilder $container)
|
||||
private function processDatabaseParameters(ContainerBuilder $container)
|
||||
{
|
||||
$this->setEnvVarFromParameter($container, 'DATABASE_TABLE_PREFIX', 'database_table_prefix');
|
||||
$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')),
|
||||
};
|
||||
|
||||
$this->setEnvVarFromParameter($container, 'DOMAIN_NAME', 'domain_name');
|
||||
$this->setEnvVarFromParameter($container, 'SERVER_NAME', 'server_name');
|
||||
$this->setEnvVarFromParameter($container, 'MAILER_DSN', 'mailer_dsn');
|
||||
$this->setEnvVarFromParameter($container, 'LOCALE', 'locale');
|
||||
$this->setEnvVarFromParameter($container, 'SECRET', 'secret');
|
||||
|
||||
$this->setEnvVarFromParameter($container, 'TWOFACTOR_SENDER', 'twofactor_sender');
|
||||
$this->setEnvVarFromParameter($container, 'FOSUSER_REGISTRATION', 'fosuser_registration');
|
||||
$this->setEnvVarFromParameter($container, 'FOSUSER_CONFIRMATION', 'fosuser_confirmation');
|
||||
$this->setEnvVarFromParameter($container, 'FOS_OAUTH_SERVER_ACCESS_TOKEN_LIFETIME', 'fos_oauth_server_access_token_lifetime');
|
||||
$this->setEnvVarFromParameter($container, 'FOS_OAUTH_SERVER_REFRESH_TOKEN_LIFETIME', 'fos_oauth_server_refresh_token_lifetime');
|
||||
$this->setEnvVarFromParameter($container, 'FROM_EMAIL', 'from_email');
|
||||
|
||||
$this->setEnvVarFromParameter($container, 'RABBITMQ_HOST', 'rabbitmq_host');
|
||||
$this->setEnvVarFromParameter($container, 'RABBITMQ_PORT', 'rabbitmq_port');
|
||||
$this->setEnvVarFromParameter($container, 'RABBITMQ_USER', 'rabbitmq_user');
|
||||
$this->setEnvVarFromParameter($container, 'RABBITMQ_PASSWORD', 'rabbitmq_password');
|
||||
$this->setEnvVarFromParameter($container, 'RABBITMQ_PREFETCH_COUNT', 'rabbitmq_prefetch_count');
|
||||
|
||||
$this->setEnvVarFromParameter($container, 'REDIS_SCHEME', 'redis_scheme');
|
||||
$this->setEnvVarFromParameter($container, 'REDIS_HOST', 'redis_host');
|
||||
$this->setEnvVarFromParameter($container, 'REDIS_PORT', 'redis_port');
|
||||
$this->setEnvVarFromParameter($container, 'REDIS_PATH', 'redis_path');
|
||||
$this->setEnvVarFromParameter($container, 'REDIS_PASSWORD', 'redis_password');
|
||||
|
||||
$this->setEnvVarFromParameter($container, 'SENTRY_DSN', 'sentry_dsn');
|
||||
}
|
||||
|
||||
private function setEnvVarFromParameter(ContainerBuilder $container, string $envVar, string $parameter)
|
||||
{
|
||||
$_ENV[$envVar] = $_SERVER[$envVar] = (string) $container->getParameter($parameter);
|
||||
$container->setParameter('env(' . $envVar . ')', (string) $container->getParameter($parameter));
|
||||
}
|
||||
|
||||
private function defineDatabaseUrlEnvVar(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'));
|
||||
}
|
||||
|
||||
$user = $container->getParameter('database_user');
|
||||
$password = $container->getParameter('database_password');
|
||||
$host = $container->getParameter('database_host');
|
||||
$port = $container->getParameter('database_port');
|
||||
$name = $container->getParameter('database_name');
|
||||
$container->setParameter('database_scheme', $scheme);
|
||||
|
||||
if ('sqlite' === $scheme) {
|
||||
$name = $container->getParameter('database_path');
|
||||
$container->setParameter('database_name', $container->getParameter('database_path'));
|
||||
}
|
||||
|
||||
$url = $scheme . '://' . $user . ':' . $password . '@' . $host;
|
||||
$container->setParameter('database_user', (string) $container->getParameter('database_user'));
|
||||
$container->setParameter('database_password', (string) $container->getParameter('database_password'));
|
||||
$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 .= '/' . $name;
|
||||
$url .= '/' . ltrim($path, '/');
|
||||
|
||||
$query = [];
|
||||
$container->setParameter('env(REDIS_URL)', $url);
|
||||
}
|
||||
|
||||
if ($container->getParameter('database_socket')) {
|
||||
$query['unix_socket'] = $container->getParameter('database_socket');
|
||||
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;
|
||||
}
|
||||
|
||||
if ($container->getParameter('database_charset')) {
|
||||
$query['charset'] = $container->getParameter('database_charset');
|
||||
}
|
||||
|
||||
if ([] !== $query) {
|
||||
$url .= '?' . http_build_query($query);
|
||||
}
|
||||
|
||||
$_ENV['DATABASE_URL'] = $_SERVER['DATABASE_URL'] = $url;
|
||||
$container->setParameter('env(DATABASE_URL)', $url);
|
||||
$container->setParameter('env(RABBITMQ_URL)', $url);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,18 +1,20 @@
|
||||
imports:
|
||||
- { resource: parameters.yml }
|
||||
- { resource: security.yml }
|
||||
- { resource: services.yml }
|
||||
- { resource: wallabag.yml }
|
||||
|
||||
parameters:
|
||||
craue_config.cache_adapter.class: Craue\ConfigBundle\CacheAdapter\SymfonyCacheComponentAdapter
|
||||
env(DATABASE_URL): '%database_scheme%://%database_user%:%database_password%@%database_host%:%database_port%/%database_name%?unix_socket=%database_socket%&charset=%database_charset%'
|
||||
|
||||
framework:
|
||||
#esi: ~
|
||||
translator:
|
||||
enabled: true
|
||||
fallback: "%env(LOCALE)%"
|
||||
fallback: "%locale%"
|
||||
default_path: '%kernel.project_dir%/translations'
|
||||
secret: "%env(SECRET)%"
|
||||
secret: "%secret%"
|
||||
router:
|
||||
resource: "%kernel.project_dir%/app/config/routing.yml"
|
||||
strict_requirements: ~
|
||||
@ -20,20 +22,22 @@ framework:
|
||||
csrf_protection: ~
|
||||
validation:
|
||||
enable_annotations: true
|
||||
default_locale: "%env(LOCALE)%"
|
||||
default_locale: "%locale%"
|
||||
trusted_hosts: ~
|
||||
session:
|
||||
# handler_id set to null will use default session handler from php.ini
|
||||
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:
|
||||
base_url: '%env(DOMAIN_NAME)%'
|
||||
base_url: '%domain_name%'
|
||||
json_manifest_path: '%kernel.project_dir%/web/build/manifest.json'
|
||||
mailer:
|
||||
dsn: "%env(MAILER_DSN)%"
|
||||
dsn: "%mailer_dsn%"
|
||||
http_client:
|
||||
scoped_clients:
|
||||
download_images.client:
|
||||
@ -58,8 +62,8 @@ twig:
|
||||
form_themes:
|
||||
- "@SpiriitFormFilter/Form/form_div_layout.html.twig"
|
||||
globals:
|
||||
wallabag_url: '%env(DOMAIN_NAME)%'
|
||||
registration_enabled: '%env(bool:FOSUSER_REGISTRATION)%'
|
||||
wallabag_url: '%domain_name%'
|
||||
registration_enabled: '%fosuser_registration%'
|
||||
|
||||
# Doctrine Configuration
|
||||
doctrine:
|
||||
@ -75,14 +79,14 @@ doctrine:
|
||||
auto_mapping: true
|
||||
mappings:
|
||||
Wallabag:
|
||||
type: annotation
|
||||
type: attribute
|
||||
is_bundle: false
|
||||
dir: '%kernel.project_dir%/src/Entity'
|
||||
prefix: 'Wallabag\Entity'
|
||||
alias: Wallabag
|
||||
|
||||
stof_doctrine_extensions:
|
||||
default_locale: "%env(LOCALE)%"
|
||||
default_locale: "%locale%"
|
||||
translation_fallback: true
|
||||
orm:
|
||||
default:
|
||||
@ -190,12 +194,12 @@ fos_user:
|
||||
user_class: Wallabag\Entity\User
|
||||
registration:
|
||||
confirmation:
|
||||
enabled: "%env(bool:FOSUSER_CONFIRMATION)%"
|
||||
enabled: "%fosuser_confirmation%"
|
||||
from_email:
|
||||
address: "%env(FROM_EMAIL)%"
|
||||
address: "%from_email%"
|
||||
sender_name: wallabag
|
||||
service:
|
||||
mailer: Wallabag\Mailer\UserMailer
|
||||
mailer: fos_user.mailer.twig_symfony
|
||||
|
||||
fos_oauth_server:
|
||||
db_driver: orm
|
||||
@ -206,8 +210,8 @@ fos_oauth_server:
|
||||
service:
|
||||
user_provider: fos_user.user_provider.username_email
|
||||
options:
|
||||
refresh_token_lifetime: "%env(FOS_OAUTH_SERVER_REFRESH_TOKEN_LIFETIME)%"
|
||||
access_token_lifetime: "%env(FOS_OAUTH_SERVER_ACCESS_TOKEN_LIFETIME)%"
|
||||
refresh_token_lifetime: "%fos_oauth_server_refresh_token_lifetime%"
|
||||
access_token_lifetime: "%fos_oauth_server_access_token_lifetime%"
|
||||
|
||||
scheb_two_factor:
|
||||
trusted_device:
|
||||
@ -220,29 +224,21 @@ scheb_two_factor:
|
||||
|
||||
google:
|
||||
enabled: true
|
||||
issuer: "%env(SERVER_NAME)%"
|
||||
issuer: "%server_name%"
|
||||
template: "Authentication/form.html.twig"
|
||||
|
||||
email:
|
||||
enabled: true
|
||||
sender_email: "%env(TWOFACTOR_SENDER)%"
|
||||
sender_email: "%twofactor_sender%"
|
||||
digits: 6
|
||||
template: "Authentication/form.html.twig"
|
||||
mailer: Wallabag\Mailer\AuthCodeMailer
|
||||
|
||||
rulerz:
|
||||
targets:
|
||||
doctrine: true
|
||||
|
||||
old_sound_rabbit_mq:
|
||||
connections:
|
||||
default:
|
||||
host: "%env(RABBITMQ_HOST)%"
|
||||
port: "%env(int:RABBITMQ_PORT)%"
|
||||
user: "%env(RABBITMQ_USER)%"
|
||||
password: "%env(RABBITMQ_PASSWORD)%"
|
||||
vhost: /
|
||||
lazy: true
|
||||
url: "%env(RABBITMQ_URL)%"
|
||||
lazy: true
|
||||
producers:
|
||||
import_pocket:
|
||||
connection: default
|
||||
@ -309,6 +305,11 @@ old_sound_rabbit_mq:
|
||||
exchange_options:
|
||||
name: 'wallabag.import.pocket_html'
|
||||
type: topic
|
||||
import_pocket_csv:
|
||||
connection: default
|
||||
exchange_options:
|
||||
name: 'wallabag.import.pocket_csv'
|
||||
type: topic
|
||||
consumers:
|
||||
import_pocket:
|
||||
connection: default
|
||||
@ -318,7 +319,7 @@ old_sound_rabbit_mq:
|
||||
queue_options:
|
||||
name: 'wallabag.import.pocket'
|
||||
callback: wallabag.consumer.amqp.pocket
|
||||
qos_options: {prefetch_count: "%env(int:RABBITMQ_PREFETCH_COUNT)%"}
|
||||
qos_options: {prefetch_count: "%rabbitmq_prefetch_count%"}
|
||||
import_readability:
|
||||
connection: default
|
||||
exchange_options:
|
||||
@ -327,7 +328,7 @@ old_sound_rabbit_mq:
|
||||
queue_options:
|
||||
name: 'wallabag.import.readability'
|
||||
callback: wallabag.consumer.amqp.readability
|
||||
qos_options: {prefetch_count: "%env(int:RABBITMQ_PREFETCH_COUNT)%"}
|
||||
qos_options: {prefetch_count: "%rabbitmq_prefetch_count%"}
|
||||
import_instapaper:
|
||||
connection: default
|
||||
exchange_options:
|
||||
@ -336,7 +337,7 @@ old_sound_rabbit_mq:
|
||||
queue_options:
|
||||
name: 'wallabag.import.instapaper'
|
||||
callback: wallabag.consumer.amqp.instapaper
|
||||
qos_options: {prefetch_count: "%env(int:RABBITMQ_PREFETCH_COUNT)%"}
|
||||
qos_options: {prefetch_count: "%rabbitmq_prefetch_count%"}
|
||||
import_pinboard:
|
||||
connection: default
|
||||
exchange_options:
|
||||
@ -345,7 +346,7 @@ old_sound_rabbit_mq:
|
||||
queue_options:
|
||||
name: 'wallabag.import.pinboard'
|
||||
callback: wallabag.consumer.amqp.pinboard
|
||||
qos_options: {prefetch_count: "%env(int:RABBITMQ_PREFETCH_COUNT)%"}
|
||||
qos_options: {prefetch_count: "%rabbitmq_prefetch_count%"}
|
||||
import_delicious:
|
||||
connection: default
|
||||
exchange_options:
|
||||
@ -354,7 +355,7 @@ old_sound_rabbit_mq:
|
||||
queue_options:
|
||||
name: 'wallabag.import.delicious'
|
||||
callback: wallabag.consumer.amqp.delicious
|
||||
qos_options: {prefetch_count: "%env(int:RABBITMQ_PREFETCH_COUNT)%"}
|
||||
qos_options: {prefetch_count: "%rabbitmq_prefetch_count%"}
|
||||
import_wallabag_v1:
|
||||
connection: default
|
||||
exchange_options:
|
||||
@ -363,7 +364,7 @@ old_sound_rabbit_mq:
|
||||
queue_options:
|
||||
name: 'wallabag.import.wallabag_v1'
|
||||
callback: wallabag.consumer.amqp.wallabag_v1
|
||||
qos_options: {prefetch_count: "%env(int:RABBITMQ_PREFETCH_COUNT)%"}
|
||||
qos_options: {prefetch_count: "%rabbitmq_prefetch_count%"}
|
||||
import_wallabag_v2:
|
||||
connection: default
|
||||
exchange_options:
|
||||
@ -372,7 +373,7 @@ old_sound_rabbit_mq:
|
||||
queue_options:
|
||||
name: 'wallabag.import.wallabag_v2'
|
||||
callback: wallabag.consumer.amqp.wallabag_v2
|
||||
qos_options: {prefetch_count: "%env(int:RABBITMQ_PREFETCH_COUNT)%"}
|
||||
qos_options: {prefetch_count: "%rabbitmq_prefetch_count%"}
|
||||
import_elcurator:
|
||||
connection: default
|
||||
exchange_options:
|
||||
@ -381,7 +382,7 @@ old_sound_rabbit_mq:
|
||||
queue_options:
|
||||
name: 'wallabag.import.elcurator'
|
||||
callback: wallabag.consumer.amqp.elcurator
|
||||
qos_options: {prefetch_count: "%env(int:RABBITMQ_PREFETCH_COUNT)%"}
|
||||
qos_options: {prefetch_count: "%rabbitmq_prefetch_count%"}
|
||||
import_omnivore:
|
||||
connection: default
|
||||
exchange_options:
|
||||
@ -390,7 +391,7 @@ old_sound_rabbit_mq:
|
||||
queue_options:
|
||||
name: 'wallabag.import.omnivore'
|
||||
callback: wallabag.consumer.amqp.omnivore
|
||||
qos_options: {prefetch_count: "%env(int:RABBITMQ_PREFETCH_COUNT)%"}
|
||||
qos_options: {prefetch_count: "%rabbitmq_prefetch_count%"}
|
||||
import_firefox:
|
||||
connection: default
|
||||
exchange_options:
|
||||
@ -399,7 +400,7 @@ old_sound_rabbit_mq:
|
||||
queue_options:
|
||||
name: 'wallabag.import.firefox'
|
||||
callback: wallabag.consumer.amqp.firefox
|
||||
qos_options: {prefetch_count: "%env(int:RABBITMQ_PREFETCH_COUNT)%"}
|
||||
qos_options: {prefetch_count: "%rabbitmq_prefetch_count%"}
|
||||
import_chrome:
|
||||
connection: default
|
||||
exchange_options:
|
||||
@ -408,7 +409,7 @@ old_sound_rabbit_mq:
|
||||
queue_options:
|
||||
name: 'wallabag.import.chrome'
|
||||
callback: wallabag.consumer.amqp.chrome
|
||||
qos_options: {prefetch_count: "%env(int:RABBITMQ_PREFETCH_COUNT)%"}
|
||||
qos_options: {prefetch_count: "%rabbitmq_prefetch_count%"}
|
||||
import_shaarli:
|
||||
connection: default
|
||||
exchange_options:
|
||||
@ -417,7 +418,7 @@ old_sound_rabbit_mq:
|
||||
queue_options:
|
||||
name: 'wallabag.import.shaarli'
|
||||
callback: wallabag.consumer.amqp.shaarli
|
||||
qos_options: {prefetch_count: "%env(int:RABBITMQ_PREFETCH_COUNT)%"}
|
||||
qos_options: {prefetch_count: "%rabbitmq_prefetch_count%"}
|
||||
import_pocket_html:
|
||||
connection: default
|
||||
exchange_options:
|
||||
@ -426,7 +427,16 @@ old_sound_rabbit_mq:
|
||||
queue_options:
|
||||
name: 'wallabag.import.pocket_html'
|
||||
callback: wallabag.consumer.amqp.pocket_html
|
||||
qos_options: {prefetch_count: "%env(int:RABBITMQ_PREFETCH_COUNT)%"}
|
||||
qos_options: {prefetch_count: "%rabbitmq_prefetch_count%"}
|
||||
import_pocket_csv:
|
||||
connection: default
|
||||
exchange_options:
|
||||
name: 'wallabag.import.pocket_csv'
|
||||
type: topic
|
||||
queue_options:
|
||||
name: 'wallabag.import.pocket_csv'
|
||||
callback: wallabag.consumer.amqp.pocket_csv
|
||||
qos_options: {prefetch_count: "%rabbitmq_prefetch_count%"}
|
||||
|
||||
fos_js_routing:
|
||||
routes_to_expose:
|
||||
|
||||
@ -21,4 +21,4 @@ monolog:
|
||||
type: console
|
||||
|
||||
sentry:
|
||||
dsn: "%env(SENTRY_DSN)%"
|
||||
dsn: "%sentry_dsn%"
|
||||
|
||||
@ -1,16 +1,16 @@
|
||||
imports:
|
||||
- { resource: config_dev.yml }
|
||||
- { resource: parameters_test.yml }
|
||||
- { resource: services_test.yml }
|
||||
|
||||
parameters:
|
||||
fosuser_registration: '%env(FOSUSER_REGISTRATION)%'
|
||||
database_url: '%env(resolve:DATABASE_URL)%'
|
||||
domain_name: '%env(DOMAIN_NAME)%'
|
||||
fosuser_registration: true
|
||||
wallabag_dbname_suffix: '_test'
|
||||
|
||||
framework:
|
||||
test: ~
|
||||
session:
|
||||
storage_id: session.storage.mock_file
|
||||
storage_factory_id: session.storage.factory.mock_file
|
||||
profiler:
|
||||
collect: false
|
||||
translator:
|
||||
@ -24,6 +24,7 @@ web_profiler:
|
||||
|
||||
doctrine:
|
||||
dbal:
|
||||
dbname_suffix: '%wallabag_dbname_suffix%' # for MySQL and PostgreSQL
|
||||
use_savepoints: true
|
||||
|
||||
orm:
|
||||
|
||||
65
app/config/parameters.yml.dist
Normal file
65
app/config/parameters.yml.dist
Normal file
@ -0,0 +1,65 @@
|
||||
# This file is a "template" of what your parameters.yml file should look like
|
||||
parameters:
|
||||
# Uncomment these settings or manually update your parameters.yml
|
||||
# to use Docker Compose
|
||||
#
|
||||
# database_driver: %env.database_driver%
|
||||
# database_host: %env.database_host%
|
||||
# database_port: %env.database_port%
|
||||
# database_name: %env.database_name%
|
||||
# database_user: %env.database_user%
|
||||
# database_password: %env.database_password%
|
||||
|
||||
database_driver: pdo_mysql
|
||||
database_host: 127.0.0.1
|
||||
database_port: ~
|
||||
database_name: wallabag
|
||||
database_user: root
|
||||
database_password: ~
|
||||
# For SQLite, database_path should be "%kernel.project_dir%/data/db/wallabag.sqlite"
|
||||
database_path: null
|
||||
database_table_prefix: wallabag_
|
||||
database_socket: null
|
||||
# with PostgreSQL and SQLite, you must set "utf8"
|
||||
database_charset: utf8mb4
|
||||
|
||||
domain_name: https://your-wallabag-instance.wallabag.org
|
||||
server_name: "Your wallabag instance"
|
||||
|
||||
mailer_dsn: smtp://127.0.0.1
|
||||
|
||||
locale: en
|
||||
|
||||
# A secret key that's used to generate certain security-related tokens
|
||||
secret: CHANGE_ME_TO_SOMETHING_SECRET_AND_RANDOM
|
||||
|
||||
# two factor stuff
|
||||
twofactor_sender: no-reply@wallabag.org
|
||||
|
||||
# fosuser stuff
|
||||
fosuser_registration: false
|
||||
fosuser_confirmation: true
|
||||
|
||||
# how long the access token should live in seconds for the API
|
||||
fos_oauth_server_access_token_lifetime: 3600
|
||||
# how long the refresh token should life in seconds for the API
|
||||
fos_oauth_server_refresh_token_lifetime: 1209600
|
||||
|
||||
from_email: no-reply@wallabag.org
|
||||
|
||||
# RabbitMQ processing
|
||||
rabbitmq_host: localhost
|
||||
rabbitmq_port: 5672
|
||||
rabbitmq_user: guest
|
||||
rabbitmq_password: guest
|
||||
rabbitmq_prefetch_count: 10
|
||||
|
||||
# Redis processing
|
||||
redis_scheme: redis
|
||||
redis_host: localhost
|
||||
redis_port: 6379
|
||||
redis_path: null
|
||||
redis_password: null
|
||||
|
||||
# sentry logging
|
||||
sentry_dsn: ~
|
||||
2
app/config/parameters_test.yml
Normal file
2
app/config/parameters_test.yml
Normal file
@ -0,0 +1,2 @@
|
||||
parameters:
|
||||
database_path: "%kernel.project_dir%/data/db/wallabag%wallabag_dbname_suffix%.sqlite"
|
||||
@ -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
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
security:
|
||||
encoders:
|
||||
password_hashers:
|
||||
FOS\UserBundle\Model\UserInterface: sha512
|
||||
|
||||
role_hierarchy:
|
||||
@ -45,7 +45,7 @@ security:
|
||||
|
||||
anonymous: true
|
||||
remember_me:
|
||||
secret: "%env(SECRET)%"
|
||||
secret: "%secret%"
|
||||
lifetime: 31536000
|
||||
path: /
|
||||
domain: ~
|
||||
@ -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 }
|
||||
|
||||
@ -15,15 +15,15 @@ services:
|
||||
$projectDir: '%kernel.project_dir%'
|
||||
$debug: '%kernel.debug%'
|
||||
$defaultLocale: '%kernel.default_locale%'
|
||||
$wallabagUrl: '%env(DOMAIN_NAME)%'
|
||||
$tablePrefix: "%env(DATABASE_TABLE_PREFIX)%"
|
||||
$wallabagUrl: '%domain_name%'
|
||||
$tablePrefix: "%database_table_prefix%"
|
||||
$encryptionKeyPath: "%wallabag.site_credentials.encryption_key_path%"
|
||||
$fetchingErrorMessageTitle: "%wallabag.fetching_error_message_title%"
|
||||
$fetchingErrorMessage: '%wallabag.fetching_error_message%'
|
||||
$languages: '%wallabag.languages%'
|
||||
$lifeTime: '%wallabag.cache_lifetime%'
|
||||
$logoPath: 'web/img/appicon/apple-touch-icon-152.png'
|
||||
$registrationEnabled: '%env(bool:FOSUSER_REGISTRATION)%'
|
||||
$registrationEnabled: '%fosuser_registration%'
|
||||
$restrictedAccess: '@=service(''craue_config'').get(''restricted_access'')'
|
||||
$senderEmail: "%scheb_two_factor.email.sender_email%"
|
||||
$senderName: "%scheb_two_factor.email.sender_name%"
|
||||
@ -108,6 +108,11 @@ services:
|
||||
$rabbitMqProducer: '@old_sound_rabbit_mq.import_pocket_html_producer'
|
||||
$redisProducer: '@wallabag.producer.redis.pocket_html'
|
||||
|
||||
Wallabag\Controller\Import\PocketCsvController:
|
||||
arguments:
|
||||
$rabbitMqProducer: '@old_sound_rabbit_mq.import_pocket_csv_producer'
|
||||
$redisProducer: '@wallabag.producer.redis.pocket_csv'
|
||||
|
||||
Wallabag\Doctrine\MigrationFactoryDecorator:
|
||||
decorates: doctrine.migrations.migrations_factory
|
||||
|
||||
@ -187,7 +192,7 @@ services:
|
||||
|
||||
Wallabag\Event\Subscriber\SchemaAdapterSubscriber:
|
||||
arguments:
|
||||
$databaseTablePrefix: "%env(DATABASE_TABLE_PREFIX)%"
|
||||
$databaseTablePrefix: "%database_table_prefix%"
|
||||
tags:
|
||||
- { name: doctrine.event_subscriber }
|
||||
|
||||
@ -230,30 +235,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: '%env(REDIS_SCHEME)%'
|
||||
host: '%env(REDIS_HOST)%'
|
||||
port: '%env(int:REDIS_PORT)%'
|
||||
path: '%env(REDIS_PATH)%'
|
||||
password: '%env(REDIS_PASSWORD)%'
|
||||
$parameters: '%env(REDIS_URL)%'
|
||||
|
||||
Wallabag\Event\Subscriber\SQLiteCascadeDeleteSubscriber:
|
||||
tags:
|
||||
@ -269,20 +261,10 @@ services:
|
||||
|
||||
Wallabag\Command\InstallCommand:
|
||||
arguments:
|
||||
$databaseUrl: '%env(DATABASE_URL)%'
|
||||
$databaseDriver: '%database_driver%'
|
||||
$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%"
|
||||
@ -351,6 +333,10 @@ services:
|
||||
tags:
|
||||
- { name: wallabag.import, alias: pocket_html }
|
||||
|
||||
Wallabag\Import\PocketCsvImport:
|
||||
tags:
|
||||
- { name: wallabag.import, alias: pocket_csv }
|
||||
|
||||
# to factorize the proximity and bypass translation for prev & next
|
||||
pagerfanta.view.default_wallabag:
|
||||
class: Pagerfanta\View\OptionableView
|
||||
|
||||
@ -20,6 +20,7 @@ services:
|
||||
$elcuratorConsumer: '@old_sound_rabbit_mq.import_elcurator_consumer'
|
||||
$shaarliConsumer: '@old_sound_rabbit_mq.import_shaarli_consumer'
|
||||
$pocketHtmlConsumer: '@old_sound_rabbit_mq.import_pocket_html_consumer'
|
||||
$pocketCsvConsumer: '@old_sound_rabbit_mq.import_pocket_csv_consumer'
|
||||
$omnivoreConsumer: '@old_sound_rabbit_mq.import_omnivore_consumer'
|
||||
|
||||
wallabag.consumer.amqp.pocket:
|
||||
@ -86,3 +87,8 @@ services:
|
||||
class: Wallabag\Consumer\AMQPEntryConsumer
|
||||
arguments:
|
||||
$import: '@Wallabag\Import\PocketHtmlImport'
|
||||
|
||||
wallabag.consumer.amqp.pocket_csv:
|
||||
class: Wallabag\Consumer\AMQPEntryConsumer
|
||||
arguments:
|
||||
$import: '@Wallabag\Import\PocketCsvImport'
|
||||
|
||||
@ -212,3 +212,19 @@ services:
|
||||
class: Wallabag\Consumer\RedisEntryConsumer
|
||||
arguments:
|
||||
$import: '@Wallabag\Import\PocketHtmlImport'
|
||||
|
||||
# pocket csv
|
||||
wallabag.queue.redis.pocket_csv:
|
||||
class: Simpleue\Queue\RedisQueue
|
||||
arguments:
|
||||
$queueName: "wallabag.import.pocket_csv"
|
||||
|
||||
wallabag.producer.redis.pocket_csv:
|
||||
class: Wallabag\Redis\Producer
|
||||
arguments:
|
||||
- "@wallabag.queue.redis.pocket_csv"
|
||||
|
||||
wallabag.consumer.redis.pocket_csv:
|
||||
class: Wallabag\Consumer\RedisEntryConsumer
|
||||
arguments:
|
||||
$import: '@Wallabag\Import\PocketCsvImport'
|
||||
|
||||
@ -1 +0,0 @@
|
||||
DATABASE_URL=mysql://root:root@127.0.0.1:3306/wallabag?charset=utf8mb4
|
||||
@ -1 +0,0 @@
|
||||
DATABASE_URL=postgres://wallabag:wallabagrocks@localhost/wallabag?charset=utf8
|
||||
@ -1 +0,0 @@
|
||||
DATABASE_URL=sqlite:///%kernel.project_dir%/data/db/wallabag.sqlite?charset=utf8
|
||||
2
app/config/tests/parameters_test.mysql.yml
Normal file
2
app/config/tests/parameters_test.mysql.yml
Normal file
@ -0,0 +1,2 @@
|
||||
parameters:
|
||||
env(DATABASE_URL): mysql://root:root@127.0.0.1:3306/wallabag?charset=utf8mb4
|
||||
2
app/config/tests/parameters_test.pgsql.yml
Normal file
2
app/config/tests/parameters_test.pgsql.yml
Normal file
@ -0,0 +1,2 @@
|
||||
parameters:
|
||||
env(DATABASE_URL): postgres://wallabag:wallabagrocks@localhost/wallabag?charset=utf8
|
||||
2
app/config/tests/parameters_test.sqlite.yml
Normal file
2
app/config/tests/parameters_test.sqlite.yml
Normal file
@ -0,0 +1,2 @@
|
||||
parameters:
|
||||
env(DATABASE_URL): sqlite:///%kernel.project_dir%/data/db/wallabag%wallabag_dbname_suffix%.sqlite?charset=utf8
|
||||
@ -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'
|
||||
@ -25,7 +25,7 @@ parameters:
|
||||
el: 'Ελληνικά'
|
||||
gl: 'Galego'
|
||||
wallabag.items_on_page: 12
|
||||
wallabag.language: '%env(LOCALE)%'
|
||||
wallabag.language: '%locale%'
|
||||
wallabag.feed_limit: 50
|
||||
wallabag.reading_speed: 200
|
||||
wallabag.cache_lifetime: 10
|
||||
@ -175,5 +175,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
11
assets/bootstrap.js
vendored
Normal 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
4
assets/controllers.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"controllers": [],
|
||||
"entrypoints": []
|
||||
}
|
||||
13
assets/controllers/add_tag_controller.js
Normal file
13
assets/controllers/add_tag_controller.js
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
57
assets/controllers/annotations_controller.js
Normal file
57
assets/controllers/annotations_controller.js
Normal 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();
|
||||
}
|
||||
}
|
||||
15
assets/controllers/batch_edit_controller.js
Normal file
15
assets/controllers/batch_edit_controller.js
Normal 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);
|
||||
}
|
||||
}
|
||||
16
assets/controllers/clipboard_controller.js
Normal file
16
assets/controllers/clipboard_controller.js
Normal 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();
|
||||
}
|
||||
}
|
||||
16
assets/controllers/config_controller.js
Normal file
16
assets/controllers/config_controller.js
Normal 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`;
|
||||
}
|
||||
}
|
||||
39
assets/controllers/dark_theme_controller.js
Normal file
39
assets/controllers/dark_theme_controller.js
Normal 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');
|
||||
}
|
||||
}
|
||||
}
|
||||
58
assets/controllers/entries_navigation_controller.js
Normal file
58
assets/controllers/entries_navigation_controller.js
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
13
assets/controllers/fake_radio_controller.js
Normal file
13
assets/controllers/fake_radio_controller.js
Normal 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;
|
||||
}
|
||||
}
|
||||
11
assets/controllers/highlight_controller.js
Normal file
11
assets/controllers/highlight_controller.js
Normal 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);
|
||||
});
|
||||
}
|
||||
}
|
||||
7
assets/controllers/leftbar_controller.js
Normal file
7
assets/controllers/leftbar_controller.js
Normal file
@ -0,0 +1,7 @@
|
||||
import { Controller } from '@hotwired/stimulus';
|
||||
|
||||
export default class extends Controller {
|
||||
toggleAddTagForm() {
|
||||
this.dispatch('toggleAddTagForm');
|
||||
}
|
||||
}
|
||||
16
assets/controllers/materialize/collapsible_controller.js
Normal file
16
assets/controllers/materialize/collapsible_controller.js
Normal 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();
|
||||
}
|
||||
}
|
||||
16
assets/controllers/materialize/dropdown_controller.js
Normal file
16
assets/controllers/materialize/dropdown_controller.js
Normal 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();
|
||||
}
|
||||
}
|
||||
32
assets/controllers/materialize/fab_controller.js
Normal file
32
assets/controllers/materialize/fab_controller.js
Normal 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();
|
||||
}
|
||||
}
|
||||
12
assets/controllers/materialize/form_select_controller.js
Normal file
12
assets/controllers/materialize/form_select_controller.js
Normal 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();
|
||||
}
|
||||
}
|
||||
24
assets/controllers/materialize/sidenav_controller.js
Normal file
24
assets/controllers/materialize/sidenav_controller.js
Normal 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();
|
||||
}
|
||||
}
|
||||
12
assets/controllers/materialize/tabs_controller.js
Normal file
12
assets/controllers/materialize/tabs_controller.js
Normal 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();
|
||||
}
|
||||
}
|
||||
12
assets/controllers/materialize/toast_controller.js
Normal file
12
assets/controllers/materialize/toast_controller.js
Normal 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();
|
||||
}
|
||||
}
|
||||
12
assets/controllers/materialize/tooltip_controller.js
Normal file
12
assets/controllers/materialize/tooltip_controller.js
Normal 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();
|
||||
}
|
||||
}
|
||||
10
assets/controllers/qrcode_controller.js
Normal file
10
assets/controllers/qrcode_controller.js
Normal 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));
|
||||
}
|
||||
}
|
||||
10
assets/controllers/scroll_indicator_controller.js
Normal file
10
assets/controllers/scroll_indicator_controller.js
Normal 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}%`;
|
||||
}
|
||||
}
|
||||
19
assets/controllers/scroll_storage_controller.js
Normal file
19
assets/controllers/scroll_storage_controller.js
Normal 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;
|
||||
}
|
||||
}
|
||||
141
assets/controllers/shortcuts_controller.js
Normal file
141
assets/controllers/shortcuts_controller.js
Normal 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();
|
||||
});
|
||||
}
|
||||
}
|
||||
7
assets/controllers/sticky_nav_controller.js
Normal file
7
assets/controllers/sticky_nav_controller.js
Normal file
@ -0,0 +1,7 @@
|
||||
import { Controller } from '@hotwired/stimulus';
|
||||
|
||||
export default class extends Controller {
|
||||
toggle() {
|
||||
this.element.classList.toggle('entry-nav-top--sticky');
|
||||
}
|
||||
}
|
||||
12
assets/controllers/tag_controller.js
Normal file
12
assets/controllers/tag_controller.js
Normal 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();
|
||||
}
|
||||
}
|
||||
31
assets/controllers/topbar_controller.js
Normal file
31
assets/controllers/topbar_controller.js
Normal 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';
|
||||
}
|
||||
}
|
||||
368
assets/index.js
368
assets/index.js
@ -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,364 +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,
|
||||
});
|
||||
|
||||
$('.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);
|
||||
});
|
||||
});
|
||||
|
||||
@ -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);
|
||||
});
|
||||
});
|
||||
@ -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();
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -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;
|
||||
}
|
||||
});
|
||||
});
|
||||
@ -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,
|
||||
};
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -183,6 +183,12 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
blockquote.annotations {
|
||||
margin-top: 5px;
|
||||
padding-left: 1rem;
|
||||
border-left: 5px solid #00acc1;
|
||||
}
|
||||
|
||||
footer {
|
||||
&.page-footer {
|
||||
margin-top: 10px;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
37
bin/console
37
bin/console
@ -3,40 +3,25 @@
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Console\Application;
|
||||
use Symfony\Component\Console\Input\ArgvInput;
|
||||
use Symfony\Component\Dotenv\Dotenv;
|
||||
use Symfony\Component\ErrorHandler\Debug;
|
||||
|
||||
if (!in_array(PHP_SAPI, ['cli', 'phpdbg', 'embed'], true)) {
|
||||
echo 'Warning: The console should be invoked via the CLI version of PHP, not the '.PHP_SAPI.' SAPI'.PHP_EOL;
|
||||
}
|
||||
// if you don't want to setup permissions the proper way, just uncomment the following PHP line
|
||||
// read https://symfony.com/doc/current/setup.html#checking-symfony-application-configuration-and-setup
|
||||
// for more information
|
||||
//umask(0000);
|
||||
|
||||
set_time_limit(0);
|
||||
|
||||
require dirname(__DIR__).'/vendor/autoload.php';
|
||||
|
||||
if (!class_exists(Application::class) || !class_exists(Dotenv::class)) {
|
||||
throw new LogicException('You need to add "symfony/framework-bundle" and "symfony/dotenv" as Composer dependencies.');
|
||||
}
|
||||
require __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
$input = new ArgvInput();
|
||||
if (null !== $env = $input->getParameterOption(['--env', '-e'], null, true)) {
|
||||
putenv('APP_ENV='.$_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = $env);
|
||||
$env = $input->getParameterOption(['--env', '-e'], getenv('SYMFONY_ENV') ?: 'dev', true);
|
||||
$debug = getenv('SYMFONY_DEBUG') !== '0' && !$input->hasParameterOption('--no-debug', true) && $env !== 'prod';
|
||||
|
||||
if ($debug) {
|
||||
Debug::enable();
|
||||
}
|
||||
|
||||
if ($input->hasParameterOption('--no-debug', true)) {
|
||||
putenv('APP_DEBUG='.$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = '0');
|
||||
}
|
||||
|
||||
(new Dotenv())->bootEnv(dirname(__DIR__).'/.env');
|
||||
|
||||
if ($_SERVER['APP_DEBUG']) {
|
||||
umask(0000);
|
||||
|
||||
if (class_exists(Debug::class)) {
|
||||
Debug::enable();
|
||||
}
|
||||
}
|
||||
|
||||
$kernel = new AppKernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']);
|
||||
$kernel = new AppKernel($env, $debug);
|
||||
$application = new Application($kernel);
|
||||
$application->run($input);
|
||||
|
||||
@ -21,7 +21,9 @@ $config
|
||||
'ergebnis/composer-normalize',
|
||||
'friendsofphp/php-cs-fixer',
|
||||
'friendsoftwig/twigcs',
|
||||
'incenteev/composer-parameter-handler',
|
||||
'j0k3r/graby-site-config',
|
||||
'j0k3r/php-readability',
|
||||
'laminas/laminas-code',
|
||||
'lcobucci/jwt',
|
||||
'mgargano/simplehtmldom',
|
||||
@ -36,13 +38,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',
|
||||
@ -63,10 +63,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;
|
||||
|
||||
219
composer.json
219
composer.json
@ -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,147 @@
|
||||
"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",
|
||||
"j0k3r/graby": "^2.4.5",
|
||||
"j0k3r/graby-site-config": "^1.0",
|
||||
"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.6",
|
||||
"j0k3r/graby-site-config": "^1.0.197",
|
||||
"j0k3r/php-readability": "^1.2.13",
|
||||
"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/dotenv": "^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,12 +228,12 @@
|
||||
"phpstan/extension-installer": true
|
||||
},
|
||||
"bin-dir": "bin",
|
||||
"platform": {
|
||||
"php": "7.4.29"
|
||||
},
|
||||
"sort-packages": true
|
||||
},
|
||||
"extra": {
|
||||
"incenteev-parameters": {
|
||||
"file": "app/config/parameters.yml"
|
||||
},
|
||||
"public-dir": "web",
|
||||
"symfony": {
|
||||
"allow-contrib": true,
|
||||
@ -236,6 +248,7 @@
|
||||
"@post-cmd"
|
||||
],
|
||||
"post-cmd": [
|
||||
"Incenteev\\ParameterHandler\\ScriptHandler::buildParameters",
|
||||
"bin/console cache:clear --no-warmup",
|
||||
"bin/console assets:install web --symlink --relative"
|
||||
]
|
||||
|
||||
2981
composer.lock
generated
2981
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@ -1,2 +1,9 @@
|
||||
MYSQL_ROOT_PASSWORD=wallaroot
|
||||
MYSQL_DATABASE=wallabag
|
||||
DATABASE_DRIVER=pdo_mysql
|
||||
DATABASE_HOST=mariadb
|
||||
DATABASE_PORT=3306
|
||||
DATABASE_NAME=wallabag
|
||||
DATABASE_USER=root
|
||||
DATABASE_PASSWORD=wallaroot
|
||||
DATABASE_CHARSET=utf8mb4
|
||||
|
||||
@ -1,4 +1,13 @@
|
||||
FROM php:8.1-fpm AS rootless
|
||||
FROM golang as envsubst
|
||||
|
||||
ARG ENVSUBST_VERSION=v1.3.0
|
||||
|
||||
# envsubst from gettext can not replace env vars with default values
|
||||
# this package is not available for ARM32 and we have to build it from source code
|
||||
# flag -ldflags "-s -w" produces a smaller executable
|
||||
RUN go install -ldflags "-s -w" -v github.com/a8m/envsubst/cmd/envsubst@${ENVSUBST_VERSION}
|
||||
|
||||
FROM php:8.2-fpm AS rootless
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
ARG NODE_VERSION=20
|
||||
@ -50,14 +59,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) \
|
||||
@ -76,10 +84,8 @@ RUN mkdir -p /tmp/blackfire \
|
||||
|
||||
RUN npm install -g yarn
|
||||
|
||||
RUN curl -L -o /usr/local/bin/envsubst https://github.com/a8m/envsubst/releases/download/v1.1.0/envsubst-`uname -s`-`uname -m`; \
|
||||
chmod +x /usr/local/bin/envsubst
|
||||
|
||||
COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer
|
||||
COPY --from=envsubst /go/bin/envsubst /usr/local/bin/envsubst
|
||||
|
||||
COPY entrypoint.sh /entrypoint.sh
|
||||
COPY config/ /opt/wallabag/config/
|
||||
|
||||
50
docker/php/config/parameters.yml
Normal file
50
docker/php/config/parameters.yml
Normal file
@ -0,0 +1,50 @@
|
||||
parameters:
|
||||
database_driver: ${DATABASE_DRIVER:-pdo_sqlite}
|
||||
database_host: ${DATABASE_HOST:-127.0.0.1}
|
||||
database_port: ${DATABASE_PORT:-~}
|
||||
database_name: ${DATABASE_NAME:-symfony}
|
||||
database_user: ${DATABASE_USER:-root}
|
||||
database_password: ${DATABASE_PASSWORD:-~}
|
||||
database_path: ${DATABASE_PATH:-"%kernel.project_dir%/data/db/wallabag.sqlite"}
|
||||
database_table_prefix: ${DATABASE_TABLE_PREFIX:-wallabag_}
|
||||
database_socket: ${DATABASE_SOCKET:-~}
|
||||
database_charset: ${DATABASE_CHARSET:-utf8}
|
||||
|
||||
domain_name: ${DOMAIN_NAME:-https://www.example.com}
|
||||
server_name: ${SERVER_NAME:-"Your wallabag instance"}
|
||||
|
||||
mailer_dsn: ${MAILER_DSN:-"smtp://127.0.0.1"}
|
||||
|
||||
locale: ${LOCALE:-en}
|
||||
|
||||
# A secret key that's used to generate certain security-related tokens
|
||||
secret: ${SECRET:-~}
|
||||
|
||||
# two factor stuff
|
||||
twofactor_sender: ${TWOFACTOR_SENDER:-no-reply@wallabag.org}
|
||||
|
||||
# fosuser stuff
|
||||
fosuser_registration: ${FOSUSER_REGISTRATION:-false}
|
||||
fosuser_confirmation: ${FOSUSER_CONFIRMATION:-true}
|
||||
|
||||
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}
|
||||
|
||||
# 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: ${RABBITMQ_PREFETCH_COUNT:-10}
|
||||
|
||||
# Redis processing
|
||||
redis_scheme: ${REDIS_SCHEME:-redis}
|
||||
redis_host: ${REDIS_HOST:-redis}
|
||||
redis_port: ${REDIS_PORT:-6379}
|
||||
redis_path: ${REDIS_PATH:-~}
|
||||
redis_password: ${REDIS_PASSWORD:-~}
|
||||
|
||||
# Sentry
|
||||
sentry_dsn: ${SENTRY_DSN:-~}
|
||||
@ -1,5 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
envsubst < /opt/wallabag/config/wallabag-php.ini > /usr/local/etc/php/conf.d/wallabag-php.ini
|
||||
envsubst < /opt/wallabag/config/parameters.yml > /var/www/html/app/config/parameters.yml
|
||||
|
||||
exec "$@"
|
||||
|
||||
@ -1,3 +1,12 @@
|
||||
PHP_SESSION_SAVE_PATH=tcp://redis:6379?database=2
|
||||
DATABASE_DRIVER=pdo_sqlite
|
||||
DATABASE_HOST=127.0.0.1
|
||||
DATABASE_PORT=~
|
||||
DATABASE_NAME=symfony
|
||||
DATABASE_USER=root
|
||||
DATABASE_PASSWORD=~
|
||||
DATABASE_PATH='"%kernel.project_dir%/data/db/wallabag.sqlite"'
|
||||
DOMAIN_NAME=http://127.0.0.1:8000
|
||||
SECRET=ch4n63m31fy0uc4n
|
||||
PHP_SESSION_SAVE_PATH=redis://redis:6379?database=2
|
||||
PHP_SESSION_HANDLER=redis
|
||||
TRUSTED_PROXIES=0.0.0.0/0
|
||||
|
||||
@ -1,3 +1,10 @@
|
||||
POSTGRES_USER=wallabag
|
||||
POSTGRES_PASSWORD=wallapass
|
||||
POSTGRES_DB=wallabag
|
||||
DATABASE_HOST=postgres
|
||||
DATABASE_PORT=5432
|
||||
DATABASE_NAME=wallabag
|
||||
DATABASE_USER=wallabag
|
||||
DATABASE_PASSWORD=wallapass
|
||||
DATABASE_DRIVER=pdo_pgsql
|
||||
DATABASE_PATH=null
|
||||
|
||||
@ -43,7 +43,7 @@ class AnnotationFixtures extends Fixture implements DependentFixtureInterface
|
||||
$manager->flush();
|
||||
}
|
||||
|
||||
public function getDependencies()
|
||||
public function getDependencies(): array
|
||||
{
|
||||
return [
|
||||
EntryFixtures::class,
|
||||
|
||||
@ -55,7 +55,7 @@ class ConfigFixtures extends Fixture implements DependentFixtureInterface
|
||||
$manager->flush();
|
||||
}
|
||||
|
||||
public function getDependencies()
|
||||
public function getDependencies(): array
|
||||
{
|
||||
return [
|
||||
UserFixtures::class,
|
||||
|
||||
@ -155,7 +155,7 @@ class EntryFixtures extends Fixture implements DependentFixtureInterface
|
||||
$manager->flush();
|
||||
}
|
||||
|
||||
public function getDependencies()
|
||||
public function getDependencies(): array
|
||||
{
|
||||
return [
|
||||
UserFixtures::class,
|
||||
|
||||
@ -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
|
||||
|
||||
@ -21,7 +21,7 @@ class IgnoreOriginUserRuleFixtures extends Fixture implements DependentFixtureIn
|
||||
$manager->flush();
|
||||
}
|
||||
|
||||
public function getDependencies()
|
||||
public function getDependencies(): array
|
||||
{
|
||||
return [
|
||||
UserFixtures::class,
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -58,7 +58,7 @@ class TaggingRuleFixtures extends Fixture implements DependentFixtureInterface
|
||||
$manager->flush();
|
||||
}
|
||||
|
||||
public function getDependencies()
|
||||
public function getDependencies(): array
|
||||
{
|
||||
return [
|
||||
ConfigFixtures::class,
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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'] . "');");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
38
package.json
38
package.json
@ -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",
|
||||
"@babel/core": "^7.27.4",
|
||||
"@babel/eslint-parser": "^7.27.5",
|
||||
"@babel/preset-env": "^7.27.2",
|
||||
"@symfony/webpack-encore": "^5.1.0",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"babel-loader": "^9.2.1",
|
||||
"core-js": "^3.23.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.3",
|
||||
"postcss": "^8.5.4",
|
||||
"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.6",
|
||||
"@fontsource/eb-garamond": "^5.2.6",
|
||||
"@fontsource/montserrat": "^5.2.6",
|
||||
"@fontsource/oswald": "^5.2.6",
|
||||
"@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"
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -2,12 +2,10 @@ includes:
|
||||
- phpstan-baseline.neon
|
||||
|
||||
parameters:
|
||||
level: 3
|
||||
level: 5
|
||||
paths:
|
||||
- src
|
||||
- tests
|
||||
bootstrapFiles:
|
||||
- tests/phpstan-bootstrap.php
|
||||
|
||||
symfony:
|
||||
container_xml_path: %rootDir%/../../../var/cache/dev/AppKernelDevDebugContainer.xml
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
<php>
|
||||
<ini name="error_reporting" value="-1"/>
|
||||
<server name="KERNEL_CLASS" value="AppKernel"/>
|
||||
<server name="APP_ENV" value="test" force="true"/>
|
||||
<server name="APP_ENV" value="test"/>
|
||||
<server name="APP_DEBUG" value="0"/>
|
||||
<env name="SYMFONY_DEPRECATIONS_HELPER" value="weak"/>
|
||||
</php>
|
||||
|
||||
28
rector.php
Normal file
28
rector.php
Normal 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);
|
||||
@ -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();
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user