Showing preview only (503K chars total). Download the full file or copy to clipboard to get everything.
Repository: j0k3r/banditore
Branch: master
Commit: aa0cb944a8c2
Files: 120
Total size: 469.1 KB
Directory structure:
gitextract_xx2gl39y/
├── .editorconfig
├── .github/
│ ├── FUNDING.yml
│ ├── dependabot.yml
│ ├── release.yml
│ └── workflows/
│ ├── coding-standards.yml
│ ├── continuous-integration.yml
│ └── coverage.yml
├── .gitignore
├── .nvmrc
├── .php-cs-fixer.dist.php
├── CONTRIBUTING.md
├── LICENSE
├── Makefile
├── README.md
├── bin/
│ └── console
├── composer.json
├── config/
│ ├── bundles.php
│ ├── packages/
│ │ ├── cache.yaml
│ │ ├── debug.yaml
│ │ ├── doctrine.yaml
│ │ ├── doctrine_migrations.yaml
│ │ ├── framework.yaml
│ │ ├── github_api.yaml
│ │ ├── http_discovery.yaml
│ │ ├── knpu_oauth2_client.yaml
│ │ ├── messenger.yaml
│ │ ├── monolog.yaml
│ │ ├── routing.yaml
│ │ ├── security.yaml
│ │ ├── sentry.yaml
│ │ ├── snc_redis.yaml
│ │ ├── twig.yaml
│ │ ├── validator.yaml
│ │ └── web_profiler.yaml
│ ├── preload.php
│ ├── reference.php
│ ├── routes/
│ │ ├── framework.yaml
│ │ ├── security.yaml
│ │ └── web_profiler.yaml
│ ├── routes.yaml
│ ├── services.yaml
│ └── services_test.yaml
├── data/
│ └── supervisor.conf
├── migrations/
│ ├── .gitignore
│ ├── Version20170222055642.php
│ ├── Version20170329095349.php
│ ├── Version20180827105910.php
│ ├── Version20200511062812.php
│ ├── Version20200613153754.php
│ └── Version20260408120000.php
├── phpstan.dist.neon
├── phpunit.xml.dist
├── public/
│ ├── css/
│ │ ├── banditore.css
│ │ ├── grids-responsive-min.css
│ │ └── pure-min.css
│ ├── fonts/
│ │ ├── .gitkeep
│ │ └── FontAwesome.otf
│ ├── index.php
│ ├── js/
│ │ └── banditore.js
│ └── robots.txt
├── rector.php
├── src/
│ ├── Cache/
│ │ ├── CustomRedisCachePool.php
│ │ ├── HierarchicalCachePoolTrait.php
│ │ └── PredisCachePool.php
│ ├── Command/
│ │ ├── SyncStarredReposCommand.php
│ │ └── SyncVersionsCommand.php
│ ├── Controller/
│ │ └── DefaultController.php
│ ├── DataFixtures/
│ │ └── AppFixtures.php
│ ├── Entity/
│ │ ├── Repo.php
│ │ ├── Star.php
│ │ ├── User.php
│ │ └── Version.php
│ ├── Github/
│ │ ├── ClientDiscovery.php
│ │ └── RateLimitTrait.php
│ ├── Kernel.php
│ ├── Message/
│ │ ├── StarredReposSync.php
│ │ └── VersionsSync.php
│ ├── MessageHandler/
│ │ ├── StarredReposSyncHandler.php
│ │ └── VersionsSyncHandler.php
│ ├── Pagination/
│ │ ├── Exception/
│ │ │ ├── CallbackNotFoundException.php
│ │ │ └── InvalidPageNumberException.php
│ │ ├── Pagination.php
│ │ ├── Paginator.php
│ │ └── PaginatorInterface.php
│ ├── PubSubHubbub/
│ │ └── Publisher.php
│ ├── Repository/
│ │ ├── RepoRepository.php
│ │ ├── StarRepository.php
│ │ ├── UserRepository.php
│ │ └── VersionRepository.php
│ ├── Rss/
│ │ └── Generator.php
│ ├── Security/
│ │ └── GithubAuthenticator.php
│ ├── Twig/
│ │ ├── PaginationExtension.php
│ │ └── RepoVersionExtension.php
│ └── Webfeeds/
│ ├── Webfeeds.php
│ └── WebfeedsWriter.php
├── templates/
│ ├── base.html.twig
│ ├── bundles/
│ │ └── TwigBundle/
│ │ └── Exception/
│ │ └── error.html.twig
│ └── default/
│ ├── _line_version.html.twig
│ ├── _pagination.html.twig
│ ├── dashboard.html.twig
│ ├── index.html.twig
│ └── stats.html.twig
└── tests/
├── Cache/
│ └── CustomRedisCachePoolTest.php
├── Command/
│ ├── SyncStarredReposCommandTest.php
│ └── SyncVersionsCommandTest.php
├── Controller/
│ └── DefaultControllerTest.php
├── Github/
│ └── ClientDiscoveryTest.php
├── MessageHandler/
│ ├── StarredReposSyncHandlerTest.php
│ └── VersionsSyncHandlerTest.php
├── PubSubHubbub/
│ └── PublisherTest.php
├── Repository/
│ ├── UserRepositoryTest.php
│ └── VersionRepositoryTest.php
├── Rss/
│ └── GeneratorTest.php
├── Security/
│ └── GithubAuthenticatorTest.php
├── Twig/
│ └── RepoVersionExtensionTest.php
├── Webfeeds/
│ ├── WebfeedsTest.php
│ └── WebfeedsWriterTest.php
├── bootstrap.php
├── console-application.php
└── object-manager.php
================================================
FILE CONTENTS
================================================
================================================
FILE: .editorconfig
================================================
# editorconfig.org
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
[{compose.yaml,compose.*.yaml}]
indent_size = 2
[.github/**.yml]
indent_size = 2
[*.md]
trim_trailing_whitespace = false
[Makefile]
indent_style = tab
================================================
FILE: .github/FUNDING.yml
================================================
github: j0k3r
================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
- package-ecosystem: composer
directory: "/"
schedule:
interval: weekly
open-pull-requests-limit: 10
groups:
symfony-dependencies:
patterns:
- "symfony/*"
twig-dependencies:
patterns:
- "twig/*"
phpstan-dependencies:
patterns:
- "phpstan/*"
- package-ecosystem: github-actions
directory: "/"
schedule:
interval: weekly
open-pull-requests-limit: 10
================================================
FILE: .github/release.yml
================================================
changelog:
exclude:
labels:
- dependencies
authors:
- dependabot
================================================
FILE: .github/workflows/coding-standards.yml
================================================
name: CS
on:
pull_request:
branches:
- master
push:
branches:
- master
jobs:
coding-standards:
name: CS Fixer & PHPStan
runs-on: "ubuntu-latest"
strategy:
matrix:
php:
- "8.2"
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Install PHP
uses: shivammathur/setup-php@v2
with:
coverage: "none"
php-version: "${{ matrix.php }}"
tools: composer:v2
ini-values: "date.timezone=Europe/Paris"
env:
COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Install dependencies with Composer
uses: ramsey/composer-install@v4
- name: Run PHP CS Fixer
run: bin/php-cs-fixer fix --verbose --dry-run
- name: Generate test cache for PHPStan
run: php bin/console cache:clear --env=test
- name: Install PHPUnit for PHPStan
run: php bin/simple-phpunit install
- name: Run PHPStan
run: php bin/phpstan analyse --no-progress
================================================
FILE: .github/workflows/continuous-integration.yml
================================================
name: CI
on:
pull_request:
branches:
- "master"
push:
branches:
- "master"
env:
fail-fast: true
APP_ENV: test
jobs:
phpunit:
name: PHPUnit (PHP ${{ matrix.php }})
runs-on: "ubuntu-latest"
services:
mysql:
image: mysql:5.7
env:
MYSQL_ALLOW_EMPTY_PASSWORD: yes
ports:
- 3306:3306
rabbitmq:
image: rabbitmq:3-alpine
ports:
- 5672:5672
redis:
image: redis:6-alpine
ports:
- 6379:6379
strategy:
matrix:
php:
- "8.2"
- "8.3"
- "8.4"
- "8.5"
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 2
- name: Install PHP
uses: shivammathur/setup-php@v2
with:
php-version: "${{ matrix.php }}"
coverage: "none"
tools: composer:v2
extensions: pdo, pdo_mysql, curl, redis, amqp
ini-values: "date.timezone=Europe/Paris"
env:
COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Install dependencies with Composer
uses: ramsey/composer-install@v4
- name: Create database
run: php bin/console doctrine:database:create --env=test
- name: Create schema
run: php bin/console doctrine:schema:create --env=test
- name: Load fixtures
run: php bin/console doctrine:fixtures:load --env=test -n
- name: Setup messenger queue
run: php bin/console messenger:setup-transports --env=dev
- name: Run PHPUnit
run: php bin/phpunit
================================================
FILE: .github/workflows/coverage.yml
================================================
name: Coverage
on:
pull_request:
branches:
- "master"
push:
branches:
- "master"
env:
APP_ENV: test
jobs:
phpunit:
name: PHPUnit
runs-on: "ubuntu-latest"
services:
mysql:
image: mysql:5.7
env:
MYSQL_ALLOW_EMPTY_PASSWORD: yes
ports:
- 3306:3306
rabbitmq:
image: rabbitmq:3-alpine
ports:
- 5672:5672
redis:
image: redis:6-alpine
ports:
- 6379:6379
strategy:
matrix:
php:
- "8.2"
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 2
- name: Install PHP with PCOV
uses: shivammathur/setup-php@v2
with:
php-version: "${{ matrix.php }}"
coverage: "pcov"
tools: composer:v2
extensions: pdo, pdo_mysql, curl, redis, amqp
ini-values: "date.timezone=Europe/Paris"
env:
COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Install dependencies with Composer
uses: ramsey/composer-install@v4
- name: Create database
run: php bin/console doctrine:database:create --env=test
- name: Create schema
run: php bin/console doctrine:schema:create --env=test
- name: Load fixtures
run: php bin/console doctrine:fixtures:load --env=test -n
- name: Setup messenger queue
run: php bin/console messenger:setup-transports --env=dev
- name: Run PHPUnit (with coverage)
run: php bin/phpunit --coverage-clover=coverage.xml
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v6
with:
files: ./coverage.xml
token: ${{ secrets.CODECOV_TOKEN }}
================================================
FILE: .gitignore
================================================
/build/
/coverage/
/var/*
!/var/cache
/var/cache/*
!var/cache/.gitkeep
!/var/log
/var/log/*
!var/log/.gitkeep
!/var/sessions
/var/sessions/*
!var/sessions/.gitkeep
/bin/*
!/bin/console
###> symfony/framework-bundle ###
/.env.local
/.env.local.php
/.env.*.local
/config/secrets/prod/prod.decrypt.private.php
/public/bundles/
/var/
/vendor/
###< symfony/framework-bundle ###
###> friendsofphp/php-cs-fixer ###
/.php-cs-fixer.php
/.php-cs-fixer.cache
###< friendsofphp/php-cs-fixer ###
###> symfony/phpunit-bridge ###
.phpunit
.phpunit.result.cache
/.phpunit.cache
/phpunit.xml
###< symfony/phpunit-bridge ###
###> phpunit/phpunit ###
/phpunit.xml
.phpunit.result.cache
###< phpunit/phpunit ###
###> phpstan/phpstan ###
phpstan.neon
###< phpstan/phpstan ###
================================================
FILE: .nvmrc
================================================
22
================================================
FILE: .php-cs-fixer.dist.php
================================================
<?php
use PhpCsFixer\Finder;
use PhpCsFixer\Config;
$finder = (new Finder())
->in(__DIR__)
->exclude(['vendor', 'var', 'web'])
->notPath([
'config/reference.php',
])
;
return (new Config())
->setRiskyAllowed(true)
->setRules([
'@Symfony' => true,
'@Symfony:risky' => true,
'array_syntax' => ['syntax' => 'short'],
'combine_consecutive_unsets' => true,
'heredoc_to_nowdoc' => true,
'no_extra_blank_lines' => ['tokens' => ['break', 'continue', 'extra', 'return', 'throw', 'use', 'parenthesis_brace_block', 'square_brace_block', 'curly_brace_block']],
'no_unreachable_default_argument_value' => true,
'no_useless_else' => true,
'no_useless_return' => true,
'ordered_class_elements' => true,
'ordered_imports' => true,
'php_unit_strict' => true,
'phpdoc_order' => true,
// 'psr4' => true,
'strict_comparison' => true,
'strict_param' => true,
'concat_space' => ['spacing' => 'one'],
])
->setFinder($finder)
;
================================================
FILE: CONTRIBUTING.md
================================================
# Contributing
Contributions are welcome, of course.
## Setting up an Environment
You locally need:
- PHP >= 8.2 (with `pdo_mysql`) with [Composer](https://getcomposer.org/) installed
- Docker
Install deps:
```
composer i
```
The application serves its frontend assets directly from `public/`, so there is no Node/Yarn setup step.
Then you can use Docker (used for test or dev):
```
docker run -d --name banditore-mysql -e MYSQL_ALLOW_EMPTY_PASSWORD=yes -p 3306:3306 mysql:latest
docker run -d --name banditore-redis -p 6379:6379 redis:latest
docker run -d --name banditore-rabbit -p 5672:5672 -p 15672:15672 rabbitmq:4-management
```
## Running Tests
You can setup the database and the project using:
```
make prepare
```
Once it's ok, launch tests:
```
php bin/phpunit
```
Test environment defaults live in `.env.test`.
## Linting
Linter is used only on PHP files:
```
php bin/php-cs-fixer fix
php bin/phpstan analyse
```
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2017-present Jérémy Benoist
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: Makefile
================================================
.PHONY: build local prepare test
build: prepare test
local:
php bin/console doctrine:database:create --if-not-exists --env=test
php bin/console doctrine:schema:create --env=test
php bin/console doctrine:fixtures:load --env=test -n
php bin/console cache:clear --env=test
prepare:
composer install --no-interaction -o --prefer-dist
php bin/console doctrine:database:create --if-not-exists --env=test
php bin/console doctrine:schema:drop --force --env=test
php bin/console doctrine:schema:create --env=test
php bin/console doctrine:fixtures:load --env=test -n
php bin/console cache:clear --env=test
test:
php bin/phpunit --coverage-html build/coverage
reset:
php bin/console doctrine:schema:drop --force --env=test
php bin/console doctrine:schema:create --env=test
php bin/console doctrine:fixtures:load --env=test -n
================================================
FILE: README.md
================================================
<img src="https://i.imgur.com/kAvg4w9.png" align="right" />
# Banditore

[](https://codecov.io/github/j0k3r/banditore)

Banditore retrieves new releases from your GitHub starred repositories and put them in a RSS feed, just for you.

## Requirements
- PHP >= 8.2 (with `pdo_mysql`)
- MySQL >= 5.7
- Redis (to cache requests to the GitHub API)
- [RabbitMQ](https://www.rabbitmq.com/), which is optional (see below)
- [Supervisor](http://supervisord.org/) (only if you use RabbitMQ)
## Installation
1. Clone the project
```bash
git clone https://github.com/j0k3r/banditore.git
```
2. [Register a new OAuth GitHub application](https://github.com/settings/applications/new) and get the _Client ID_ & _Client Secret_ for the next step (for the _Authorization callback URL_ put `http://127.0.0.1:8000/callback`)
3. Install dependencies using [Composer](https://getcomposer.org/download/) and define your parameter during the installation
```bash
APP_ENV=prod composer install -o --no-dev
```
If you want to use:
- **Sentry** to retrieve all errors, [register here](https://sentry.io/signup/) and get your dsn (in Project Settings > DSN).
4. Setup the database
```bash
php bin/console doctrine:database:create -e prod
php bin/console doctrine:schema:create -e prod
```
5. The application serves its frontend assets directly from `public/`, so no Node/Yarn install step is required (it's locked on `font-awesome@4.7.0` & `purecss@3.0.0`).
6. You can now launch the website:
```bash
php -S localhost:8000 -t public/
```
And access it at this address: `http://127.0.0.1:8000`
## Running the instance
Once the website is up, you now have to setup few things to retrieve new releases.
You have two choices:
- using crontab command (very simple and ok if you are alone)
- using RabbitMQ (might be better if you plan to have more than few persons but it's more complex) :call_me_hand:
### Without RabbitMQ
You just need to define these 2 cronjobs (replace all `/path/to/banditore` with real value):
```bash
# retrieve new release of each repo every 10 minutes
*/10 * * * * php /path/to/banditore/bin/console -e prod banditore:sync:versions >> /path/to/banditore/var/logs/command-sync-versions.log 2>&1
# sync starred repos of each user every 5 minutes
*/5 * * * * php /path/to/banditore/bin/console -e prod banditore:sync:starred-repos >> /path/banditore/to/var/logs/command-sync-repos.log 2>&1
```
### With RabbitMQ
1. You'll need to declare exchanges and queues. Replace `guest` by the user of your RabbitMQ instance (`guest` is the default one):
```bash
php bin/console messenger:setup-transports -vvv sync_starred_repos
php bin/console messenger:setup-transports -vvv sync_versions
```
2. You now have two queues and two exchanges defined:
- `banditore.sync_starred_repos`: will receive messages to sync starred repos of all users
- `banditore.sync_versions`: will receive message to retrieve new release for repos
3. Enable these 2 cronjobs which will periodically push messages in queues (replace all `/path/to/banditore` with real value):
```bash
# retrieve new release of each repo every 10 minutes
*/10 * * * * php /path/to/banditore/bin/console -e prod banditore:sync:versions --use_queue >> /path/to/banditore/var/logs/command-sync-versions.log 2>&1
# sync starred repos of each user every 5 minutes
*/5 * * * * php /path/to/banditore/bin/console -e prod banditore:sync:starred-repos --use_queue >> /path/banditore/to/var/logs/command-sync-repos.log 2>&1
```
4. Setup Supervisor using the [sample file](data/supervisor.conf) from the repo. You can copy/paste it into `/etc/supervisor/conf.d/` and adjust path. The default file will launch:
- 2 workers for sync starred repos
- 4 workers to fetch new releases
Once you've put the file in the supervisor conf repo, run `supervisorctl update && supervisorctl start all` (`update` will read your conf, `start all` will start all workers)
### Monitoring
There is a status page available at `/status`, it returns a json with some information about the freshness of fetched versions:
```json
{
"latest": {
"date": "2019-09-17 19:50:50.000000",
"timezone_type": 3,
"timezone": "Europe\/Berlin"
},
"diff": 1736,
"is_fresh": true
}
```
- `latest`: the latest created version as a DateTime
- `diff`: the difference between now and the latest created version (in seconds)
- `is_fresh`: indicate if everything is fine by comparing the `diff` above with the `status_minute_interval_before_alert` parameter
For example, I've setup a check on [updown.io](https://updown.io/r/P7qer) to check that status page and if the page contains `"is_fresh":true`. So I receive an alert when `is_fresh` is false: which means there is a potential issue on the server.
## Running the test suite
If you plan to contribute (you're awesome, I know that :v:), you'll need to install the project in a different way (for example, to retrieve dev packages):
```bash
git clone https://github.com/j0k3r/banditore.git
composer install -o
php bin/console doctrine:database:create -e=test
php bin/console doctrine:schema:create -e=test
php bin/console doctrine:fixtures:load --env=test -n
php bin/phpunit
```
Test environment defaults, including the database connection, are defined in `.env.test`.
## How it works
Ok, if you goes that deeper in the readme, it means you're a bit more than interested, I like that.
### Retrieving new release / tag
This is the complex part of the app. Here is a simplified solution to achieve it.
#### New release
It's not as easy as using the `/repos/:owner/:repo/releases` API endpoint to retrieve latest release for a given repo. Because not all repo owner use that feature (which is a shame in my case).
All information for a release are available on that endpoint:
- name of the tag (ie: v1.0.0)
- name of the release (ie: yay first release)
- published date
- description of the release
> Check a new release of that repo as example: https://api.github.com/repos/j0k3r/banditore/releases/5770680
#### New tag
Some owners also use tag which is a bit more complex to retrieve all information because a tag only contains information about the SHA-1 of the commit which was used to make the tag.
We only have these information:
- name of the tag (ie: v1.4.2)
- name of the release will be the name of the tag, in that case
> Check tag list of swarrot/SwarrotBundle as example: https://api.github.com/repos/swarrot/SwarrotBundle/tags
After retrieving the tag, we need to retrieve the commit to get these information:
- date of the commit
- message of the commit
> Check a commit from the previous tag list as example: https://api.github.com/repos/swarrot/SwarrotBundle/commits/84c7c57622e4666ae5706f33cd71842639b78755
### GitHub Client Discovery
This is the most important piece of the app. One thing that I ran though is hitting the rate limit on GitHub.
The rate limit for a given authenticated client is 5.000 calls per hour. This limit is **never** reached when looking for new release (thanks to the [conditional requests](https://developer.github.com/v3/#conditional-requests) of the GitHub API) on a daily basis.
But when new user sign in, we need to sync all its starred repositories and also all their releases / tags. And here come the gourmand part:
- one call for the list of release
- one call to retrieve information of each tag (if the repo doesn't have release)
- one call for each release to convert markdown text to html
Let's say the repo:
- has 50 tags: 1 (get tag list) + 50 (get commit information) + 50 (convert markdown) = 101 calls.
- has 50 releases: 1 (get tag list) + 50 (get each release) + 50 (convert markdown) = 101 calls.
And keep in mind that some repos got also 1.000+ tags (!!).
To avoid hitting the limit in such case and wait 1 hour to be able to make requests again I created the [GitHub Client Discovery class](src/AppBundle/Github/ClientDiscovery.php).
It aims to find the best client with enough rate limit remain (defined as 50).
- it first checks using the GitHub OAuth app
- then it checks using all user GitHub token
Which means, if you have 5 users on the app, you'll be able to make (1 + 5) x 5.000 = 30.000 calls per hour
================================================
FILE: bin/console
================================================
#!/usr/bin/env php
<?php
use App\Kernel;
use Symfony\Bundle\FrameworkBundle\Console\Application;
if (!is_dir(dirname(__DIR__).'/vendor')) {
throw new LogicException('Dependencies are missing. Try running "composer install".');
}
if (!is_file(dirname(__DIR__).'/vendor/autoload_runtime.php')) {
throw new LogicException('Symfony Runtime is missing. Try running "composer require symfony/runtime".');
}
require_once dirname(__DIR__).'/vendor/autoload_runtime.php';
return function (array $context) {
$kernel = new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
return new Application($kernel);
};
================================================
FILE: composer.json
================================================
{
"name": "j0k3r/banditore",
"description": "Banditore retrieve all new releases from your starred repositories and put them in a RSS feed, just for you.",
"license": "MIT",
"type": "project",
"autoload": {
"psr-4": {
"App\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"App\\Tests\\": "tests/"
}
},
"require": {
"php": ">=8.2",
"cache/adapter-common": "dev-psr-cache-v3",
"cache/tag-interop": "dev-psr-cache-v3",
"doctrine/doctrine-bundle": "^2.0",
"doctrine/doctrine-migrations-bundle": "^3.0",
"doctrine/orm": "^3.5",
"knplabs/github-api": "^3.0",
"knplabs/knp-time-bundle": "^2.4",
"knpuniversity/oauth2-client-bundle": "^2.1",
"laminas/laminas-code": "^4.5",
"league/oauth2-github": "^3.0",
"marcw/rss-writer": "dev-fix/symfony-6",
"php-http/guzzle7-adapter": "^1.1",
"predis/predis": "^3.2",
"ramsey/uuid": "^4.0",
"sentry/sentry-symfony": "^5.0",
"snc/redis-bundle": "^4.10",
"symfony/amqp-messenger": "*",
"symfony/asset": "*",
"symfony/dotenv": "*",
"symfony/expression-language": "*",
"symfony/flex": "^2.5",
"symfony/monolog-bundle": "^4.0",
"symfony/polyfill-apcu": "^1.0",
"symfony/polyfill-php80": "^1.27",
"symfony/runtime": "*",
"symfony/security-bundle": "*",
"symfony/translation": "*",
"symfony/twig-bundle": "*",
"symfony/validator": "*",
"symfony/yaml": "*",
"twig/extra-bundle": "^2.12|^3.0",
"twig/twig": "^2.0|^3.0"
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^4.1",
"friendsofphp/php-cs-fixer": "~3.0",
"phpstan/extension-installer": "^1.0",
"phpstan/phpstan": "^2.0",
"phpstan/phpstan-deprecation-rules": "^2.0",
"phpstan/phpstan-doctrine": "^2.0",
"phpstan/phpstan-phpunit": "^2.0",
"phpstan/phpstan-symfony": "^2.0",
"phpunit/phpunit": "^11",
"rector/rector": "^2.1",
"symfony/browser-kit": "*",
"symfony/css-selector": "*",
"symfony/debug-bundle": "*",
"symfony/phpunit-bridge": "*",
"symfony/web-profiler-bundle": "*"
},
"conflict": {
"symfony/symfony": "*"
},
"scripts": {
"auto-scripts": {
"cache:clear": "symfony-cmd",
"assets:install %PUBLIC_DIR%": "symfony-cmd"
},
"post-install-cmd": [
"@auto-scripts"
],
"post-update-cmd": [
"@auto-scripts"
]
},
"config": {
"bin-dir": "bin",
"sort-packages": true,
"allow-plugins": {
"phpstan/extension-installer": true,
"symfony/flex": true,
"symfony/runtime": true,
"php-http/discovery": true
}
},
"repositories": [
{
"type": "vcs",
"url": "https://github.com/j0k3r/rss-writer"
},
{
"type": "vcs",
"url": "https://github.com/j0k3r/adapter-common"
},
{
"type": "vcs",
"url": "https://github.com/j0k3r/tag-interop"
}
],
"extra": {
"symfony": {
"allow-contrib": true,
"require": "7.4.*"
}
}
}
================================================
FILE: config/bundles.php
================================================
<?php
use Doctrine\Bundle\DoctrineBundle\DoctrineBundle;
use Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle;
use Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle;
use Knp\Bundle\TimeBundle\KnpTimeBundle;
use KnpU\OAuth2ClientBundle\KnpUOAuth2ClientBundle;
use Sentry\SentryBundle\SentryBundle;
use Snc\RedisBundle\SncRedisBundle;
use Symfony\Bundle\DebugBundle\DebugBundle;
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
use Symfony\Bundle\MonologBundle\MonologBundle;
use Symfony\Bundle\SecurityBundle\SecurityBundle;
use Symfony\Bundle\TwigBundle\TwigBundle;
use Symfony\Bundle\WebProfilerBundle\WebProfilerBundle;
use Twig\Extra\TwigExtraBundle\TwigExtraBundle;
return [
FrameworkBundle::class => ['all' => true],
DoctrineBundle::class => ['all' => true],
DoctrineMigrationsBundle::class => ['all' => true],
KnpTimeBundle::class => ['all' => true],
KnpUOAuth2ClientBundle::class => ['all' => true],
SentryBundle::class => ['prod' => true],
SncRedisBundle::class => ['all' => true],
MonologBundle::class => ['all' => true],
DoctrineFixturesBundle::class => ['dev' => true, 'test' => true],
TwigBundle::class => ['all' => true],
TwigExtraBundle::class => ['all' => true],
SecurityBundle::class => ['all' => true],
DebugBundle::class => ['dev' => true, 'test' => true],
WebProfilerBundle::class => ['dev' => true, 'test' => true],
];
================================================
FILE: config/packages/cache.yaml
================================================
framework:
cache:
# Unique name of your app: used to compute stable namespaces for cache keys.
#prefix_seed: your_vendor_name/app_name
# The "app" cache stores to the filesystem by default.
# The data in this cache should persist between deploys.
# Other options include:
# Redis
#app: cache.adapter.redis
#default_redis_provider: redis://localhost
# APCu (not recommended with heavy random-write workloads as memory fragmentation can cause perf issues)
#app: cache.adapter.apcu
# Namespaced pools use the above "app" backend by default
#pools:
#my.dedicated.cache: null
================================================
FILE: config/packages/debug.yaml
================================================
when@dev:
debug:
# Forwards VarDumper Data clones to a centralized server allowing to inspect dumps on CLI or in your browser.
# See the "server:dump" command to start a new server.
dump_destination: "tcp://%env(VAR_DUMPER_SERVER)%"
================================================
FILE: config/packages/doctrine.yaml
================================================
doctrine:
dbal:
url: '%env(resolve:DATABASE_URL)%'
# driver: pdo_mysql
# host: "%database_host%"
# port: "%database_port%"
# dbname: "%database_name%"
# user: "%database_user%"
# password: "%database_password%"
charset: utf8mb4
server_version: 5.7
default_table_options:
charset: utf8mb4
collate: utf8mb4_unicode_ci
# backtrace queries in profiler (increases memory usage per request)
profiling_collect_backtrace: '%kernel.debug%'
use_savepoints: true
orm:
auto_generate_proxy_classes: true
enable_lazy_ghost_objects: true
report_fields_where_declared: true
validate_xml_mapping: true
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
identity_generation_preferences:
Doctrine\DBAL\Platforms\PostgreSQLPlatform: identity
auto_mapping: true
mappings:
App:
type: attribute
is_bundle: false
dir: '%kernel.project_dir%/src/Entity'
prefix: 'App\Entity'
alias: App
controller_resolver:
auto_mapping: false
when@test:
doctrine:
dbal:
logging: false
# "TEST_TOKEN" is typically set by ParaTest
# dbname_suffix: '_test%env(default::TEST_TOKEN)%'
when@prod:
doctrine:
orm:
auto_generate_proxy_classes: false
proxy_dir: '%kernel.build_dir%/doctrine/orm/Proxies'
metadata_cache_driver:
type: pool
pool: doctrine.system_cache_pool
query_cache_driver:
type: pool
pool: doctrine.system_cache_pool
result_cache_driver:
type: pool
pool: doctrine.result_cache_pool
framework:
cache:
pools:
doctrine.result_cache_pool:
adapter: cache.app
doctrine.system_cache_pool:
adapter: cache.system
================================================
FILE: config/packages/doctrine_migrations.yaml
================================================
doctrine_migrations:
migrations_paths:
# namespace is arbitrary but should be different from App\Migrations
# as migrations classes should NOT be autoloaded
'DoctrineMigrations': '%kernel.project_dir%/migrations'
enable_profiler: false
================================================
FILE: config/packages/framework.yaml
================================================
# see https://symfony.com/doc/current/reference/configuration/framework.html
framework:
secret: '%env(APP_SECRET)%'
annotations: false
http_method_override: true
handle_all_throwables: true
# Enables session support. Note that the session will ONLY be started if you read or write from it.
# Remove or comment this section to explicitly disable session support.
session:
name: banditore
storage_factory_id: session.storage.factory.native
save_path: "%kernel.project_dir%/var/sessions/%kernel.environment%"
cookie_secure: auto
cookie_samesite: lax
#esi: true
#fragments: true
when@test:
framework:
test: true
session:
storage_factory_id: session.storage.factory.mock_file
================================================
FILE: config/packages/github_api.yaml
================================================
services:
Github\Client:
arguments:
- '@Github\HttpClient\Builder'
# Uncomment to enable authentication
#calls:
# - ['authenticate', ['%env(GITHUB_USERNAME)%', '%env(GITHUB_SECRET)%', '%env(GITHUB_AUTH_METHOD)%']]
Github\HttpClient\Builder:
arguments:
- '@?Http\Client\HttpClient'
- '@?Http\Message\RequestFactory'
- '@?Http\Message\StreamFactory'
================================================
FILE: config/packages/http_discovery.yaml
================================================
services:
Psr\Http\Message\RequestFactoryInterface: '@http_discovery.psr17_factory'
Psr\Http\Message\ResponseFactoryInterface: '@http_discovery.psr17_factory'
Psr\Http\Message\ServerRequestFactoryInterface: '@http_discovery.psr17_factory'
Psr\Http\Message\StreamFactoryInterface: '@http_discovery.psr17_factory'
Psr\Http\Message\UploadedFileFactoryInterface: '@http_discovery.psr17_factory'
Psr\Http\Message\UriFactoryInterface: '@http_discovery.psr17_factory'
http_discovery.psr17_factory:
class: Http\Discovery\Psr17Factory
================================================
FILE: config/packages/knpu_oauth2_client.yaml
================================================
knpu_oauth2_client:
clients:
# will create service: "knpu.oauth2.client.github"
# an instance of: KnpU\OAuth2ClientBundle\Client\Provider\GithubClient
github:
type: github
client_id: "%env(GITHUB_CLIENT_ID)%"
client_secret: "%env(GITHUB_CLIENT_SECRET)%"
# a route name you'll create
redirect_route: github_callback
redirect_params: {}
================================================
FILE: config/packages/messenger.yaml
================================================
framework:
messenger:
# Uncomment this (and the failed transport below) to send failed messages to this transport for later handling.
# failure_transport: failed
transports:
sync_starred_repos:
dsn: '%env(MESSENGER_TRANSPORT_DSN)%/sync_starred_repos'
options:
exchange:
name: banditore.sync_starred_repos
type: direct
queues:
banditore.sync_starred_repos: ~
sync_versions:
dsn: '%env(MESSENGER_TRANSPORT_DSN)%/sync_versions'
options:
exchange:
name: banditore.sync_versions
type: direct
queues:
banditore.sync_versions: ~
# https://symfony.com/doc/current/messenger.html#transport-configuration
# async: '%env(MESSENGER_TRANSPORT_DSN)%'
# failed: 'doctrine://default?queue_name=failed'
# sync: 'sync://'
routing:
'App\Message\StarredReposSync': sync_starred_repos
'App\Message\VersionsSync': sync_versions
buses:
command_bus:
middleware:
- doctrine_ping_connection
- doctrine_close_connection
when@test:
framework:
messenger:
transports:
sync_starred_repos: 'in-memory://'
sync_versions: 'in-memory://'
================================================
FILE: config/packages/monolog.yaml
================================================
monolog:
channels:
- deprecation # Deprecations are logged in the dedicated "deprecation" channel when it exists
when@dev:
monolog:
handlers:
main:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
channels: ["!event"]
console:
type: console
process_psr_3_messages: false
channels: ["!event", "!doctrine", "!console"]
when@test:
monolog:
handlers:
main:
type: fingers_crossed
action_level: error
handler: nested
excluded_http_codes: [404, 405]
channels: ["!event"]
nested:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
when@prod:
monolog:
handlers:
main:
type: fingers_crossed
action_level: error
handler: nested
excluded_http_codes: [404, 405]
channels: ["!deprecation"]
buffer_size: 50 # How many messages should be saved? Prevent memory leaks
nested:
type: rotating_file
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
max_files: 10
console:
type: console
process_psr_3_messages: false
channels: ["!event", "!doctrine"]
deprecation:
type: stream
channels: [deprecation]
path: "%kernel.logs_dir%/deprecation.log"
================================================
FILE: config/packages/routing.yaml
================================================
framework:
router:
# Configure how to generate URLs in non-HTTP contexts, such as CLI commands.
# See https://symfony.com/doc/current/routing.html#generating-urls-in-commands
default_uri: '%env(DEFAULT_URI)%'
when@prod:
framework:
router:
strict_requirements: null
================================================
FILE: config/packages/security.yaml
================================================
security:
# https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords
password_hashers:
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
# https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider
providers:
github_provider:
entity:
class: App\Entity\User
property: githubId
firewalls:
dev:
# Ensure dev tools and static assets are always allowed
pattern: ^/(_profiler|_wdt|assets|build|css|images|js)/
security: false
main:
lazy: true
custom_authenticators:
- App\Security\GithubAuthenticator
logout:
path: logout
# Activate different ways to authenticate:
# https://symfony.com/doc/current/security.html#the-firewall
# https://symfony.com/doc/current/security/impersonating_user.html
# switch_user: true
# Note: Only the *first* matching rule is applied
access_control:
# - { path: ^/admin, roles: ROLE_ADMIN }
# - { path: ^/profile, roles: ROLE_USER }
when@test:
security:
password_hashers:
# Password hashers are resource-intensive by design to ensure security.
# In tests, it's safe to reduce their cost to improve performance.
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface:
algorithm: auto
cost: 4 # Lowest possible value for bcrypt
time_cost: 3 # Lowest possible value for argon
memory_cost: 10 # Lowest possible value for argon
================================================
FILE: config/packages/sentry.yaml
================================================
when@prod:
sentry:
dsn: '%env(SENTRY_DSN)%'
options:
integrations:
- 'Sentry\Integration\IgnoreErrorsIntegration'
- 'Symfony\Component\ErrorHandler\Error\FatalError'
- 'Symfony\Component\Debug\Exception\FatalErrorException'
# If you are using Monolog, you also need these additional configuration and services to log the errors correctly:
# https://docs.sentry.io/platforms/php/guides/symfony/#monolog-integration
register_error_listener: false
register_error_handler: false
# this hooks into critical paths of the framework (and vendors) to perform
# automatic instrumentation (there might be some performance penalty)
# https://docs.sentry.io/platforms/php/guides/symfony/performance/instrumentation/automatic-instrumentation/
tracing:
enabled: false
monolog:
handlers:
sentry:
type: service
id: Sentry\Monolog\Handler
level: !php/const Monolog\Logger::ERROR
services:
Sentry\Integration\IgnoreErrorsIntegration:
arguments:
$options:
ignore_exceptions:
- Symfony\Component\HttpKernel\Exception\NotFoundHttpException
Sentry\Monolog\Handler:
arguments:
$hub: '@Sentry\State\HubInterface'
$level: !php/const Monolog\Logger::ERROR
$bubble: false
================================================
FILE: config/packages/snc_redis.yaml
================================================
# Define your clients here. The example below connects to database 0 of the default Redis server.
#
# See https://github.com/snc/SncRedisBundle/blob/master/docs/README.md for instructions on
# how to configure the bundle.
snc_redis:
clients:
guzzle_cache:
type: predis
alias: guzzle_cache
dsn: "%env(REDIS_URL_GUZZLE_CACHE)%"
app_cache:
type: predis
alias: app_cache
dsn: "%env(REDIS_URL_APP_CACHE)%"
================================================
FILE: config/packages/twig.yaml
================================================
twig:
file_name_pattern: '*.twig'
when@test:
twig:
strict_variables: true
================================================
FILE: config/packages/validator.yaml
================================================
framework:
validation:
enable_attributes: true
email_validation_mode: html5
# Enables validator auto-mapping support.
# For instance, basic validation constraints will be inferred from Doctrine's metadata.
auto_mapping:
App\Entity\: []
when@test:
framework:
validation:
not_compromised_password: false
================================================
FILE: config/packages/web_profiler.yaml
================================================
when@dev:
web_profiler:
toolbar: true
framework:
profiler:
collect_serializer_data: true
when@test:
web_profiler:
toolbar: false
intercept_redirects: false
framework:
profiler:
enabled: false
collect: false
collect_serializer_data: true
================================================
FILE: config/preload.php
================================================
<?php
if (file_exists(dirname(__DIR__) . '/var/cache/prod/App_KernelProdContainer.preload.php')) {
require dirname(__DIR__) . '/var/cache/prod/App_KernelProdContainer.preload.php';
}
================================================
FILE: config/reference.php
================================================
<?php
// This file is auto-generated and is for apps only. Bundles SHOULD NOT rely on its content.
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
use Symfony\Component\Config\Loader\ParamConfigurator as Param;
/**
* This class provides array-shapes for configuring the services and bundles of an application.
*
* Services declared with the config() method below are autowired and autoconfigured by default.
*
* This is for apps only. Bundles SHOULD NOT use it.
*
* Example:
*
* ```php
* // config/services.php
* namespace Symfony\Component\DependencyInjection\Loader\Configurator;
*
* return App::config([
* 'services' => [
* 'App\\' => [
* 'resource' => '../src/',
* ],
* ],
* ]);
* ```
*
* @psalm-type ImportsConfig = list<string|array{
* resource: string,
* type?: string|null,
* ignore_errors?: bool,
* }>
* @psalm-type ParametersConfig = array<string, scalar|\UnitEnum|array<scalar|\UnitEnum|array<mixed>|Param|null>|Param|null>
* @psalm-type ArgumentsType = list<mixed>|array<string, mixed>
* @psalm-type CallType = array<string, ArgumentsType>|array{0:string, 1?:ArgumentsType, 2?:bool}|array{method:string, arguments?:ArgumentsType, returns_clone?:bool}
* @psalm-type TagsType = list<string|array<string, array<string, mixed>>> // arrays inside the list must have only one element, with the tag name as the key
* @psalm-type CallbackType = string|array{0:string|ReferenceConfigurator,1:string}|\Closure|ReferenceConfigurator|ExpressionConfigurator
* @psalm-type DeprecationType = array{package: string, version: string, message?: string}
* @psalm-type DefaultsType = array{
* public?: bool,
* tags?: TagsType,
* resource_tags?: TagsType,
* autowire?: bool,
* autoconfigure?: bool,
* bind?: array<string, mixed>,
* }
* @psalm-type InstanceofType = array{
* shared?: bool,
* lazy?: bool|string,
* public?: bool,
* properties?: array<string, mixed>,
* configurator?: CallbackType,
* calls?: list<CallType>,
* tags?: TagsType,
* resource_tags?: TagsType,
* autowire?: bool,
* bind?: array<string, mixed>,
* constructor?: string,
* }
* @psalm-type DefinitionType = array{
* class?: string,
* file?: string,
* parent?: string,
* shared?: bool,
* synthetic?: bool,
* lazy?: bool|string,
* public?: bool,
* abstract?: bool,
* deprecated?: DeprecationType,
* factory?: CallbackType,
* configurator?: CallbackType,
* arguments?: ArgumentsType,
* properties?: array<string, mixed>,
* calls?: list<CallType>,
* tags?: TagsType,
* resource_tags?: TagsType,
* decorates?: string,
* decoration_inner_name?: string,
* decoration_priority?: int,
* decoration_on_invalid?: 'exception'|'ignore'|null,
* autowire?: bool,
* autoconfigure?: bool,
* bind?: array<string, mixed>,
* constructor?: string,
* from_callable?: CallbackType,
* }
* @psalm-type AliasType = string|array{
* alias: string,
* public?: bool,
* deprecated?: DeprecationType,
* }
* @psalm-type PrototypeType = array{
* resource: string,
* namespace?: string,
* exclude?: string|list<string>,
* parent?: string,
* shared?: bool,
* lazy?: bool|string,
* public?: bool,
* abstract?: bool,
* deprecated?: DeprecationType,
* factory?: CallbackType,
* arguments?: ArgumentsType,
* properties?: array<string, mixed>,
* configurator?: CallbackType,
* calls?: list<CallType>,
* tags?: TagsType,
* resource_tags?: TagsType,
* autowire?: bool,
* autoconfigure?: bool,
* bind?: array<string, mixed>,
* constructor?: string,
* }
* @psalm-type StackType = array{
* stack: list<DefinitionType|AliasType|PrototypeType|array<class-string, ArgumentsType|null>>,
* public?: bool,
* deprecated?: DeprecationType,
* }
* @psalm-type ServicesConfig = array{
* _defaults?: DefaultsType,
* _instanceof?: InstanceofType,
* ...<string, DefinitionType|AliasType|PrototypeType|StackType|ArgumentsType|null>
* }
* @psalm-type ExtensionType = array<string, mixed>
* @psalm-type FrameworkConfig = array{
* secret?: scalar|Param|null,
* http_method_override?: bool|Param, // Set true to enable support for the '_method' request parameter to determine the intended HTTP method on POST requests. // Default: false
* allowed_http_method_override?: list<string|Param>|null,
* trust_x_sendfile_type_header?: scalar|Param|null, // Set true to enable support for xsendfile in binary file responses. // Default: "%env(bool:default::SYMFONY_TRUST_X_SENDFILE_TYPE_HEADER)%"
* ide?: scalar|Param|null, // Default: "%env(default::SYMFONY_IDE)%"
* test?: bool|Param,
* default_locale?: scalar|Param|null, // Default: "en"
* set_locale_from_accept_language?: bool|Param, // Whether to use the Accept-Language HTTP header to set the Request locale (only when the "_locale" request attribute is not passed). // Default: false
* set_content_language_from_locale?: bool|Param, // Whether to set the Content-Language HTTP header on the Response using the Request locale. // Default: false
* enabled_locales?: list<scalar|Param|null>,
* trusted_hosts?: list<scalar|Param|null>,
* trusted_proxies?: mixed, // Default: ["%env(default::SYMFONY_TRUSTED_PROXIES)%"]
* trusted_headers?: list<scalar|Param|null>,
* error_controller?: scalar|Param|null, // Default: "error_controller"
* handle_all_throwables?: bool|Param, // HttpKernel will handle all kinds of \Throwable. // Default: true
* csrf_protection?: bool|array{
* enabled?: scalar|Param|null, // Default: null
* stateless_token_ids?: list<scalar|Param|null>,
* check_header?: scalar|Param|null, // Whether to check the CSRF token in a header in addition to a cookie when using stateless protection. // Default: false
* cookie_name?: scalar|Param|null, // The name of the cookie to use when using stateless protection. // Default: "csrf-token"
* },
* form?: bool|array{ // Form configuration
* enabled?: bool|Param, // Default: false
* csrf_protection?: bool|array{
* enabled?: scalar|Param|null, // Default: null
* token_id?: scalar|Param|null, // Default: null
* field_name?: scalar|Param|null, // Default: "_token"
* field_attr?: array<string, scalar|Param|null>,
* },
* },
* http_cache?: bool|array{ // HTTP cache configuration
* enabled?: bool|Param, // Default: false
* debug?: bool|Param, // Default: "%kernel.debug%"
* trace_level?: "none"|"short"|"full"|Param,
* trace_header?: scalar|Param|null,
* default_ttl?: int|Param,
* private_headers?: list<scalar|Param|null>,
* skip_response_headers?: list<scalar|Param|null>,
* allow_reload?: bool|Param,
* allow_revalidate?: bool|Param,
* stale_while_revalidate?: int|Param,
* stale_if_error?: int|Param,
* terminate_on_cache_hit?: bool|Param,
* },
* esi?: bool|array{ // ESI configuration
* enabled?: bool|Param, // Default: false
* },
* ssi?: bool|array{ // SSI configuration
* enabled?: bool|Param, // Default: false
* },
* fragments?: bool|array{ // Fragments configuration
* enabled?: bool|Param, // Default: false
* hinclude_default_template?: scalar|Param|null, // Default: null
* path?: scalar|Param|null, // Default: "/_fragment"
* },
* profiler?: bool|array{ // Profiler configuration
* enabled?: bool|Param, // Default: false
* collect?: bool|Param, // Default: true
* collect_parameter?: scalar|Param|null, // The name of the parameter to use to enable or disable collection on a per request basis. // Default: null
* only_exceptions?: bool|Param, // Default: false
* only_main_requests?: bool|Param, // Default: false
* dsn?: scalar|Param|null, // Default: "file:%kernel.cache_dir%/profiler"
* collect_serializer_data?: bool|Param, // Enables the serializer data collector and profiler panel. // Default: false
* },
* workflows?: bool|array{
* enabled?: bool|Param, // Default: false
* workflows?: array<string, array{ // Default: []
* audit_trail?: bool|array{
* enabled?: bool|Param, // Default: false
* },
* type?: "workflow"|"state_machine"|Param, // Default: "state_machine"
* marking_store?: array{
* type?: "method"|Param,
* property?: scalar|Param|null,
* service?: scalar|Param|null,
* },
* supports?: list<scalar|Param|null>,
* definition_validators?: list<scalar|Param|null>,
* support_strategy?: scalar|Param|null,
* initial_marking?: list<scalar|Param|null>,
* events_to_dispatch?: list<string|Param>|null,
* places?: list<array{ // Default: []
* name?: scalar|Param|null,
* metadata?: array<string, mixed>,
* }>,
* transitions?: list<array{ // Default: []
* name?: string|Param,
* guard?: string|Param, // An expression to block the transition.
* from?: list<array{ // Default: []
* place?: string|Param,
* weight?: int|Param, // Default: 1
* }>,
* to?: list<array{ // Default: []
* place?: string|Param,
* weight?: int|Param, // Default: 1
* }>,
* weight?: int|Param, // Default: 1
* metadata?: array<string, mixed>,
* }>,
* metadata?: array<string, mixed>,
* }>,
* },
* router?: bool|array{ // Router configuration
* enabled?: bool|Param, // Default: false
* resource?: scalar|Param|null,
* type?: scalar|Param|null,
* cache_dir?: scalar|Param|null, // Deprecated: Setting the "framework.router.cache_dir.cache_dir" configuration option is deprecated. It will be removed in version 8.0. // Default: "%kernel.build_dir%"
* default_uri?: scalar|Param|null, // The default URI used to generate URLs in a non-HTTP context. // Default: null
* http_port?: scalar|Param|null, // Default: 80
* https_port?: scalar|Param|null, // Default: 443
* strict_requirements?: scalar|Param|null, // set to true to throw an exception when a parameter does not match the requirements set to false to disable exceptions when a parameter does not match the requirements (and return null instead) set to null to disable parameter checks against requirements 'true' is the preferred configuration in development mode, while 'false' or 'null' might be preferred in production // Default: true
* utf8?: bool|Param, // Default: true
* },
* session?: bool|array{ // Session configuration
* enabled?: bool|Param, // Default: false
* storage_factory_id?: scalar|Param|null, // Default: "session.storage.factory.native"
* handler_id?: scalar|Param|null, // Defaults to using the native session handler, or to the native *file* session handler if "save_path" is not null.
* name?: scalar|Param|null,
* cookie_lifetime?: scalar|Param|null,
* cookie_path?: scalar|Param|null,
* cookie_domain?: scalar|Param|null,
* cookie_secure?: true|false|"auto"|Param, // Default: "auto"
* cookie_httponly?: bool|Param, // Default: true
* cookie_samesite?: null|"lax"|"strict"|"none"|Param, // Default: "lax"
* use_cookies?: bool|Param,
* gc_divisor?: scalar|Param|null,
* gc_probability?: scalar|Param|null,
* gc_maxlifetime?: scalar|Param|null,
* save_path?: scalar|Param|null, // Defaults to "%kernel.cache_dir%/sessions" if the "handler_id" option is not null.
* metadata_update_threshold?: int|Param, // Seconds to wait between 2 session metadata updates. // Default: 0
* sid_length?: int|Param, // Deprecated: Setting the "framework.session.sid_length.sid_length" configuration option is deprecated. It will be removed in version 8.0. No alternative is provided as PHP 8.4 has deprecated the related option.
* sid_bits_per_character?: int|Param, // Deprecated: Setting the "framework.session.sid_bits_per_character.sid_bits_per_character" configuration option is deprecated. It will be removed in version 8.0. No alternative is provided as PHP 8.4 has deprecated the related option.
* },
* request?: bool|array{ // Request configuration
* enabled?: bool|Param, // Default: false
* formats?: array<string, string|list<scalar|Param|null>>,
* },
* assets?: bool|array{ // Assets configuration
* enabled?: bool|Param, // Default: true
* strict_mode?: bool|Param, // Throw an exception if an entry is missing from the manifest.json. // Default: false
* version_strategy?: scalar|Param|null, // Default: null
* version?: scalar|Param|null, // Default: null
* version_format?: scalar|Param|null, // Default: "%%s?%%s"
* json_manifest_path?: scalar|Param|null, // Default: null
* base_path?: scalar|Param|null, // Default: ""
* base_urls?: list<scalar|Param|null>,
* packages?: array<string, array{ // Default: []
* strict_mode?: bool|Param, // Throw an exception if an entry is missing from the manifest.json. // Default: false
* version_strategy?: scalar|Param|null, // Default: null
* version?: scalar|Param|null,
* version_format?: scalar|Param|null, // Default: null
* json_manifest_path?: scalar|Param|null, // Default: null
* base_path?: scalar|Param|null, // Default: ""
* base_urls?: list<scalar|Param|null>,
* }>,
* },
* asset_mapper?: bool|array{ // Asset Mapper configuration
* enabled?: bool|Param, // Default: false
* paths?: array<string, scalar|Param|null>,
* excluded_patterns?: list<scalar|Param|null>,
* exclude_dotfiles?: bool|Param, // If true, any files starting with "." will be excluded from the asset mapper. // Default: true
* server?: bool|Param, // If true, a "dev server" will return the assets from the public directory (true in "debug" mode only by default). // Default: true
* public_prefix?: scalar|Param|null, // The public path where the assets will be written to (and served from when "server" is true). // Default: "/assets/"
* missing_import_mode?: "strict"|"warn"|"ignore"|Param, // Behavior if an asset cannot be found when imported from JavaScript or CSS files - e.g. "import './non-existent.js'". "strict" means an exception is thrown, "warn" means a warning is logged, "ignore" means the import is left as-is. // Default: "warn"
* extensions?: array<string, scalar|Param|null>,
* importmap_path?: scalar|Param|null, // The path of the importmap.php file. // Default: "%kernel.project_dir%/importmap.php"
* importmap_polyfill?: scalar|Param|null, // The importmap name that will be used to load the polyfill. Set to false to disable. // Default: "es-module-shims"
* importmap_script_attributes?: array<string, scalar|Param|null>,
* vendor_dir?: scalar|Param|null, // The directory to store JavaScript vendors. // Default: "%kernel.project_dir%/assets/vendor"
* precompress?: bool|array{ // Precompress assets with Brotli, Zstandard and gzip.
* enabled?: bool|Param, // Default: false
* formats?: list<scalar|Param|null>,
* extensions?: list<scalar|Param|null>,
* },
* },
* translator?: bool|array{ // Translator configuration
* enabled?: bool|Param, // Default: true
* fallbacks?: list<scalar|Param|null>,
* logging?: bool|Param, // Default: false
* formatter?: scalar|Param|null, // Default: "translator.formatter.default"
* cache_dir?: scalar|Param|null, // Default: "%kernel.cache_dir%/translations"
* default_path?: scalar|Param|null, // The default path used to load translations. // Default: "%kernel.project_dir%/translations"
* paths?: list<scalar|Param|null>,
* pseudo_localization?: bool|array{
* enabled?: bool|Param, // Default: false
* accents?: bool|Param, // Default: true
* expansion_factor?: float|Param, // Default: 1.0
* brackets?: bool|Param, // Default: true
* parse_html?: bool|Param, // Default: false
* localizable_html_attributes?: list<scalar|Param|null>,
* },
* providers?: array<string, array{ // Default: []
* dsn?: scalar|Param|null,
* domains?: list<scalar|Param|null>,
* locales?: list<scalar|Param|null>,
* }>,
* globals?: array<string, string|array{ // Default: []
* value?: mixed,
* message?: string|Param,
* parameters?: array<string, scalar|Param|null>,
* domain?: string|Param,
* }>,
* },
* validation?: bool|array{ // Validation configuration
* enabled?: bool|Param, // Default: true
* cache?: scalar|Param|null, // Deprecated: Setting the "framework.validation.cache.cache" configuration option is deprecated. It will be removed in version 8.0.
* enable_attributes?: bool|Param, // Default: true
* static_method?: list<scalar|Param|null>,
* translation_domain?: scalar|Param|null, // Default: "validators"
* email_validation_mode?: "html5"|"html5-allow-no-tld"|"strict"|"loose"|Param, // Default: "html5"
* mapping?: array{
* paths?: list<scalar|Param|null>,
* },
* not_compromised_password?: bool|array{
* enabled?: bool|Param, // When disabled, compromised passwords will be accepted as valid. // Default: true
* endpoint?: scalar|Param|null, // API endpoint for the NotCompromisedPassword Validator. // Default: null
* },
* disable_translation?: bool|Param, // Default: false
* auto_mapping?: array<string, array{ // Default: []
* services?: list<scalar|Param|null>,
* }>,
* },
* annotations?: bool|array{
* enabled?: bool|Param, // Default: false
* },
* serializer?: bool|array{ // Serializer configuration
* enabled?: bool|Param, // Default: false
* enable_attributes?: bool|Param, // Default: true
* name_converter?: scalar|Param|null,
* circular_reference_handler?: scalar|Param|null,
* max_depth_handler?: scalar|Param|null,
* mapping?: array{
* paths?: list<scalar|Param|null>,
* },
* default_context?: array<string, mixed>,
* named_serializers?: array<string, array{ // Default: []
* name_converter?: scalar|Param|null,
* default_context?: array<string, mixed>,
* include_built_in_normalizers?: bool|Param, // Whether to include the built-in normalizers // Default: true
* include_built_in_encoders?: bool|Param, // Whether to include the built-in encoders // Default: true
* }>,
* },
* property_access?: bool|array{ // Property access configuration
* enabled?: bool|Param, // Default: true
* magic_call?: bool|Param, // Default: false
* magic_get?: bool|Param, // Default: true
* magic_set?: bool|Param, // Default: true
* throw_exception_on_invalid_index?: bool|Param, // Default: false
* throw_exception_on_invalid_property_path?: bool|Param, // Default: true
* },
* type_info?: bool|array{ // Type info configuration
* enabled?: bool|Param, // Default: true
* aliases?: array<string, scalar|Param|null>,
* },
* property_info?: bool|array{ // Property info configuration
* enabled?: bool|Param, // Default: true
* with_constructor_extractor?: bool|Param, // Registers the constructor extractor.
* },
* cache?: array{ // Cache configuration
* prefix_seed?: scalar|Param|null, // Used to namespace cache keys when using several apps with the same shared backend. // Default: "_%kernel.project_dir%.%kernel.container_class%"
* app?: scalar|Param|null, // App related cache pools configuration. // Default: "cache.adapter.filesystem"
* system?: scalar|Param|null, // System related cache pools configuration. // Default: "cache.adapter.system"
* directory?: scalar|Param|null, // Default: "%kernel.share_dir%/pools/app"
* default_psr6_provider?: scalar|Param|null,
* default_redis_provider?: scalar|Param|null, // Default: "redis://localhost"
* default_valkey_provider?: scalar|Param|null, // Default: "valkey://localhost"
* default_memcached_provider?: scalar|Param|null, // Default: "memcached://localhost"
* default_doctrine_dbal_provider?: scalar|Param|null, // Default: "database_connection"
* default_pdo_provider?: scalar|Param|null, // Default: null
* pools?: array<string, array{ // Default: []
* adapters?: list<scalar|Param|null>,
* tags?: scalar|Param|null, // Default: null
* public?: bool|Param, // Default: false
* default_lifetime?: scalar|Param|null, // Default lifetime of the pool.
* provider?: scalar|Param|null, // Overwrite the setting from the default provider for this adapter.
* early_expiration_message_bus?: scalar|Param|null,
* clearer?: scalar|Param|null,
* }>,
* },
* php_errors?: array{ // PHP errors handling configuration
* log?: mixed, // Use the application logger instead of the PHP logger for logging PHP errors. // Default: true
* throw?: bool|Param, // Throw PHP errors as \ErrorException instances. // Default: true
* },
* exceptions?: array<string, array{ // Default: []
* log_level?: scalar|Param|null, // The level of log message. Null to let Symfony decide. // Default: null
* status_code?: scalar|Param|null, // The status code of the response. Null or 0 to let Symfony decide. // Default: null
* log_channel?: scalar|Param|null, // The channel of log message. Null to let Symfony decide. // Default: null
* }>,
* web_link?: bool|array{ // Web links configuration
* enabled?: bool|Param, // Default: false
* },
* lock?: bool|string|array{ // Lock configuration
* enabled?: bool|Param, // Default: false
* resources?: array<string, string|list<scalar|Param|null>>,
* },
* semaphore?: bool|string|array{ // Semaphore configuration
* enabled?: bool|Param, // Default: false
* resources?: array<string, scalar|Param|null>,
* },
* messenger?: bool|array{ // Messenger configuration
* enabled?: bool|Param, // Default: true
* routing?: array<string, string|array{ // Default: []
* senders?: list<scalar|Param|null>,
* }>,
* serializer?: array{
* default_serializer?: scalar|Param|null, // Service id to use as the default serializer for the transports. // Default: "messenger.transport.native_php_serializer"
* symfony_serializer?: array{
* format?: scalar|Param|null, // Serialization format for the messenger.transport.symfony_serializer service (which is not the serializer used by default). // Default: "json"
* context?: array<string, mixed>,
* },
* },
* transports?: array<string, string|array{ // Default: []
* dsn?: scalar|Param|null,
* serializer?: scalar|Param|null, // Service id of a custom serializer to use. // Default: null
* options?: array<string, mixed>,
* failure_transport?: scalar|Param|null, // Transport name to send failed messages to (after all retries have failed). // Default: null
* retry_strategy?: string|array{
* service?: scalar|Param|null, // Service id to override the retry strategy entirely. // Default: null
* max_retries?: int|Param, // Default: 3
* delay?: int|Param, // Time in ms to delay (or the initial value when multiplier is used). // Default: 1000
* multiplier?: float|Param, // If greater than 1, delay will grow exponentially for each retry: this delay = (delay * (multiple ^ retries)). // Default: 2
* max_delay?: int|Param, // Max time in ms that a retry should ever be delayed (0 = infinite). // Default: 0
* jitter?: float|Param, // Randomness to apply to the delay (between 0 and 1). // Default: 0.1
* },
* rate_limiter?: scalar|Param|null, // Rate limiter name to use when processing messages. // Default: null
* }>,
* failure_transport?: scalar|Param|null, // Transport name to send failed messages to (after all retries have failed). // Default: null
* stop_worker_on_signals?: list<scalar|Param|null>,
* default_bus?: scalar|Param|null, // Default: null
* buses?: array<string, array{ // Default: {"messenger.bus.default":{"default_middleware":{"enabled":true,"allow_no_handlers":false,"allow_no_senders":true},"middleware":[]}}
* default_middleware?: bool|string|array{
* enabled?: bool|Param, // Default: true
* allow_no_handlers?: bool|Param, // Default: false
* allow_no_senders?: bool|Param, // Default: true
* },
* middleware?: list<string|array{ // Default: []
* id?: scalar|Param|null,
* arguments?: list<mixed>,
* }>,
* }>,
* },
* scheduler?: bool|array{ // Scheduler configuration
* enabled?: bool|Param, // Default: false
* },
* disallow_search_engine_index?: bool|Param, // Enabled by default when debug is enabled. // Default: true
* http_client?: bool|array{ // HTTP Client configuration
* enabled?: bool|Param, // Default: false
* max_host_connections?: int|Param, // The maximum number of connections to a single host.
* default_options?: array{
* headers?: array<string, mixed>,
* vars?: array<string, mixed>,
* max_redirects?: int|Param, // The maximum number of redirects to follow.
* http_version?: scalar|Param|null, // The default HTTP version, typically 1.1 or 2.0, leave to null for the best version.
* resolve?: array<string, scalar|Param|null>,
* proxy?: scalar|Param|null, // The URL of the proxy to pass requests through or null for automatic detection.
* no_proxy?: scalar|Param|null, // A comma separated list of hosts that do not require a proxy to be reached.
* timeout?: float|Param, // The idle timeout, defaults to the "default_socket_timeout" ini parameter.
* max_duration?: float|Param, // The maximum execution time for the request+response as a whole.
* bindto?: scalar|Param|null, // A network interface name, IP address, a host name or a UNIX socket to bind to.
* verify_peer?: bool|Param, // Indicates if the peer should be verified in a TLS context.
* verify_host?: bool|Param, // Indicates if the host should exist as a certificate common name.
* cafile?: scalar|Param|null, // A certificate authority file.
* capath?: scalar|Param|null, // A directory that contains multiple certificate authority files.
* local_cert?: scalar|Param|null, // A PEM formatted certificate file.
* local_pk?: scalar|Param|null, // A private key file.
* passphrase?: scalar|Param|null, // The passphrase used to encrypt the "local_pk" file.
* ciphers?: scalar|Param|null, // A list of TLS ciphers separated by colons, commas or spaces (e.g. "RC3-SHA:TLS13-AES-128-GCM-SHA256"...)
* peer_fingerprint?: array{ // Associative array: hashing algorithm => hash(es).
* sha1?: mixed,
* pin-sha256?: mixed,
* md5?: mixed,
* },
* crypto_method?: scalar|Param|null, // The minimum version of TLS to accept; must be one of STREAM_CRYPTO_METHOD_TLSv*_CLIENT constants.
* extra?: array<string, mixed>,
* rate_limiter?: scalar|Param|null, // Rate limiter name to use for throttling requests. // Default: null
* caching?: bool|array{ // Caching configuration.
* enabled?: bool|Param, // Default: false
* cache_pool?: string|Param, // The taggable cache pool to use for storing the responses. // Default: "cache.http_client"
* shared?: bool|Param, // Indicates whether the cache is shared (public) or private. // Default: true
* max_ttl?: int|Param, // The maximum TTL (in seconds) allowed for cached responses. Null means no cap. // Default: null
* },
* retry_failed?: bool|array{
* enabled?: bool|Param, // Default: false
* retry_strategy?: scalar|Param|null, // service id to override the retry strategy. // Default: null
* http_codes?: array<string, array{ // Default: []
* code?: int|Param,
* methods?: list<string|Param>,
* }>,
* max_retries?: int|Param, // Default: 3
* delay?: int|Param, // Time in ms to delay (or the initial value when multiplier is used). // Default: 1000
* multiplier?: float|Param, // If greater than 1, delay will grow exponentially for each retry: delay * (multiple ^ retries). // Default: 2
* max_delay?: int|Param, // Max time in ms that a retry should ever be delayed (0 = infinite). // Default: 0
* jitter?: float|Param, // Randomness in percent (between 0 and 1) to apply to the delay. // Default: 0.1
* },
* },
* mock_response_factory?: scalar|Param|null, // The id of the service that should generate mock responses. It should be either an invokable or an iterable.
* scoped_clients?: array<string, string|array{ // Default: []
* scope?: scalar|Param|null, // The regular expression that the request URL must match before adding the other options. When none is provided, the base URI is used instead.
* base_uri?: scalar|Param|null, // The URI to resolve relative URLs, following rules in RFC 3985, section 2.
* auth_basic?: scalar|Param|null, // An HTTP Basic authentication "username:password".
* auth_bearer?: scalar|Param|null, // A token enabling HTTP Bearer authorization.
* auth_ntlm?: scalar|Param|null, // A "username:password" pair to use Microsoft NTLM authentication (requires the cURL extension).
* query?: array<string, scalar|Param|null>,
* headers?: array<string, mixed>,
* max_redirects?: int|Param, // The maximum number of redirects to follow.
* http_version?: scalar|Param|null, // The default HTTP version, typically 1.1 or 2.0, leave to null for the best version.
* resolve?: array<string, scalar|Param|null>,
* proxy?: scalar|Param|null, // The URL of the proxy to pass requests through or null for automatic detection.
* no_proxy?: scalar|Param|null, // A comma separated list of hosts that do not require a proxy to be reached.
* timeout?: float|Param, // The idle timeout, defaults to the "default_socket_timeout" ini parameter.
* max_duration?: float|Param, // The maximum execution time for the request+response as a whole.
* bindto?: scalar|Param|null, // A network interface name, IP address, a host name or a UNIX socket to bind to.
* verify_peer?: bool|Param, // Indicates if the peer should be verified in a TLS context.
* verify_host?: bool|Param, // Indicates if the host should exist as a certificate common name.
* cafile?: scalar|Param|null, // A certificate authority file.
* capath?: scalar|Param|null, // A directory that contains multiple certificate authority files.
* local_cert?: scalar|Param|null, // A PEM formatted certificate file.
* local_pk?: scalar|Param|null, // A private key file.
* passphrase?: scalar|Param|null, // The passphrase used to encrypt the "local_pk" file.
* ciphers?: scalar|Param|null, // A list of TLS ciphers separated by colons, commas or spaces (e.g. "RC3-SHA:TLS13-AES-128-GCM-SHA256"...).
* peer_fingerprint?: array{ // Associative array: hashing algorithm => hash(es).
* sha1?: mixed,
* pin-sha256?: mixed,
* md5?: mixed,
* },
* crypto_method?: scalar|Param|null, // The minimum version of TLS to accept; must be one of STREAM_CRYPTO_METHOD_TLSv*_CLIENT constants.
* extra?: array<string, mixed>,
* rate_limiter?: scalar|Param|null, // Rate limiter name to use for throttling requests. // Default: null
* caching?: bool|array{ // Caching configuration.
* enabled?: bool|Param, // Default: false
* cache_pool?: string|Param, // The taggable cache pool to use for storing the responses. // Default: "cache.http_client"
* shared?: bool|Param, // Indicates whether the cache is shared (public) or private. // Default: true
* max_ttl?: int|Param, // The maximum TTL (in seconds) allowed for cached responses. Null means no cap. // Default: null
* },
* retry_failed?: bool|array{
* enabled?: bool|Param, // Default: false
* retry_strategy?: scalar|Param|null, // service id to override the retry strategy. // Default: null
* http_codes?: array<string, array{ // Default: []
* code?: int|Param,
* methods?: list<string|Param>,
* }>,
* max_retries?: int|Param, // Default: 3
* delay?: int|Param, // Time in ms to delay (or the initial value when multiplier is used). // Default: 1000
* multiplier?: float|Param, // If greater than 1, delay will grow exponentially for each retry: delay * (multiple ^ retries). // Default: 2
* max_delay?: int|Param, // Max time in ms that a retry should ever be delayed (0 = infinite). // Default: 0
* jitter?: float|Param, // Randomness in percent (between 0 and 1) to apply to the delay. // Default: 0.1
* },
* }>,
* },
* mailer?: bool|array{ // Mailer configuration
* enabled?: bool|Param, // Default: false
* message_bus?: scalar|Param|null, // The message bus to use. Defaults to the default bus if the Messenger component is installed. // Default: null
* dsn?: scalar|Param|null, // Default: null
* transports?: array<string, scalar|Param|null>,
* envelope?: array{ // Mailer Envelope configuration
* sender?: scalar|Param|null,
* recipients?: list<scalar|Param|null>,
* allowed_recipients?: list<scalar|Param|null>,
* },
* headers?: array<string, string|array{ // Default: []
* value?: mixed,
* }>,
* dkim_signer?: bool|array{ // DKIM signer configuration
* enabled?: bool|Param, // Default: false
* key?: scalar|Param|null, // Key content, or path to key (in PEM format with the `file://` prefix) // Default: ""
* domain?: scalar|Param|null, // Default: ""
* select?: scalar|Param|null, // Default: ""
* passphrase?: scalar|Param|null, // The private key passphrase // Default: ""
* options?: array<string, mixed>,
* },
* smime_signer?: bool|array{ // S/MIME signer configuration
* enabled?: bool|Param, // Default: false
* key?: scalar|Param|null, // Path to key (in PEM format) // Default: ""
* certificate?: scalar|Param|null, // Path to certificate (in PEM format without the `file://` prefix) // Default: ""
* passphrase?: scalar|Param|null, // The private key passphrase // Default: null
* extra_certificates?: scalar|Param|null, // Default: null
* sign_options?: int|Param, // Default: null
* },
* smime_encrypter?: bool|array{ // S/MIME encrypter configuration
* enabled?: bool|Param, // Default: false
* repository?: scalar|Param|null, // S/MIME certificate repository service. This service shall implement the `Symfony\Component\Mailer\EventListener\SmimeCertificateRepositoryInterface`. // Default: ""
* cipher?: int|Param, // A set of algorithms used to encrypt the message // Default: null
* },
* },
* secrets?: bool|array{
* enabled?: bool|Param, // Default: true
* vault_directory?: scalar|Param|null, // Default: "%kernel.project_dir%/config/secrets/%kernel.runtime_environment%"
* local_dotenv_file?: scalar|Param|null, // Default: "%kernel.project_dir%/.env.%kernel.environment%.local"
* decryption_env_var?: scalar|Param|null, // Default: "base64:default::SYMFONY_DECRYPTION_SECRET"
* },
* notifier?: bool|array{ // Notifier configuration
* enabled?: bool|Param, // Default: false
* message_bus?: scalar|Param|null, // The message bus to use. Defaults to the default bus if the Messenger component is installed. // Default: null
* chatter_transports?: array<string, scalar|Param|null>,
* texter_transports?: array<string, scalar|Param|null>,
* notification_on_failed_messages?: bool|Param, // Default: false
* channel_policy?: array<string, string|list<scalar|Param|null>>,
* admin_recipients?: list<array{ // Default: []
* email?: scalar|Param|null,
* phone?: scalar|Param|null, // Default: ""
* }>,
* },
* rate_limiter?: bool|array{ // Rate limiter configuration
* enabled?: bool|Param, // Default: false
* limiters?: array<string, array{ // Default: []
* lock_factory?: scalar|Param|null, // The service ID of the lock factory used by this limiter (or null to disable locking). // Default: "auto"
* cache_pool?: scalar|Param|null, // The cache pool to use for storing the current limiter state. // Default: "cache.rate_limiter"
* storage_service?: scalar|Param|null, // The service ID of a custom storage implementation, this precedes any configured "cache_pool". // Default: null
* policy?: "fixed_window"|"token_bucket"|"sliding_window"|"compound"|"no_limit"|Param, // The algorithm to be used by this limiter.
* limiters?: list<scalar|Param|null>,
* limit?: int|Param, // The maximum allowed hits in a fixed interval or burst.
* interval?: scalar|Param|null, // Configures the fixed interval if "policy" is set to "fixed_window" or "sliding_window". The value must be a number followed by "second", "minute", "hour", "day", "week" or "month" (or their plural equivalent).
* rate?: array{ // Configures the fill rate if "policy" is set to "token_bucket".
* interval?: scalar|Param|null, // Configures the rate interval. The value must be a number followed by "second", "minute", "hour", "day", "week" or "month" (or their plural equivalent).
* amount?: int|Param, // Amount of tokens to add each interval. // Default: 1
* },
* }>,
* },
* uid?: bool|array{ // Uid configuration
* enabled?: bool|Param, // Default: false
* default_uuid_version?: 7|6|4|1|Param, // Default: 7
* name_based_uuid_version?: 5|3|Param, // Default: 5
* name_based_uuid_namespace?: scalar|Param|null,
* time_based_uuid_version?: 7|6|1|Param, // Default: 7
* time_based_uuid_node?: scalar|Param|null,
* },
* html_sanitizer?: bool|array{ // HtmlSanitizer configuration
* enabled?: bool|Param, // Default: false
* sanitizers?: array<string, array{ // Default: []
* allow_safe_elements?: bool|Param, // Allows "safe" elements and attributes. // Default: false
* allow_static_elements?: bool|Param, // Allows all static elements and attributes from the W3C Sanitizer API standard. // Default: false
* allow_elements?: array<string, mixed>,
* block_elements?: list<string|Param>,
* drop_elements?: list<string|Param>,
* allow_attributes?: array<string, mixed>,
* drop_attributes?: array<string, mixed>,
* force_attributes?: array<string, array<string, string|Param>>,
* force_https_urls?: bool|Param, // Transforms URLs using the HTTP scheme to use the HTTPS scheme instead. // Default: false
* allowed_link_schemes?: list<string|Param>,
* allowed_link_hosts?: list<string|Param>|null,
* allow_relative_links?: bool|Param, // Allows relative URLs to be used in links href attributes. // Default: false
* allowed_media_schemes?: list<string|Param>,
* allowed_media_hosts?: list<string|Param>|null,
* allow_relative_medias?: bool|Param, // Allows relative URLs to be used in media source attributes (img, audio, video, ...). // Default: false
* with_attribute_sanitizers?: list<string|Param>,
* without_attribute_sanitizers?: list<string|Param>,
* max_input_length?: int|Param, // The maximum length allowed for the sanitized input. // Default: 0
* }>,
* },
* webhook?: bool|array{ // Webhook configuration
* enabled?: bool|Param, // Default: false
* message_bus?: scalar|Param|null, // The message bus to use. // Default: "messenger.default_bus"
* routing?: array<string, array{ // Default: []
* service?: scalar|Param|null,
* secret?: scalar|Param|null, // Default: ""
* }>,
* },
* remote-event?: bool|array{ // RemoteEvent configuration
* enabled?: bool|Param, // Default: false
* },
* json_streamer?: bool|array{ // JSON streamer configuration
* enabled?: bool|Param, // Default: false
* },
* }
* @psalm-type DoctrineConfig = array{
* dbal?: array{
* default_connection?: scalar|Param|null,
* types?: array<string, string|array{ // Default: []
* class?: scalar|Param|null,
* commented?: bool|Param, // Deprecated: The doctrine-bundle type commenting features were removed; the corresponding config parameter was deprecated in 2.0 and will be dropped in 3.0.
* }>,
* driver_schemes?: array<string, scalar|Param|null>,
* connections?: array<string, array{ // Default: []
* url?: scalar|Param|null, // A URL with connection information; any parameter value parsed from this string will override explicitly set parameters
* dbname?: scalar|Param|null,
* host?: scalar|Param|null, // Defaults to "localhost" at runtime.
* port?: scalar|Param|null, // Defaults to null at runtime.
* user?: scalar|Param|null, // Defaults to "root" at runtime.
* password?: scalar|Param|null, // Defaults to null at runtime.
* override_url?: bool|Param, // Deprecated: The "doctrine.dbal.override_url" configuration key is deprecated.
* dbname_suffix?: scalar|Param|null, // Adds the given suffix to the configured database name, this option has no effects for the SQLite platform
* application_name?: scalar|Param|null,
* charset?: scalar|Param|null,
* path?: scalar|Param|null,
* memory?: bool|Param,
* unix_socket?: scalar|Param|null, // The unix socket to use for MySQL
* persistent?: bool|Param, // True to use as persistent connection for the ibm_db2 driver
* protocol?: scalar|Param|null, // The protocol to use for the ibm_db2 driver (default to TCPIP if omitted)
* service?: bool|Param, // True to use SERVICE_NAME as connection parameter instead of SID for Oracle
* servicename?: scalar|Param|null, // Overrules dbname parameter if given and used as SERVICE_NAME or SID connection parameter for Oracle depending on the service parameter.
* sessionMode?: scalar|Param|null, // The session mode to use for the oci8 driver
* server?: scalar|Param|null, // The name of a running database server to connect to for SQL Anywhere.
* default_dbname?: scalar|Param|null, // Override the default database (postgres) to connect to for PostgreSQL connexion.
* sslmode?: scalar|Param|null, // Determines whether or with what priority a SSL TCP/IP connection will be negotiated with the server for PostgreSQL.
* sslrootcert?: scalar|Param|null, // The name of a file containing SSL certificate authority (CA) certificate(s). If the file exists, the server's certificate will be verified to be signed by one of these authorities.
* sslcert?: scalar|Param|null, // The path to the SSL client certificate file for PostgreSQL.
* sslkey?: scalar|Param|null, // The path to the SSL client key file for PostgreSQL.
* sslcrl?: scalar|Param|null, // The file name of the SSL certificate revocation list for PostgreSQL.
* pooled?: bool|Param, // True to use a pooled server with the oci8/pdo_oracle driver
* MultipleActiveResultSets?: bool|Param, // Configuring MultipleActiveResultSets for the pdo_sqlsrv driver
* use_savepoints?: bool|Param, // Use savepoints for nested transactions
* instancename?: scalar|Param|null, // Optional parameter, complete whether to add the INSTANCE_NAME parameter in the connection. It is generally used to connect to an Oracle RAC server to select the name of a particular instance.
* connectstring?: scalar|Param|null, // Complete Easy Connect connection descriptor, see https://docs.oracle.com/database/121/NETAG/naming.htm.When using this option, you will still need to provide the user and password parameters, but the other parameters will no longer be used. Note that when using this parameter, the getHost and getPort methods from Doctrine\DBAL\Connection will no longer function as expected.
* driver?: scalar|Param|null, // Default: "pdo_mysql"
* platform_service?: scalar|Param|null, // Deprecated: The "platform_service" configuration key is deprecated since doctrine-bundle 2.9. DBAL 4 will not support setting a custom platform via connection params anymore.
* auto_commit?: bool|Param,
* schema_filter?: scalar|Param|null,
* logging?: bool|Param, // Default: true
* profiling?: bool|Param, // Default: true
* profiling_collect_backtrace?: bool|Param, // Enables collecting backtraces when profiling is enabled // Default: false
* profiling_collect_schema_errors?: bool|Param, // Enables collecting schema errors when profiling is enabled // Default: true
* disable_type_comments?: bool|Param,
* server_version?: scalar|Param|null,
* idle_connection_ttl?: int|Param, // Default: 600
* driver_class?: scalar|Param|null,
* wrapper_class?: scalar|Param|null,
* keep_slave?: bool|Param, // Deprecated: The "keep_slave" configuration key is deprecated since doctrine-bundle 2.2. Use the "keep_replica" configuration key instead.
* keep_replica?: bool|Param,
* options?: array<string, mixed>,
* mapping_types?: array<string, scalar|Param|null>,
* default_table_options?: array<string, scalar|Param|null>,
* schema_manager_factory?: scalar|Param|null, // Default: "doctrine.dbal.default_schema_manager_factory"
* result_cache?: scalar|Param|null,
* slaves?: array<string, array{ // Default: []
* url?: scalar|Param|null, // A URL with connection information; any parameter value parsed from this string will override explicitly set parameters
* dbname?: scalar|Param|null,
* host?: scalar|Param|null, // Defaults to "localhost" at runtime.
* port?: scalar|Param|null, // Defaults to null at runtime.
* user?: scalar|Param|null, // Defaults to "root" at runtime.
* password?: scalar|Param|null, // Defaults to null at runtime.
* override_url?: bool|Param, // Deprecated: The "doctrine.dbal.override_url" configuration key is deprecated.
* dbname_suffix?: scalar|Param|null, // Adds the given suffix to the configured database name, this option has no effects for the SQLite platform
* application_name?: scalar|Param|null,
* charset?: scalar|Param|null,
* path?: scalar|Param|null,
* memory?: bool|Param,
* unix_socket?: scalar|Param|null, // The unix socket to use for MySQL
* persistent?: bool|Param, // True to use as persistent connection for the ibm_db2 driver
* protocol?: scalar|Param|null, // The protocol to use for the ibm_db2 driver (default to TCPIP if omitted)
* service?: bool|Param, // True to use SERVICE_NAME as connection parameter instead of SID for Oracle
* servicename?: scalar|Param|null, // Overrules dbname parameter if given and used as SERVICE_NAME or SID connection parameter for Oracle depending on the service parameter.
* sessionMode?: scalar|Param|null, // The session mode to use for the oci8 driver
* server?: scalar|Param|null, // The name of a running database server to connect to for SQL Anywhere.
* default_dbname?: scalar|Param|null, // Override the default database (postgres) to connect to for PostgreSQL connexion.
* sslmode?: scalar|Param|null, // Determines whether or with what priority a SSL TCP/IP connection will be negotiated with the server for PostgreSQL.
* sslrootcert?: scalar|Param|null, // The name of a file containing SSL certificate authority (CA) certificate(s). If the file exists, the server's certificate will be verified to be signed by one of these authorities.
* sslcert?: scalar|Param|null, // The path to the SSL client certificate file for PostgreSQL.
* sslkey?: scalar|Param|null, // The path to the SSL client key file for PostgreSQL.
* sslcrl?: scalar|Param|null, // The file name of the SSL certificate revocation list for PostgreSQL.
* pooled?: bool|Param, // True to use a pooled server with the oci8/pdo_oracle driver
* MultipleActiveResultSets?: bool|Param, // Configuring MultipleActiveResultSets for the pdo_sqlsrv driver
* use_savepoints?: bool|Param, // Use savepoints for nested transactions
* instancename?: scalar|Param|null, // Optional parameter, complete whether to add the INSTANCE_NAME parameter in the connection. It is generally used to connect to an Oracle RAC server to select the name of a particular instance.
* connectstring?: scalar|Param|null, // Complete Easy Connect connection descriptor, see https://docs.oracle.com/database/121/NETAG/naming.htm.When using this option, you will still need to provide the user and password parameters, but the other parameters will no longer be used. Note that when using this parameter, the getHost and getPort methods from Doctrine\DBAL\Connection will no longer function as expected.
* }>,
* replicas?: array<string, array{ // Default: []
* url?: scalar|Param|null, // A URL with connection information; any parameter value parsed from this string will override explicitly set parameters
* dbname?: scalar|Param|null,
* host?: scalar|Param|null, // Defaults to "localhost" at runtime.
* port?: scalar|Param|null, // Defaults to null at runtime.
* user?: scalar|Param|null, // Defaults to "root" at runtime.
* password?: scalar|Param|null, // Defaults to null at runtime.
* override_url?: bool|Param, // Deprecated: The "doctrine.dbal.override_url" configuration key is deprecated.
* dbname_suffix?: scalar|Param|null, // Adds the given suffix to the configured database name, this option has no effects for the SQLite platform
* application_name?: scalar|Param|null,
* charset?: scalar|Param|null,
* path?: scalar|Param|null,
* memory?: bool|Param,
* unix_socket?: scalar|Param|null, // The unix socket to use for MySQL
* persistent?: bool|Param, // True to use as persistent connection for the ibm_db2 driver
* protocol?: scalar|Param|null, // The protocol to use for the ibm_db2 driver (default to TCPIP if omitted)
* service?: bool|Param, // True to use SERVICE_NAME as connection parameter instead of SID for Oracle
* servicename?: scalar|Param|null, // Overrules dbname parameter if given and used as SERVICE_NAME or SID connection parameter for Oracle depending on the service parameter.
* sessionMode?: scalar|Param|null, // The session mode to use for the oci8 driver
* server?: scalar|Param|null, // The name of a running database server to connect to for SQL Anywhere.
* default_dbname?: scalar|Param|null, // Override the default database (postgres) to connect to for PostgreSQL connexion.
* sslmode?: scalar|Param|null, // Determines whether or with what priority a SSL TCP/IP connection will be negotiated with the server for PostgreSQL.
* sslrootcert?: scalar|Param|null, // The name of a file containing SSL certificate authority (CA) certificate(s). If the file exists, the server's certificate will be verified to be signed by one of these authorities.
* sslcert?: scalar|Param|null, // The path to the SSL client certificate file for PostgreSQL.
* sslkey?: scalar|Param|null, // The path to the SSL client key file for PostgreSQL.
* sslcrl?: scalar|Param|null, // The file name of the SSL certificate revocation list for PostgreSQL.
* pooled?: bool|Param, // True to use a pooled server with the oci8/pdo_oracle driver
* MultipleActiveResultSets?: bool|Param, // Configuring MultipleActiveResultSets for the pdo_sqlsrv driver
* use_savepoints?: bool|Param, // Use savepoints for nested transactions
* instancename?: scalar|Param|null, // Optional parameter, complete whether to add the INSTANCE_NAME parameter in the connection. It is generally used to connect to an Oracle RAC server to select the name of a particular instance.
* connectstring?: scalar|Param|null, // Complete Easy Connect connection descriptor, see https://docs.oracle.com/database/121/NETAG/naming.htm.When using this option, you will still need to provide the user and password parameters, but the other parameters will no longer be used. Note that when using this parameter, the getHost and getPort methods from Doctrine\DBAL\Connection will no longer function as expected.
* }>,
* }>,
* },
* orm?: array{
* default_entity_manager?: scalar|Param|null,
* auto_generate_proxy_classes?: scalar|Param|null, // Auto generate mode possible values are: "NEVER", "ALWAYS", "FILE_NOT_EXISTS", "EVAL", "FILE_NOT_EXISTS_OR_CHANGED", this option is ignored when the "enable_native_lazy_objects" option is true // Default: false
* enable_lazy_ghost_objects?: bool|Param, // Enables the new implementation of proxies based on lazy ghosts instead of using the legacy implementation // Default: true
* enable_native_lazy_objects?: bool|Param, // Enables the new native implementation of PHP lazy objects instead of generated proxies // Default: false
* proxy_dir?: scalar|Param|null, // Configures the path where generated proxy classes are saved when using non-native lazy objects, this option is ignored when the "enable_native_lazy_objects" option is true // Default: "%kernel.build_dir%/doctrine/orm/Proxies"
* proxy_namespace?: scalar|Param|null, // Defines the root namespace for generated proxy classes when using non-native lazy objects, this option is ignored when the "enable_native_lazy_objects" option is true // Default: "Proxies"
* controller_resolver?: bool|array{
* enabled?: bool|Param, // Default: true
* auto_mapping?: bool|Param|null, // Set to false to disable using route placeholders as lookup criteria when the primary key doesn't match the argument name // Default: null
* evict_cache?: bool|Param, // Set to true to fetch the entity from the database instead of using the cache, if any // Default: false
* },
* entity_managers?: array<string, array{ // Default: []
* query_cache_driver?: string|array{
* type?: scalar|Param|null, // Default: null
* id?: scalar|Param|null,
* pool?: scalar|Param|null,
* },
* metadata_cache_driver?: string|array{
* type?: scalar|Param|null, // Default: null
* id?: scalar|Param|null,
* pool?: scalar|Param|null,
* },
* result_cache_driver?: string|array{
* type?: scalar|Param|null, // Default: null
* id?: scalar|Param|null,
* pool?: scalar|Param|null,
* },
* entity_listeners?: array{
* entities?: array<string, array{ // Default: []
* listeners?: array<string, array{ // Default: []
* events?: list<array{ // Default: []
* type?: scalar|Param|null,
* method?: scalar|Param|null, // Default: null
* }>,
* }>,
* }>,
* },
* connection?: scalar|Param|null,
* class_metadata_factory_name?: scalar|Param|null, // Default: "Doctrine\\ORM\\Mapping\\ClassMetadataFactory"
* default_repository_class?: scalar|Param|null, // Default: "Doctrine\\ORM\\EntityRepository"
* auto_mapping?: scalar|Param|null, // Default: false
* naming_strategy?: scalar|Param|null, // Default: "doctrine.orm.naming_strategy.default"
* quote_strategy?: scalar|Param|null, // Default: "doctrine.orm.quote_strategy.default"
* typed_field_mapper?: scalar|Param|null, // Default: "doctrine.orm.typed_field_mapper.default"
* entity_listener_resolver?: scalar|Param|null, // Default: null
* fetch_mode_subselect_batch_size?: scalar|Param|null,
* repository_factory?: scalar|Param|null, // Default: "doctrine.orm.container_repository_factory"
* schema_ignore_classes?: list<scalar|Param|null>,
* report_fields_where_declared?: bool|Param, // Set to "true" to opt-in to the new mapping driver mode that was added in Doctrine ORM 2.16 and will be mandatory in ORM 3.0. See https://github.com/doctrine/orm/pull/10455. // Default: true
* validate_xml_mapping?: bool|Param, // Set to "true" to opt-in to the new mapping driver mode that was added in Doctrine ORM 2.14. See https://github.com/doctrine/orm/pull/6728. // Default: false
* second_level_cache?: array{
* region_cache_driver?: string|array{
* type?: scalar|Param|null, // Default: null
* id?: scalar|Param|null,
* pool?: scalar|Param|null,
* },
* region_lock_lifetime?: scalar|Param|null, // Default: 60
* log_enabled?: bool|Param, // Default: true
* region_lifetime?: scalar|Param|null, // Default: 3600
* enabled?: bool|Param, // Default: true
* factory?: scalar|Param|null,
* regions?: array<string, array{ // Default: []
* cache_driver?: string|array{
* type?: scalar|Param|null, // Default: null
* id?: scalar|Param|null,
* pool?: scalar|Param|null,
* },
* lock_path?: scalar|Param|null, // Default: "%kernel.cache_dir%/doctrine/orm/slc/filelock"
* lock_lifetime?: scalar|Param|null, // Default: 60
* type?: scalar|Param|null, // Default: "default"
* lifetime?: scalar|Param|null, // Default: 0
* service?: scalar|Param|null,
* name?: scalar|Param|null,
* }>,
* loggers?: array<string, array{ // Default: []
* name?: scalar|Param|null,
* service?: scalar|Param|null,
* }>,
* },
* hydrators?: array<string, scalar|Param|null>,
* mappings?: array<string, bool|string|array{ // Default: []
* mapping?: scalar|Param|null, // Default: true
* type?: scalar|Param|null,
* dir?: scalar|Param|null,
* alias?: scalar|Param|null,
* prefix?: scalar|Param|null,
* is_bundle?: bool|Param,
* }>,
* dql?: array{
* string_functions?: array<string, scalar|Param|null>,
* numeric_functions?: array<string, scalar|Param|null>,
* datetime_functions?: array<string, scalar|Param|null>,
* },
* filters?: array<string, string|array{ // Default: []
* class?: scalar|Param|null,
* enabled?: bool|Param, // Default: false
* parameters?: array<string, mixed>,
* }>,
* identity_generation_preferences?: array<string, scalar|Param|null>,
* }>,
* resolve_target_entities?: array<string, scalar|Param|null>,
* },
* }
* @psalm-type DoctrineMigrationsConfig = array{
* enable_service_migrations?: bool|Param, // Whether to enable fetching migrations from the service container. // Default: false
* migrations_paths?: array<string, scalar|Param|null>,
* services?: array<string, scalar|Param|null>,
* factories?: array<string, scalar|Param|null>,
* storage?: array{ // Storage to use for migration status metadata.
* table_storage?: array{ // The default metadata storage, implemented as a table in the database.
* table_name?: scalar|Param|null, // Default: null
* version_column_name?: scalar|Param|null, // Default: null
* version_column_length?: scalar|Param|null, // Default: null
* executed_at_column_name?: scalar|Param|null, // Default: null
* execution_time_column_name?: scalar|Param|null, // Default: null
* },
* },
* migrations?: list<scalar|Param|null>,
* connection?: scalar|Param|null, // Connection name to use for the migrations database. // Default: null
* em?: scalar|Param|null, // Entity manager name to use for the migrations database (available when doctrine/orm is installed). // Default: null
* all_or_nothing?: scalar|Param|null, // Run all migrations in a transaction. // Default: false
* check_database_platform?: scalar|Param|null, // Adds an extra check in the generated migrations to allow execution only on the same platform as they were initially generated on. // Default: true
* custom_template?: scalar|Param|null, // Custom template path for generated migration classes. // Default: null
* organize_migrations?: scalar|Param|null, // Organize migrations mode. Possible values are: "BY_YEAR", "BY_YEAR_AND_MONTH", false // Default: false
* enable_profiler?: bool|Param, // Whether or not to enable the profiler collector to calculate and visualize migration status. This adds some queries overhead. // Default: false
* transactional?: bool|Param, // Whether or not to wrap migrations in a single transaction. // Default: true
* }
* @psalm-type KnpuOauth2ClientConfig = array{
* http_client?: scalar|Param|null, // Service id of HTTP client to use (must implement GuzzleHttp\ClientInterface) // Default: null
* http_client_options?: array{
* timeout?: int|Param,
* proxy?: scalar|Param|null,
* verify?: bool|Param, // Use only with proxy option set
* },
* clients?: array<string, array<string, mixed>>,
* }
* @psalm-type SentryConfig = array{
* dsn?: scalar|Param|null, // If this value is not provided, the SDK will try to read it from the SENTRY_DSN environment variable. If that variable also does not exist, the SDK will not send any events.
* register_error_listener?: bool|Param, // Default: true
* register_error_handler?: bool|Param, // Default: true
* logger?: scalar|Param|null, // The service ID of the PSR-3 logger used to log messages coming from the SDK client. Be aware that setting the same logger of the application may create a circular loop when an event fails to be sent. // Default: null
* options?: array{
* integrations?: mixed, // Default: []
* default_integrations?: bool|Param,
* prefixes?: list<scalar|Param|null>,
* sample_rate?: float|Param, // The sampling factor to apply to events. A value of 0 will deny sending any event, and a value of 1 will send all events.
* enable_tracing?: bool|Param,
* traces_sample_rate?: float|Param, // The sampling factor to apply to transactions. A value of 0 will deny sending any transaction, and a value of 1 will send all transactions.
* traces_sampler?: scalar|Param|null,
* profiles_sample_rate?: float|Param, // The sampling factor to apply to profiles. A value of 0 will deny sending any profiles, and a value of 1 will send all profiles. Profiles are sampled in relation to traces_sample_rate
* enable_logs?: bool|Param,
* log_flush_threshold?: mixed, // Default: null
* enable_metrics?: bool|Param, // Default: true
* attach_stacktrace?: bool|Param,
* attach_metric_code_locations?: bool|Param,
* context_lines?: int|Param,
* environment?: scalar|Param|null, // Default: "%kernel.environment%"
* logger?: scalar|Param|null,
* spotlight?: bool|Param,
* spotlight_url?: scalar|Param|null,
* release?: scalar|Param|null, // Default: "%env(default::SENTRY_RELEASE)%"
* org_id?: int|Param,
* server_name?: scalar|Param|null,
* ignore_exceptions?: list<scalar|Param|null>,
* ignore_transactions?: list<scalar|Param|null>,
* before_send?: scalar|Param|null,
* before_send_transaction?: scalar|Param|null,
* before_send_check_in?: scalar|Param|null,
* before_send_metrics?: scalar|Param|null,
* before_send_log?: scalar|Param|null,
* before_send_metric?: scalar|Param|null,
* trace_propagation_targets?: mixed,
* strict_trace_continuation?: bool|Param,
* tags?: array<string, scalar|Param|null>,
* error_types?: scalar|Param|null,
* max_breadcrumbs?: int|Param,
* before_breadcrumb?: mixed,
* in_app_exclude?: list<scalar|Param|null>,
* in_app_include?: list<scalar|Param|null>,
* send_default_pii?: bool|Param,
* max_value_length?: int|Param,
* transport?: scalar|Param|null,
* http_client?: scalar|Param|null,
* http_proxy?: scalar|Param|null,
* http_proxy_authentication?: scalar|Param|null,
* http_connect_timeout?: float|Param, // The maximum number of seconds to wait while trying to connect to a server. It works only when using the default transport.
* http_timeout?: float|Param, // The maximum execution time for the request+response as a whole. It works only when using the default transport.
* http_ssl_verify_peer?: bool|Param,
* http_compression?: bool|Param,
* capture_silenced_errors?: bool|Param,
* max_request_body_size?: "none"|"never"|"small"|"medium"|"always"|Param,
* class_serializers?: array<string, scalar|Param|null>,
* },
* messenger?: bool|array{
* enabled?: bool|Param, // Default: true
* capture_soft_fails?: bool|Param, // Default: true
* isolate_breadcrumbs_by_message?: bool|Param, // Default: false
* isolate_context_by_message?: bool|Param, // Default: false
* },
* tracing?: bool|array{
* enabled?: bool|Param, // Default: true
* dbal?: bool|array{
* enabled?: bool|Param, // Default: true
* ignore_prepare_spans?: bool|Param, // Default: false
* connections?: list<scalar|Param|null>,
* },
* twig?: bool|array{
* enabled?: bool|Param, // Default: true
* },
* cache?: bool|array{
* enabled?: bool|Param, // Default: true
* },
* http_client?: bool|array{
* enabled?: bool|Param, // Default: false
* },
* console?: array{
* excluded_commands?: list<scalar|Param|null>,
* },
* },
* }
* @psalm-type SncRedisConfig = array{
* class?: array{
* client?: scalar|Param|null, // Default: "Predis\\Client"
* client_options?: scalar|Param|null, // Default: "Predis\\Configuration\\Options"
* connection_parameters?: scalar|Param|null, // Default: "Predis\\Connection\\Parameters"
* connection_factory?: scalar|Param|null, // Default: "Snc\\RedisBundle\\Client\\Predis\\Connection\\ConnectionFactory"
* connection_wrapper?: scalar|Param|null, // Default: "Snc\\RedisBundle\\Client\\Predis\\Connection\\ConnectionWrapper"
* phpredis_client?: scalar|Param|null, // Default: "Redis"
* relay_client?: scalar|Param|null, // Default: "Relay\\Relay"
* phpredis_clusterclient?: scalar|Param|null, // Default: "RedisCluster"
* logger?: scalar|Param|null, // Default: "Snc\\RedisBundle\\Logger\\RedisLogger"
* data_collector?: scalar|Param|null, // Default: "Snc\\RedisBundle\\DataCollector\\RedisDataCollector"
* monolog_handler?: scalar|Param|null, // Default: "Monolog\\Handler\\RedisHandler"
* },
* clients?: array<string, array{ // Default: []
* type?: scalar|Param|null,
* alias?: scalar|Param|null,
* logging?: bool|Param, // Default: true
* dsns?: list<mixed>,
* options?: array{
* commands?: array<string, scalar|Param|null>,
* connection_async?: bool|Param, // Default: false
* connection_persistent?: mixed, // Default: false
* connection_timeout?: scalar|Param|null, // Default: 5
* scan?: int|Param, // Default: null
* read_write_timeout?: scalar|Param|null, // Default: null
* iterable_multibulk?: bool|Param, // Default: false
* throw_errors?: bool|Param, // Default: true
* serialization?: scalar|Param|null, // Default: "default"
* cluster?: scalar|Param|null, // Default: null
* prefix?: scalar|Param|null, // Default: null
* replication?: true|"predis"|"sentinel"|Param,
* service?: scalar|Param|null, // Default: null
* slave_failover?: "none"|"error"|"distribute"|"distribute_slaves"|Param,
* parameters?: array{
* database?: scalar|Param|null, // Default: null
* username?: scalar|Param|null, // Default: null
* password?: scalar|Param|null, // Default: null
* sentinel_username?: scalar|Param|null, // Default: null
* sentinel_password?: scalar|Param|null, // Default: null
* logging?: bool|Param, // Default: true
* ssl_context?: mixed, // Default: null
* },
* },
* }>,
* monolog?: array{
* client?: scalar|Param|null,
* key?: scalar|Param|null,
* formatter?: scalar|Param|null,
* },
* }
* @psalm-type MonologConfig = array{
* use_microseconds?: scalar|Param|null, // Default: true
* channels?: list<scalar|Param|null>,
* handlers?: array<string, array{ // Default: []
* type?: scalar|Param|null,
* id?: scalar|Param|null,
* enabled?: bool|Param, // Default: true
* priority?: scalar|Param|null, // Default: 0
* level?: scalar|Param|null, // Default: "DEBUG"
* bubble?: bool|Param, // Default: true
* interactive_only?: bool|Param, // Default: false
* app_name?: scalar|Param|null, // Default: null
* include_stacktraces?: bool|Param, // Default: false
* process_psr_3_messages?: array{
* enabled?: bool|Param|null, // Default: null
* date_format?: scalar|Param|null,
* remove_used_context_fields?: bool|Param,
* },
* path?: scalar|Param|null, // Default: "%kernel.logs_dir%/%kernel.environment%.log"
* file_permission?: scalar|Param|null, // Default: null
* use_locking?: bool|Param, // Default: false
* filename_format?: scalar|Param|null, // Default: "{filename}-{date}"
* date_format?: scalar|Param|null, // Default: "Y-m-d"
* ident?: scalar|Param|null, // Default: false
* logopts?: scalar|Param|null, // Default: 1
* facility?: scalar|Param|null, // Default: "user"
* max_files?: scalar|Param|null, // Default: 0
* action_level?: scalar|Param|null, // Default: "WARNING"
* activation_strategy?: scalar|Param|null, // Default: null
* stop_buffering?: bool|Param, // Default: true
* passthru_level?: scalar|Param|null, // Default: null
* excluded_http_codes?: list<array{ // Default: []
* code?: scalar|Param|null,
* urls?: list<scalar|Param|null>,
* }>,
* accepted_levels?: list<scalar|Param|null>,
* min_level?: scalar|Param|null, // Default: "DEBUG"
* max_level?: scalar|Param|null, // Default: "EMERGENCY"
* buffer_size?: scalar|Param|null, // Default: 0
* flush_on_overflow?: bool|Param, // Default: false
* handler?: scalar|Param|null,
* url?: scalar|Param|null,
* exchange?: scalar|Param|null,
* exchange_name?: scalar|Param|null, // Default: "log"
* channel?: scalar|Param|null, // Default: null
* bot_name?: scalar|Param|null, // Default: "Monolog"
* use_attachment?: scalar|Param|null, // Default: true
* use_short_attachment?: scalar|Param|null, // Default: false
* include_extra?: scalar|Param|null, // Default: false
* icon_emoji?: scalar|Param|null, // Default: null
* webhook_url?: scalar|Param|null,
* exclude_fields?: list<scalar|Param|null>,
* token?: scalar|Param|null,
* region?: scalar|Param|null,
* source?: scalar|Param|null,
* use_ssl?: bool|Param, // Default: true
* user?: mixed,
* title?: scalar|Param|null, // Default: null
* host?: scalar|Param|null, // Default: null
* port?: scalar|Param|null, // Default: 514
* config?: list<scalar|Param|null>,
* members?: list<scalar|Param|null>,
* connection_string?: scalar|Param|null,
* timeout?: scalar|Param|null,
* time?: scalar|Param|null, // Default: 60
* deduplication_level?: scalar|Param|null, // Default: 400
* store?: scalar|Param|null, // Default: null
* connection_timeout?: scalar|Param|null,
* persistent?: bool|Param,
* message_type?: scalar|Param|null, // Default: 0
* parse_mode?: scalar|Param|null, // Default: null
* disable_webpage_preview?: bool|Param|null, // Default: null
* disable_notification?: bool|Param|null, // Default: null
* split_long_messages?: bool|Param, // Default: false
* delay_between_messages?: bool|Param, // Default: false
* topic?: int|Param, // Default: null
* factor?: int|Param, // Default: 1
* tags?: list<scalar|Param|null>,
* console_formatter_options?: mixed, // Default: []
* formatter?: scalar|Param|null,
* nested?: bool|Param, // Default: false
* publisher?: string|array{
* id?: scalar|Param|null,
* hostname?: scalar|Param|null,
* port?: scalar|Param|null, // Default: 12201
* chunk_size?: scalar|Param|null, // Default: 1420
* encoder?: "json"|"compressed_json"|Param,
* },
* mongodb?: string|array{
* id?: scalar|Param|null, // ID of a MongoDB\Client service
* uri?: scalar|Param|null,
* username?: scalar|Param|null,
* password?: scalar|Param|null,
* database?: scalar|Param|null, // Default: "monolog"
* collection?: scalar|Param|null, // Default: "logs"
* },
* elasticsearch?: string|array{
* id?: scalar|Param|null,
* hosts?: list<scalar|Param|null>,
* host?: scalar|Param|null,
* port?: scalar|Param|null, // Default: 9200
* transport?: scalar|Param|null, // Default: "Http"
* user?: scalar|Param|null, // Default: null
* password?: scalar|Param|null, // Default: null
* },
* index?: scalar|Param|null, // Default: "monolog"
* document_type?: scalar|Param|null, // Default: "logs"
* ignore_error?: scalar|Param|null, // Default: false
* redis?: string|array{
* id?: scalar|Param|null,
* host?: scalar|Param|null,
* password?: scalar|Param|null, // Default: null
* port?: scalar|Param|null, // Default: 6379
* database?: scalar|Param|null, // Default: 0
* key_name?: scalar|Param|null, // Default: "monolog_redis"
* },
* predis?: string|array{
* id?: scalar|Param|null,
* host?: scalar|Param|null,
* },
* from_email?: scalar|Param|null,
* to_email?: list<scalar|Param|null>,
* subject?: scalar|Param|null,
* content_type?: scalar|Param|null, // Default: null
* headers?: list<scalar|Param|null>,
* mailer?: scalar|Param|null, // Default: null
* email_prototype?: string|array{
* id?: scalar|Param|null,
* method?: scalar|Param|null, // Default: null
* },
* verbosity_levels?: array{
* VERBOSITY_QUIET?: scalar|Param|null, // Default: "ERROR"
* VERBOSITY_NORMAL?: scalar|Param|null, // Default: "WARNING"
* VERBOSITY_VERBOSE?: scalar|Param|null, // Default: "NOTICE"
* VERBOSITY_VERY_VERBOSE?: scalar|Param|null, // Default: "INFO"
* VERBOSITY_DEBUG?: scalar|Param|null, // Default: "DEBUG"
* },
* channels?: string|array{
* type?: scalar|Param|null,
* elements?: list<scalar|Param|null>,
* },
* }>,
* }
* @psalm-type TwigConfig = array{
* form_themes?: list<scalar|Param|null>,
* globals?: array<string, array{ // Default: []
* id?: scalar|Param|null,
* type?: scalar|Param|null,
* value?: mixed,
* }>,
* autoescape_service?: scalar|Param|null, // Default: null
* autoescape_service_method?: scalar|Param|null, // Default: null
* base_template_class?: scalar|Param|null, // Deprecated: The child node "base_template_class" at path "twig.base_template_class" is deprecated.
* cache?: scalar|Param|null, // Default: true
* charset?: scalar|Param|null, // Default: "%kernel.charset%"
* debug?: bool|Param, // Default: "%kernel.debug%"
* strict_variables?: bool|Param, // Default: "%kernel.debug%"
* auto_reload?: scalar|Param|null,
* optimizations?: int|Param,
* default_path?: scalar|Param|null, // The default path used to load templates. // Default: "%kernel.project_dir%/templates"
* file_name_pattern?: list<scalar|Param|null>,
* paths?: array<string, mixed>,
* date?: array{ // The default format options used by the date filter.
* format?: scalar|Param|null, // Default: "F j, Y H:i"
* interval_format?: scalar|Param|null, // Default: "%d days"
* timezone?: scalar|Param|null, // The timezone used when formatting dates, when set to null, the timezone returned by date_default_timezone_get() is used. // Default: null
* },
* number_format?: array{ // The default format options for the number_format filter.
* decimals?: int|Param, // Default: 0
* decimal_point?: scalar|Param|null, // Default: "."
* thousands_separator?: scalar|Param|null, // Default: ","
* },
* mailer?: array{
* html_to_text_converter?: scalar|Param|null, // A service implementing the "Symfony\Component\Mime\HtmlToTextConverter\HtmlToTextConverterInterface". // Default: null
* },
* }
* @psalm-type TwigExtraConfig = array{
* cache?: bool|array{
* enabled?: bool|Param, // Default: false
* },
* html?: bool|array{
* enabled?: bool|Param, // Default: false
* },
* markdown?: bool|array{
* enabled?: bool|Param, // Default: false
* },
* intl?: bool|array{
* enabled?: bool|Param, // Default: false
* },
* cssinliner?: bool|array{
* enabled?: bool|Param, // Default: false
* },
* inky?: bool|array{
* enabled?: bool|Param, // Default: false
* },
* string?: bool|array{
* enabled?: bool|Param, // Default: false
* },
* commonmark?: array{
* renderer?: array{ // Array of options for rendering HTML.
* block_separator?: scalar|Param|null,
* inner_separator?: scalar|Param|null,
* soft_break?: scalar|Param|null,
* },
* html_input?: "strip"|"allow"|"escape"|Param, // How to handle HTML input.
* allow_unsafe_links?: bool|Param, // Remove risky link and image URLs by setting this to false. // Default: true
* max_nesting_level?: int|Param, // The maximum nesting level for blocks. // Default: 9223372036854775807
* max_delimiters_per_line?: int|Param, // The maximum number of strong/emphasis delimiters per line. // Default: 9223372036854775807
* slug_normalizer?: array{ // Array of options for configuring how URL-safe slugs are created.
* instance?: mixed,
* max_length?: int|Param, // Default: 255
* unique?: mixed,
* },
* commonmark?: array{ // Array of options for configuring the CommonMark core extension.
* enable_em?: bool|Param, // Default: true
* enable_strong?: bool|Param, // Default: true
* use_asterisk?: bool|Param, // Default: true
* use_underscore?: bool|Param, // Default: true
* unordered_list_markers?: list<scalar|Param|null>,
* },
* ...<string, mixed>
* },
* }
* @psalm-type SecurityConfig = array{
* access_denied_url?: scalar|Param|null, // Default: null
* session_fixation_strategy?: "none"|"migrate"|"invalidate"|Param, // Default: "migrate"
* hide_user_not_found?: bool|Param, // Deprecated: The "hide_user_not_found" option is deprecated and will be removed in 8.0. Use the "expose_security_errors" option instead.
* expose_security_errors?: \Symfony\Component\Security\Http\Authentication\ExposeSecurityLevel::None|\Symfony\Component\Security\Http\Authentication\ExposeSecurityLevel::AccountStatus|\Symfony\Component\Security\Http\Authentication\ExposeSecurityLevel::All|Param, // Default: "none"
* erase_credentials?: bool|Param, // Default: true
* access_decision_manager?: array{
* strategy?: "affirmative"|"consensus"|"unanimous"|"priority"|Param,
* service?: scalar|Param|null,
* strategy_service?: scalar|Param|null,
* allow_if_all_abstain?: bool|Param, // Default: false
* allow_if_equal_granted_denied?: bool|Param, // Default: true
* },
* password_hashers?: array<string, string|array{ // Default: []
* algorithm?: scalar|Param|null,
* migrate_from?: list<scalar|Param|null>,
* hash_algorithm?: scalar|Param|null, // Name of hashing algorithm for PBKDF2 (i.e. sha256, sha512, etc..) See hash_algos() for a list of supported algorithms. // Default: "sha512"
* key_length?: scalar|Param|null, // Default: 40
* ignore_case?: bool|Param, // Default: false
* encode_as_base64?: bool|Param, // Default: true
* iterations?: scalar|Param|null, // Default: 5000
* cost?: int|Param, // Default: null
* memory_cost?: scalar|Param|null, // Default: null
* time_cost?: scalar|Param|null, // Default: null
* id?: scalar|Param|null,
* }>,
* providers?: array<string, array{ // Default: []
* id?: scalar|Param|null,
* chain?: array{
* providers?: list<scalar|Param|null>,
* },
* entity?: array{
* class?: scalar|Param|null, // The full entity class name of your user class.
* property?: scalar|Param|null, // Default: null
* manager_name?: scalar|Param|null, // Default: null
* },
* memory?: array{
* users?: array<string, array{ // Default: []
* password?: scalar|Param|null, // Default: null
* roles?: list<scalar|Param|null>,
* }>,
* },
* ldap?: array{
* service?: scalar|Param|null,
* base_dn?: scalar|Param|null,
* search_dn?: scalar|Param|null, // Default: null
* search_password?: scalar|Param|null, // Default: null
* extra_fields?: list<scalar|Param|null>,
* default_roles?: list<scalar|Param|null>,
* role_fetcher?: scalar|Param|null, // Default: null
* uid_key?: scalar|Param|null, // Default: "sAMAccountName"
* filter?: scalar|Param|null, // Default: "({uid_key}={user_identifier})"
* password_attribute?: scalar|Param|null, // Default: null
* },
* }>,
* firewalls?: array<string, array{ // Default: []
* pattern?: scalar|Param|null,
* host?: scalar|Param|null,
* methods?: list<scalar|Param|null>,
* security?: bool|Param, // Default: true
* user_checker?: scalar|Param|null, // The UserChecker to use when authenticating users in this firewall. // Default: "security.user_checker"
* request_matcher?: scalar|Param|null,
* access_denied_url?: scalar|Param|null,
* access_denied_handler?: scalar|Param|null,
* entry_point?: scalar|Param|null, // An enabled authenticator name or a service id that implements "Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface".
* provider?: scalar|Param|null,
* stateless?: bool|Param, // Default: false
* lazy?: bool|Param, // Default: false
* context?: scalar|Param|null,
* logout?: array{
* enable_csrf?: bool|Param|null, // Default: null
* csrf_token_id?: scalar|Param|null, // Default: "logout"
* csrf_parameter?: scalar|Param|null, // Default: "_csrf_token"
* csrf_token_manager?: scalar|Param|null,
* path?: scalar|Param|null, // Default: "/logout"
* target?: scalar|Param|null, // Default: "/"
* invalidate_session?: bool|Param, // Default: true
* clear_site_data?: list<"*"|"cache"|"cookies"|"storage"|"executionContexts"|Param>,
* delete_cookies?: array<string, array{ // Default: []
* path?: scalar|Param|null, // Default: null
* domain?: scalar|Param|null, // Default: null
* secure?: scalar|Param|null, // Default: false
* samesite?: scalar|Param|null, // Default: null
* partitioned?: scalar|Param|null, // Default: false
* }>,
* },
* switch_user?: array{
* provider?: scalar|Param|null,
* parameter?: scalar|Param|null, // Default: "_switch_user"
* role?: scalar|Param|null, // Default: "ROLE_ALLOWED_TO_SWITCH"
* target_route?: scalar|Param|null, // Default: null
* },
* required_badges?: list<scalar|Param|null>,
* custom_authenticators?: list<scalar|Param|null>,
* login_throttling?: array{
* limiter?: scalar|Param|null, // A service id implementing "Symfony\Component\HttpFoundation\RateLimiter\RequestRateLimiterInterface".
* max_attempts?: int|Param, // Default: 5
* interval?: scalar|Param|null, // Default: "1 minute"
* lock_factory?: scalar|Param|null, // The service ID of the lock factory used by the login rate limiter (or null to disable locking). // Default: null
* cache_pool?: string|Param, // The cache pool to use for storing the limiter state // Default: "cache.rate_limiter"
* storage_service?: string|Param, // The service ID of a custom storage implementation, this precedes any configured "cache_pool" // Default: null
* },
* x509?: array{
* provider?: scalar|Param|null,
* user?: scalar|Param|null, // Default: "SSL_CLIENT_S_DN_Email"
* credentials?: scalar|Param|null, // Default: "SSL_CLIENT_S_DN"
* user_identifier?: scalar|Param|null, // Default: "emailAddress"
* },
* remote_user?: array{
* provider?: scalar|Param|null,
* user?: scalar|Param|null, // Default: "REMOTE_USER"
* },
* login_link?: array{
* check_route?: scalar|Param|null, // Route that will validate the login link - e.g. "app_login_link_verify".
* check_post_only?: scalar|Param|null, // If true, only HTTP POST requests to "check_route" will be handled by the authenticator. // Default: false
* signature_properties?: list<scalar|Param|null>,
* lifetime?: int|Param, // The lifetime of the login link in seconds. // Default: 600
* max_uses?: int|Param, // Max number of times a login link can be used - null means unlimited within lifetime. // Default: null
* used_link_cache?: scalar|Param|null, // Cache service id used to expired links of max_uses is set.
* success_handler?: scalar|Param|null, // A service id that implements Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface.
* failure_handler?: scalar|Param|null, // A service id that implements Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface.
* provider?: scalar|Param|null, // The user provider to load users from.
* secret?: scalar|Param|null, // Default: "%kernel.secret%"
* always_use_default_target_path?: bool|Param, // Default: false
* default_target_path?: scalar|Param|null, // Default: "/"
* login_path?: scalar|Param|null, // Default: "/login"
* target_path_parameter?: scalar|Param|null, // Default: "_target_path"
* use_referer?: bool|Param, // Default: false
* failure_path?: scalar|Param|null, // Default: null
* failure_forward?: bool|Param, // Default: false
* failure_path_parameter?: scalar|Param|null, // Default: "_failure_path"
* },
* form_login?: array{
* provider?: scalar|Param|null,
* remember_me?: bool|Param, // Default: true
* success_handler?: scalar|Param|null,
* failure_handler?: scalar|Param|null,
* check_path?: scalar|Param|null, // Default: "/login_check"
* use_forward?: bool|Param, // Default: false
* login_path?: scalar|Param|null, // Default: "/login"
* username_parameter?: scalar|Param|null, // Default: "_username"
* password_parameter?: scalar|Param|null, // Default: "_password"
* csrf_parameter?: scalar|Param|null, // Default: "_csrf_token"
* csrf_token_id?: scalar|Param|null, // Default: "authenticate"
* enable_csrf?: bool|Param, // Default: false
* post_only?: bool|Param, // Default: true
* form_only?: bool|Param, // Default: false
* always_use_default_target_path?: bool|Param, // Default: false
* default_target_path?: scalar|Param|null, // Default: "/"
* target_path_parameter?: scalar|Param|null, // Default: "_target_path"
* use_referer?: bool|Param, // Default: false
* failure_path?: scalar|Param|null, // Default: null
* failure_forward?: bool|Param, // Default: false
* failure_path_parameter?: scalar|Param|null, // Default: "_failure_path"
* },
* form_login_ldap?: array{
* provider?: scalar|Param|null,
* remember_me?: bool|Param, // Default: true
* success_handler?: scalar|Param|null,
* failure_handler?: scalar|Param|null,
* check_path?: scalar|Param|null, // Default: "/login_check"
* use_forward?: bool|Param, // Default: false
* login_path?: scalar|Param|null, // Default: "/login"
* username_parameter?: scalar|Param|null, // Default: "_username"
* password_parameter?: scalar|Param|null, // Default: "_password"
* csrf_parameter?: scalar|Param|null, // Default: "_csrf_token"
* csrf_token_id?: scalar|Param|null, // Default: "authenticate"
* enable_csrf?: bool|Param, // Default: false
* post_only?: bool|Param, // Default: true
* form_only?: bool|Param, // Default: false
* always_use_default_target_path?: bool|Param, // Default: false
* default_target_path?: scalar|Param|null, // Default: "/"
* target_path_parameter?: scalar|Param|null, // Default: "_target_path"
* use_referer?: bool|Param, // Default: false
* failure_path?: scalar|Param|null, // Default: null
* failure_forward?: bool|Param, // Default: false
* failure_path_parameter?: scalar|Param|null, // Default: "_failure_path"
* service?: scalar|Param|null, // Default: "ldap"
* dn_string?: scalar|Param|null, // Default: "{user_identifier}"
* query_string?: scalar|Param|null,
* search_dn?: scalar|Param|null, // Default: ""
* search_password?: scalar|Param|null, // Default: ""
* },
* json_login?: array{
* provider?: scalar|Param|null,
* remember_me?: bool|Param, // Default: true
* success_handler?: scalar|Param|null,
* failure_handler?: scalar|Param|null,
* check_path?: scalar|Param|null, // Default: "/login_check"
* use_forward?: bool|Param, // Default: false
* login_path?: scalar|Param|null, // Default: "/login"
* username_path?: scalar|Param|null, // Default: "username"
* password_path?: scalar|Param|null, // Default: "password"
* },
* json_login_ldap?: array{
* provider?: scalar|Param|null,
* remember_me?: bool|Param, // Default: true
* success_handler?: scalar|Param|null,
* failure_handler?: scalar|Param|null,
* check_path?: scalar|Param|null, // Default: "/login_check"
* use_forward?: bool|Param, // Default: false
* login_path?: scalar|Param|null, // Default: "/login"
* username_path?: scalar|Param|null, // Default: "username"
* password_path?: scalar|Param|null, // Default: "password"
* service?: scalar|Param|null, // Default: "ldap"
* dn_string?: scalar|Param|null, // Default: "{user_identifier}"
* query_string?: scalar|Param|null,
* search_dn?: scalar|Param|null, // Default: ""
* search_password?: scalar|Param|null, // Default: ""
* },
* access_token?: array{
* provider?: scalar|Param|null,
* remember_me?: bool|Param, // Default: true
* success_handler?: scalar|Param|null,
* failure_handler?: scalar|Param|null,
* realm?: scalar|Param|null, // Default: null
* token_extractors?: list<scalar|Param|null>,
* token_handler?: string|array{
* id?: scalar|Param|null,
* oidc_user_info?: string|array{
* base_uri?: scalar|Param|null, // Base URI of the userinfo endpoint on the OIDC server, or the OIDC server URI to use the discovery (require "discovery" to be configured).
* discovery?: array{ // Enable the OIDC discovery.
* cache?: array{
* id?: scalar|Param|null, // Cache service id to use to cache the OIDC discovery configuration.
* },
* },
* claim?: scalar|Param|null, // Claim which contains the user identifier (e.g. sub, email, etc.). // Default: "sub"
* client?: scalar|Param|null, // HttpClient service id to use to call the OIDC server.
* },
* oidc?: array{
* discovery?: array{ // Enable the OIDC discovery.
* base_uri?: list<scalar|Param|null>,
* cache?: array{
* id?: scalar|Param|null, // Cache service id to use to cache the OIDC discovery configuration.
* },
* },
* claim?: scalar|Param|null, // Claim which contains the user identifier (e.g.: sub, email..). // Default: "sub"
* audience?: scalar|Param|null, // Audience set in the token, for validation purpose.
* issuers?: list<scalar|Param|null>,
* algorithm?: array<mixed>,
* algorithms?: list<scalar|Param|null>,
* key?: scalar|Param|null, // Deprecated: The "key" option is deprecated and will be removed in 8.0. Use the "keyset" option instead. // JSON-encoded JWK used to sign the token (must contain a "kty" key).
* keyset?: scalar|Param|null, // JSON-encoded JWKSet used to sign the token (must contain a list of valid public keys).
* encryption?: bool|array{
* enabled?: bool|Param, // Default: false
* enforce?: bool|Param, // When enabled, the token shall be encrypted. // Default: false
* algorithms?: list<scalar|Param|null>,
* keyset?: scalar|Param|null, // JSON-encoded JWKSet used to decrypt the token (must contain a list of valid private keys).
* },
* },
* cas?: array{
* validation_url?: scalar|Param|null, // CAS server validation URL
* prefix?: scalar|Param|null, // CAS prefix // Default: "cas"
* http_client?: scalar|Param|null, // HTTP Client service // Default: null
* },
* oauth2?: scalar|Param|null,
* },
* },
* http_basic?: array{
* provider?: scalar|Param|null,
* realm?: scalar|Param|null, // Default: "Secured Area"
* },
* http_basic_ldap?: array{
* provider?: scalar|Param|null,
* realm?: scalar|Param|null, // Default: "Secured Area"
* service?: scalar|Param|null, // Default: "ldap"
* dn_string?: scalar|Param|null, // Default: "{user_identifier}"
* query_string?: scalar|Param|null,
* search_dn?: scalar|Param|null, // Default: ""
* search_password?: scalar|Param|null, // Default: ""
* },
* remember_me?: array{
* secret?: scalar|Param|null, // Default: "%kernel.secret%"
* service?: scalar|Param|null,
* user_providers?: list<scalar|Param|null>,
* catch_exceptions?: bool|Param, // Default: true
* signature_properties?: list<scalar|Param|null>,
* token_provider?: string|array{
* service?: scalar|Param|null, // The service ID of a custom remember-me token provider.
* doctrine?: bool|array{
* enabled?: bool|Param, // Default: false
* connection?: scalar|Param|null, // Default: null
* },
* },
* token_verifier?: scalar|Param|null, // The service ID of a custom rememberme token verifier.
* name?: scalar|Param|null, // Default: "REMEMBERME"
* lifetime?: int|Param, // Default: 31536000
* path?: scalar|Param|null, // Default: "/"
* domain?: scalar|Param|null, // Default: null
* secure?: true|false|"auto"|Param, // Default: null
* httponly?: bool|Param, // Default: true
* samesite?: null|"lax"|"strict"|"none"|Param, // Default: "lax"
* always_remember_me?: bool|Param, // Default: false
* remember_me_parameter?: scalar|Param|null, // Default: "_remember_me"
* },
* }>,
* access_control?: list<array{ // Default: []
* request_matcher?: scalar|Param|null, // Default: null
* requires_channel?: scalar|Param|null, // Default: null
* path?: scalar|Param|null, // Use the urldecoded format. // Default: null
* host?: scalar|Param|null, // Default: null
* port?: int|Param, // Default: null
* ips?: list<scalar|Param|null>,
* attributes?: array<string, scalar|Param|null>,
* route?: scalar|Param|null, // Default: null
* methods?: list<scalar|Param|null>,
* allow_if?: scalar|Param|null, // Default: null
* roles?: list<scalar|Param|null>,
* }>,
* role_hierarchy?: array<string, string|list<scalar|Param|null>>,
* }
* @psalm-type DebugConfig = array{
* max_items?: int|Param, // Max number of displayed items past the first level, -1 means no limit. // Default: 2500
* min_depth?: int|Param, // Minimum tree depth to clone all the items, 1 is default. // Default: 1
* max_string_length?: int|Param, // Max length of displayed strings, -1 means no limit. // Default: -1
* dump_destination?: scalar|Param|null, // A stream URL where dumps should be written to. // Default: null
* theme?: "dark"|"light"|Param, // Changes the color of the dump() output when rendered directly on the templating. "dark" (default) or "light". // Default: "dark"
* }
* @psalm-type WebProfilerConfig = array{
* toolbar?: bool|array{ // Profiler toolbar configuration
* enabled?: bool|Param, // Default: false
* ajax_replace?: bool|Param, // Replace toolbar on AJAX requests // Default: false
* },
* intercept_redirects?: bool|Param, // Default: false
* excluded_ajax_paths?: scalar|Param|null, // Default: "^/((index|app(_[\\w]+)?)\\.php/)?_wdt"
* }
* @psalm-type ConfigType = array{
* imports?: ImportsConfig,
* parameters?: ParametersConfig,
* services?: ServicesConfig,
* framework?: FrameworkConfig,
* doctrine?: DoctrineConfig,
* doctrine_migrations?: DoctrineMigrationsConfig,
* knpu_oauth2_client?: KnpuOauth2ClientConfig,
* snc_redis?: SncRedisConfig,
* monolog?: MonologConfig,
* twig?: TwigConfig,
* twig_extra?: TwigExtraConfig,
* security?: SecurityConfig,
* "when@dev"?: array{
* imports?: ImportsConfig,
* parameters?: ParametersConfig,
* services?: ServicesConfig,
* framework?: FrameworkConfig,
* doctrine?: DoctrineConfig,
* doctrine_migrations?: DoctrineMigrationsConfig,
* knpu_oauth2_client?: KnpuOauth2ClientConfig,
* snc_redis?: SncRedisConfig,
* monolog?: MonologConfig,
* twig?: TwigConfig,
* twig_extra?: TwigExtraConfig,
* security?: SecurityConfig,
* debug?: DebugConfig,
* web_profiler?: WebProfilerConfig,
* },
* "when@prod"?: array{
* imports?: ImportsConfig,
* parameters?: ParametersConfig,
* services?: ServicesConfig,
* framework?: FrameworkConfig,
* doctrine?: DoctrineConfig,
* doctrine_migrations?: DoctrineMigrationsConfig,
* knpu_oauth2_client?: KnpuOauth2ClientConfig,
* sentry?: SentryConfig,
* snc_redis?: SncRedisConfig,
* monolog?: MonologConfig,
* twig?: TwigConfig,
* twig_extra?: TwigExtraConfig,
* security?: SecurityConfig,
* },
* "when@test"?: array{
* imports?: ImportsConfig,
* parameters?: ParametersConfig,
* services?: ServicesConfig,
* framework?: FrameworkConfig,
* doctrine?: DoctrineConfig,
* doctrine_migrations?: DoctrineMigrationsConfig,
* knpu_oauth2_client?: KnpuOauth2ClientConfig,
* snc_redis?: SncRedisConfig,
* monolog?: MonologConfig,
* twig?: TwigConfig,
* twig_extra?: TwigExtraConfig,
* security?: SecurityConfig,
* debug?: DebugConfig,
* web_profiler?: WebProfilerConfig,
* },
* ...<string, ExtensionType|array{ // extra keys must follow the when@%env% pattern or match an extension alias
* imports?: ImportsConfig,
* parameters?: ParametersConfig,
* services?: ServicesConfig,
* ...<string, ExtensionType>,
* }>
* }
*/
final class App
{
/**
* @param ConfigType $config
*
* @psalm-return ConfigType
*/
public static function config(array $config): array
{
/** @var ConfigType $config */
$config = AppReference::config($config);
return $config;
}
}
namespace Symfony\Component\Routing\Loader\Configurator;
/**
* This class provides array-shapes for configuring the routes of an application.
*
* Example:
*
* ```php
* // config/routes.php
* namespace Symfony\Component\Routing\Loader\Configurator;
*
* return Routes::config([
* 'controllers' => [
* 'resource' => 'routing.controllers',
* ],
* ]);
* ```
*
* @psalm-type RouteConfig = array{
* path: string|array<string,string>,
* controller?: string,
* methods?: string|list<string>,
* requirements?: array<string,string>,
* defaults?: array<string,mixed>,
* options?: array<string,mixed>,
* host?: string|array<string,string>,
* schemes?: string|list<string>,
* condition?: string,
* locale?: string,
* format?: string,
* utf8?: bool,
* stateless?: bool,
* }
* @psalm-type ImportConfig = array{
* resource: string,
* type?: string,
* exclude?: string|list<string>,
* prefix?: string|array<string,string>,
* name_prefix?: string,
* trailing_slash_on_root?: bool,
* controller?: string,
* methods?: string|list<string>,
* requirements?: array<string,string>,
* defaults?: array<string,mixed>,
* options?: array<string,mixed>,
* host?: string|array<string,string>,
* schemes?: string|list<string>,
* condition?: string,
* locale?: string,
* format?: string,
* utf8?: bool,
* stateless?: bool,
* }
* @psalm-type AliasConfig = array{
* alias: string,
* deprecated?: array{package:string, version:string, message?:string},
* }
* @psalm-type RoutesConfig = array{
* "when@dev"?: array<string, RouteConfig|ImportConfig|AliasConfig>,
* "when@prod"?: array<string, RouteConfig|ImportConfig|AliasConfig>,
* "when@test"?: array<string, RouteConfig|ImportConfig|AliasConfig>,
* ...<string, RouteConfig|ImportConfig|AliasConfig>
* }
*/
final class Routes
{
/**
* @param RoutesConfig $config
*
* @psalm-return RoutesConfig
*/
public static function config(array $config): array
{
return $config;
}
}
================================================
FILE: config/routes/framework.yaml
================================================
when@dev:
_errors:
resource: '@FrameworkBundle/Resources/config/routing/errors.php'
prefix: /_error
================================================
FILE: config/routes/security.yaml
================================================
_security_logout:
resource: security.route_loader.logout
type: service
================================================
FILE: config/routes/web_profiler.yaml
================================================
when@dev:
web_profiler_wdt:
resource: '@WebProfilerBundle/Resources/config/routing/wdt.php'
prefix: /_wdt
web_profiler_profiler:
resource: '@WebProfilerBundle/Resources/config/routing/profiler.php'
prefix: /_profiler
================================================
FILE: config/routes.yaml
================================================
# yaml-language-server: $schema=../vendor/symfony/routing/Loader/schema/routing.schema.json
# This file is the entry point to configure the routes of your app.
# Methods with the #[Route] attribute are automatically imported.
# See also https://symfony.com/doc/current/routing.html
# To list all registered routes, run the following command:
# bin/console debug:router
logout:
path: /logout
controllers:
resource:
path: ../src/Controller/
namespace: App\Controller
type: attribute
================================================
FILE: config/services.yaml
================================================
# yaml-language-server: $schema=../vendor/symfony/dependency-injection/Loader/schema/services.schema.json
# This file is the entry point to configure your own services.
# Files in the packages/ subdirectory configure your dependencies.
# See also https://symfony.com/doc/current/service_container/import.html
# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices.html#use-parameters-for-application-configuration
parameters:
services:
# default configuration for services in *this* file
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
App\:
resource: '../src/'
exclude:
- '../src/DependencyInjection/'
- '../src/Kernel.php'
# controllers are imported separately to make sure services can be injected
# as action arguments even if you don't extend any base controller class
App\Controller\:
resource: '../src/Controller/'
tags: ['controller.service_arguments']
# autorwire parameters
App\Github\ClientDiscovery:
arguments:
$clientId: "%env(GITHUB_CLIENT_ID)%"
$clientSecret: "%env(GITHUB_CLIENT_SECRET)%"
App\Controller\DefaultController:
arguments:
$diffInterval: "%env(STATUS_MINUTE_INTERVAL_BEFORE_ALERT)%"
$redis: "@snc_redis.app_cache"
App\PubSubHubbub\Publisher:
arguments:
$hub: "http://pubsubhubbub.appspot.com"
$host: "%env(PROJECT_HOST)%"
$scheme: "%env(PROJECT_SCHEME)%"
App\Command\SyncStarredReposCommand:
arguments:
$transport: "@messenger.transport.sync_starred_repos"
App\Command\SyncVersionsCommand:
arguments:
$transport: "@messenger.transport.sync_versions"
App\Webfeeds\WebfeedsWriter:
tags:
- { name: marcw_rss_writer.extension.writer }
# lazy consumer
# to avoid triggering Github Client Discovery
# which will make a doctrine query on Travis because the default limit to Github will be reached
App\MessageHandler\StarredReposSyncHandler:
lazy: true
arguments:
$redis: "@snc_redis.app_cache"
App\MessageHandler\VersionsSyncHandler:
lazy: true
# github stuff
banditore.client.guzzle:
class: GuzzleHttp\Client
banditore.client.github:
class: Github\Client
factory: [ "@App\\Github\\ClientDiscovery", find ]
# feed stuff
banditore.writer.rss:
class: MarcW\RssWriter\RssWriter
arguments:
- ~
-
core: "@marcw_rss_writer.writer.core"
webfeeds: "@App\\Webfeeds\\WebfeedsWriter"
atom: "@marcw_rss_writer.writer.atom"
- true
- " "
# force this service to be injected at first instead of the default one (from marcw)
MarcW\RssWriter\RssWriter: '@banditore.writer.rss'
App\Pagination\Paginator:
arguments:
-
itemsPerPage: 30
pagesInRange: 5
Predis\Client:
alias: snc_redis.guzzle_cache
GuzzleHttp\Client:
alias: banditore.client.guzzle
Github\Client:
alias: banditore.client.github
# bundle not using recipe OR not compatible with Symfony > 3
marcw_rss_writer.rss_writer:
class: MarcW\RssWriter\RssWriter
marcw_rss_writer.writer.core:
class: MarcW\RssWriter\Extension\Core\CoreWriter
tags:
- { name: marcw_rss_writer.extension.writer }
marcw_rss_writer.writer.atom:
class: MarcW\RssWriter\Extension\Atom\AtomWriter
tags:
- { name: marcw_rss_writer.extension.writer }
================================================
FILE: config/services_test.yaml
================================================
services:
# see https://github.com/symfony/symfony/issues/24543
banditore.client.github.test:
alias: banditore.client.github
public: true
banditore.client.guzzle.test:
alias: banditore.client.guzzle
public: true
================================================
FILE: data/supervisor.conf
================================================
[group:sync_repo]
programs=sync_repo_1,sync_repo_2
[program:sync_repo_1]
directory=/path/to/banditore
command=/usr/bin/php bin/console messenger:consume --limit=5 sync_starred_repos -e prod
autostart=true
autorestart=true
stderr_logfile=/path/to/banditore/var/log/sync_starred_repos_1.err
stdout_logfile=/path/to/banditore/var/log/sync_starred_repos_1.log
user=www-data
environment = http_proxy="",https_proxy=""
[program:sync_repo_2]
directory=/path/to/banditore
command=/usr/bin/php bin/console messenger:consume --limit=5 sync_starred_repos -e prod
autostart=true
autorestart=true
stderr_logfile=/path/to/banditore/var/log/sync_starred_repos_2.err
stdout_logfile=/path/to/banditore/var/log/sync_starred_repos_2.log
user=www-data
environment = http_proxy="",https_proxy=""
[group:sync_version]
programs=sync_version_1,sync_version_2,sync_version_3,sync_version_4
[program:sync_version_1]
directory=/path/to/banditore
command=/usr/bin/php php bin/console messenger:consume --limit=50 sync_versions -e prod
autostart=true
autorestart=true
stderr_logfile=/path/to/banditore/var/log/sync_versions_1.err
stdout_logfile=/path/to/banditore/var/log/sync_versions_1.log
user=www-data
environment = http_proxy="",https_proxy=""
[program:sync_version_2]
directory=/path/to/banditore
command=/usr/bin/php php bin/console messenger:consume --limit=50 sync_versions -e prod
autostart=true
autorestart=true
stderr_logfile=/path/to/banditore/var/log/sync_versions_2.err
stdout_logfile=/path/to/banditore/var/log/sync_versions_2.log
user=www-data
environment = http_proxy="",https_proxy=""
[program:sync_version_3]
directory=/path/to/banditore
command=/usr/bin/php php bin/console messenger:consume --limit=50 sync_versions -e prod
autostart=true
autorestart=true
stderr_logfile=/path/to/banditore/var/log/sync_versions_3.err
stdout_logfile=/path/to/banditore/var/log/sync_versions_3.log
user=www-data
environment = http_proxy="",https_proxy=""
[program:sync_version_4]
directory=/path/to/banditore
command=/usr/bin/php php bin/console messenger:consume --limit=50 sync_versions -e prod
autostart=true
autorestart=true
stderr_logfile=/path/to/banditore/var/log/sync_versions_4.err
stdout_logfile=/path/to/banditore/var/log/sync_versions_4.log
user=www-data
environment = http_proxy="",https_proxy=""
================================================
FILE: migrations/.gitignore
================================================
================================================
FILE: migrations/Version20170222055642.php
================================================
<?php
namespace DoctrineMigrations;
use Doctrine\DBAL\Platforms\AbstractMySQLPlatform;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Add homepage & language to the repo entity.
*/
final class Version20170222055642 extends AbstractMigration
{
public function getDescription(): string
{
return 'Add homepage & language to the repo entity.';
}
public function up(Schema $schema): void
{
$this->abortIf(!$this->connection->getDatabasePlatform() instanceof AbstractMySQLPlatform, 'Migration can only be executed safely on MySQL.');
$repoTable = $schema->getTable('repo');
$this->skipIf($repoTable->hasColumn('homepage') || $repoTable->hasColumn('language'), 'It seems that you already played this migration.');
$this->addSql('ALTER TABLE repo ADD homepage VARCHAR(255) DEFAULT NULL, ADD language VARCHAR(255) DEFAULT NULL');
}
public function down(Schema $schema): void
{
$this->abortIf(!$this->connection->getDatabasePlatform() instanceof AbstractMySQLPlatform, 'Migration can only be executed safely on MySQL.');
$this->addSql('ALTER TABLE repo DROP homepage, DROP language');
}
}
================================================
FILE: migrations/Version20170329095349.php
================================================
<?php
namespace DoctrineMigrations;
use Doctrine\DBAL\Platforms\AbstractMySQLPlatform;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* GitHub name can be null.
*/
final class Version20170329095349 extends AbstractMigration
{
public function getDescription(): string
{
return 'GitHub name can be null.';
}
public function up(Schema $schema): void
{
$this->abortIf(!$this->connection->getDatabasePlatform() instanceof AbstractMySQLPlatform, 'Migration can only be executed safely on MySQL.');
$this->addSql('ALTER TABLE user CHANGE name name VARCHAR(191) DEFAULT NULL');
}
public function down(Schema $schema): void
{
$this->abortIf(!$this->connection->getDatabasePlatform() instanceof AbstractMySQLPlatform, 'Migration can only be executed safely on MySQL.');
$this->addSql('ALTER TABLE user CHANGE name name VARCHAR(191) NOT NULL COLLATE utf8mb4_unicode_ci');
}
}
================================================
FILE: migrations/Version20180827105910.php
================================================
<?php
namespace DoctrineMigrations;
use Doctrine\DBAL\Platforms\AbstractMySQLPlatform;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Mark a repo as removed to avoid checking for new version in the future.
*/
final class Version20180827105910 extends AbstractMigration
{
public function getDescription(): string
{
return 'Mark a repo as removed to avoid checking for new version in the future.';
}
public function up(Schema $schema): void
{
$this->abortIf(!$this->connection->getDatabasePlatform() instanceof AbstractMySQLPlatform, 'Migration can only be executed safely on MySQL.');
$this->addSql('ALTER TABLE repo ADD removed_at DATETIME DEFAULT NULL');
}
public function down(Schema $schema): void
{
$this->abortIf(!$this->connection->getDatabasePlatform() instanceof AbstractMySQLPlatform, 'Migration can only be executed safely on MySQL.');
$this->addSql('ALTER TABLE repo DROP removed_at');
}
}
================================================
FILE: migrations/Version20200511062812.php
================================================
<?php
namespace DoctrineMigrations;
use Doctrine\DBAL\Platforms\AbstractMySQLPlatform;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Mark a user as removed to avoid checking for new starred repos in the future.
*/
final class Version20200511062812 extends AbstractMigration
{
public function getDescription(): string
{
return 'Mark a user as removed to avoid checking for new starred repos in the future.';
}
public function up(Schema $schema): void
{
$this->abortIf(!$this->connection->getDatabasePlatform() instanceof AbstractMySQLPlatform, 'Migration can only be executed safely on MySQL.');
$this->addSql('ALTER TABLE user ADD removed_at DATETIME DEFAULT NULL');
}
public function down(Schema $schema): void
{
$this->abortIf(!$this->connection->getDatabasePlatform() instanceof AbstractMySQLPlatform, 'Migration can only be executed safely on MySQL.');
$this->addSql('ALTER TABLE user DROP removed_at');
}
}
================================================
FILE: migrations/Version20200613153754.php
================================================
<?php
namespace DoctrineMigrations;
use Doctrine\DBAL\Platforms\AbstractMySQLPlatform;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Enforce some relations to not be null.
*/
final class Version20200613153754 extends AbstractMigration
{
public function getDescription(): string
{
return 'Enforce some relations to not be null';
}
public function up(Schema $schema): void
{
$this->abortIf(!$this->connection->getDatabasePlatform() instanceof AbstractMySQLPlatform, 'Migration can only be executed safely on MySQL.');
$this->addSql('ALTER TABLE star CHANGE user_id user_id INT NOT NULL, CHANGE repo_id repo_id INT NOT NULL');
$this->addSql('ALTER TABLE version CHANGE repo_id repo_id INT NOT NULL');
}
public function down(Schema $schema): void
{
$this->abortIf(!$this->connection->getDatabasePlatform() instanceof AbstractMySQLPlatform, 'Migration can only be executed safely on MySQL.');
$this->addSql('ALTER TABLE star CHANGE user_id user_id INT DEFAULT NULL, CHANGE repo_id repo_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE version CHANGE repo_id repo_id INT DEFAULT NULL');
}
}
================================================
FILE: migrations/Version20260408120000.php
================================================
<?php
namespace DoctrineMigrations;
use Doctrine\DBAL\Platforms\AbstractMySQLPlatform;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
final class Version20260408120000 extends AbstractMigration
{
public function getDescription(): string
{
return 'Add per-user repo flag to ignore releases in RSS feeds';
}
public function up(Schema $schema): void
{
$this->abortIf(!$this->connection->getDatabasePlatform() instanceof AbstractMySQLPlatform, 'Migration can only be executed safely on MySQL.');
$this->addSql('ALTER TABLE star ADD ignored_in_feed TINYINT(1) DEFAULT 0 NOT NULL');
}
public function down(Schema $schema): void
{
$this->abortIf(!$this->connection->getDatabasePlatform() instanceof AbstractMySQLPlatform, 'Migration can only be executed safely on MySQL.');
$this->addSql('ALTER TABLE star DROP ignored_in_feed');
}
}
================================================
FILE: phpstan.dist.neon
================================================
parameters:
level: max
paths:
- src
- tests
symfony:
containerXmlPath: %rootDir%/../../../var/cache/test/App_KernelTestDebugContainer.xml
consoleApplicationLoader: tests/console-application.php
doctrine:
objectManagerLoader: tests/object-manager.php
ignoreErrors:
-
identifier: missingType.iterableValue
-
identifier: offsetAccess.nonOffsetAccessible
-
identifier: argument.type
-
identifier: cast.int
-
identifier: cast.string
-
identifier: foreach.nonIterable
-
identifier: binaryOp.invalid
-
identifier: method.nonObject
-
path: src/Pagination/PaginatorInterface.php
identifier: throws.notThrowable
-
path: src/Repository/VersionRepository.php
identifier: return.type
-
path: tests/Security/GithubAuthenticatorTest.php
identifier: deadCode.unreachable
count: 2
-
path: tests/bootstrap.php
identifier: function.alreadyNarrowedType
count: 1
-
path: src/Cache/PredisCachePool.php
identifier: return.type
count: 2
-
path: src/Entity/User.php
identifier: return.type
count: 1
inferPrivatePropertyTypeFromConstructor: true
treatPhpDocTypesAsCertain: false
================================================
FILE: phpunit.xml.dist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!-- https://phpunit.readthedocs.io/en/latest/configuration.html -->
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/11.5/phpunit.xsd" backupGlobals="false" colors="true" bootstrap="tests/bootstrap.php" cacheDirectory=".phpunit.cache">
<php>
<ini name="error_reporting" value="-1"/>
<server name="APP_ENV" value="test" force="true"/>
<server name="SHELL_VERBOSITY" value="-1"/>
<server name="APP_DEBUG" value="0"/>
<env name="SYMFONY_DEPRECATIONS_HELPER" value="weak"/>
</php>
<testsuites>
<testsuite name="Project Test Suite">
<directory>tests</directory>
</testsuite>
</testsuites>
<source>
<include>
<directory suffix=".php">src</directory>
</include>
<exclude>
<directory>src/DataFixtures</directory>
<directory>src/Migrations</directory>
</exclude>
</source>
</phpunit>
================================================
FILE: public/css/banditore.css
================================================
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
/*
* -- BASE STYLES --
* Most of these are inherited from Base, but I want to change a few.
*/
body {
line-height: 1.7em;
color: #7f8c8d;
font-size: 13px;
background: #10556B;
}
a {
color: #7f8c8d;
}
h1,
h2,
h3,
h4,
h5,
h6,
label {
color: #34495e;
}
.pure-img-responsive {
max-width: 100%;
height: auto;
}
/*
* -- LAYOUT STYLES --
* These are some useful classes which I will need
*/
.l-box {
padding: 0 1em;
}
.l-box-lrg {
padding: 2em;
border-bottom: 1px solid rgba(0,0,0,0.1);
}
.is-center {
text-align: center;
}
/*
* -- PURE FORM STYLES --
* Style the form inputs and labels
*/
.pure-form label {
margin: 1em 0 0;
font-weight: bold;
font-size: 100%;
}
.pure-form input[type] {
border: 2px solid #ddd;
box-shadow: none;
font-size: 100%;
width: 100%;
margin-bottom: 1em;
}
/*
* -- PURE BUTTON STYLES --
* I want my pure-button elements to look a little different
*/
.pure-button {
background-color: #2B687F;
color: white;
padding: 0.5em 2em;
border-radius: 5px;
}
a.pure-button-primary {
background: #FFAB80;
color: white;
border-radius: 5px;
font-size: 120%;
}
a.pure-button-primary:hover {
color: #2B687F;
}
/*
* -- MENU STYLES --
* I want to customize how my .pure-menu looks at the top of the page
*/
.menu-wrapper {
background-color: #10556B;
/*margin-bottom: 1em;*/
/*-webkit-font-smoothing: antialiased;*/
height: 3.8em;
padding: 8px 0;
overflow: hidden;
-webkit-transition: height 0.5s;
-moz-transition: height 0.5s;
-ms-transition: height 0.5s;
transition: height 0.5s;
/*box-shadow: 0 1px 1px rgba(0,0,0, 0.10);*/
}
.pure-menu li a {
color: #6FBEF3;
}
.pure-menu li a:hover,
.pure-menu li a:focus {
color: white;
background-color: #10556B;
}
.pure-menu-heading {
color: #FFAB80;
font-weight: 400;
font-size: 120%;
}
.menu-wrapper.open {
height: 12.5em;
}
.menu-can-transform {
text-align: left;
}
.menu-toggle {
width: 34px;
height: 34px;
display: block;
position: absolute;
top: 0;
right: 0;
margin: 7px;
}
.menu-toggle .bar {
background-color: #777;
display: block;
width: 20px;
height: 2px;
border-radius: 100px;
position: absolute;
top: 18px;
right: 7px;
-webkit-transition: all 0.5s;
-moz-transition: all 0.5s;
-ms-transition: all 0.5s;
transition: all 0.5s;
}
.menu-toggle .bar:first-child {
-webkit-transform: translateY(-6px);
-moz-transform: translateY(-6px);
-ms-transform: translateY(-6px);
transform: translateY(-6px);
}
.menu-toggle.x .bar {
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
}
.menu-toggle.x .bar:first-child {
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
transform: rotate(-45deg);
}
/*
* -- SPLASH STYLES --
* This is the blue top section that appears on the page.
*/
.splash-container {
background: #2B687F;
padding: 80px 0 70px;
}
.splash {
/* absolute center .splash within .splash-container */
width: 80%;
height: 50%;
margin: 0 auto;
/*position: absolute;*/
top: 0;
left: 0;
bottom: 0;
right: 0;
text-align: center;
text-transform: uppercase;
}
.splash p {
color: #D5E1E5;
letter-spacing: 0.05em;
}
/* This is the main heading that appears on the blue section */
.splash-head {
font-size: 20px;
color: white;
border: 3px solid #FFAB80;
padding: 1em 1.6em;
font-weight: 100;
border-radius: 5px;
line-height: 1.3em;
}
/*
* -- CONTENT STYLES --
* This represents the content area (everything below the blue section)
*/
.content-wrapper {
/* These styles are required for the "scroll-over" effect */
/*position: absolute;*/
/*top: 69%;*/
/*width: 100%;*/
/*min-height: 12%;*/
/*z-index: 2;*/
background: #2B687F;
margin: 0 auto;
/*padding-top: 51px;*/
}
/* We want to give the content area some more padding */
.content {
padding: 1em;
background: white;
}
/* This is the class used for the main content headers (<h2>) */
.content-head {
font-weight: 400;
text-transform: uppercase;
letter-spacing: 0.1em;
margin: 2em 0 1em;
}
/* This is a modifier class used when the content-head is inside a ribbon */
.content-head-ribbon {
color: white;
}
/* This is the class used for the content sub-headers (<h3>) */
.content-subhead {
color: #2B687F;
}
.content-subhead i {
margin-right: 7px;
}
/* This is the class used for the dark-background areas. */
.ribbon {
background: #10556B;
color: #aaa;
}
img.repo-avatar {
vertical-align: middle;
width: 25px;
}
.image-productivity,
.image-megaphone {
display: none;
}
aside.feed {
background: #2B687F;
margin: 1em auto;
padding: 0.3em 1em;
border-radius: 3px;
color: #fff;
display: block;
}
aside.feed a {
color: #FFAB80;
text-decoration: none;
}
aside.feed a:hover {
text-decoration: underline;
}
aside.feed b:after {
content: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACGklEQVQ4T53TX0hTURzA8e/d3XbnxLUlpaOkFZW0IQqJkQ8t6GHuodAX3YOi/aGQeqgnrd4iCOrVpIdhovUWIiQsoX9oPkSFPdjIbGrDJ3Pq5pzc/bk3NuWWNkI7T4dzzu9zfr8f5wg/b5a6VUV4jMBBdjZmUWkV5jvs0/8RvH6Vyoww32lXs3PDgWr0ZcdRFn+QCn9EiS9sKx8NMJ++RqHn1oaskpoeIzH6iOTk639CGmAsP4Op2oe+pBxxz2EtKPn1JSvPbqCsRvJCGvDnrljsoKD2EgUnWkA0kFmeI+pvJBOZ/QvRAKmqAaniHOm5ceTxgVyQ3u7C0tKDaCsjsxRmucuLkljahOTvgZJmbcxPfPgeusLdWNufI1r3I38JEHtyMT8g7j2K8YgbyenBcKg2dyj57S3Rvlb0die29iHQiSz7G0mF3mlI3h5IzjqKmroQjGYSI92sBu5S1HAfU00zyclXRHtb8gCCgFRxFjJp5GAAyenF0uyHTIrIg5PoTEXYrr8BJc3CHReqvJJDfjexsh6Lrzu3GOs/jxwcxnplEIOjJpdBNpPijg/orPuI9vhITo1sAaoasDQ93AAuIAdfYHZfpbDuNvLEELGnl9nV1k/2vcQHO1l737cZIFtCZf16CRNDoKroS49hdHrILIaRPw8gubyIJeWkvo+SCn/SgBnAsa2Hv/WQIISyv/EU0LvjHykIIRTafgEZntfprlNojgAAAABJRU5ErkJggg==');
vertical-align: text-top;
margin-left: 5px;
}
/*
* -- DASHBOARD TABLE --
*
* From https://codepen.io/geoffyuen/pen/FCBEg?editors=1100
*/
.pure-table-rwd {
margin: 0 auto;
min-width: 300px;
}
.pure-table-rwd tr {
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
}
.pure-table-rwd th {
display: none;
}
.pure-table-rwd td {
display: block;
}
.pure-table-rwd td:first-child {
padding-top: .5em;
}
.pure-table-rwd td:last-child {
padding-bottom: .5em;
}
.pure-table-rwd td:before {
content: attr(data-th) ": ";
font-weight: bold;
width: 3.5em;
display: inline-block;
}
.pure-table-rwd th, .pure-table-rwd td {
text-align: left;
border-left-width: 0;
}
/*
* Pagination
*
* From https://www.bypeople.com/quick-and-simple-pagination-cssdeck/
*/
.pagination {
text-align: center;
margin: 20px
}
.pagination a.previous,
.pagination a.next {
display: none;
}
.pagination a, .pagination strong {
color: #4A4A4A;
border: 0;
outline: 0;
background: #fff;
display: inline-block;
margin-right: 3px;
padding: 4px 12px;
text-decoration: none;
line-height: 1.5em;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
}
.pagination a:hover {
background-color: #10556B;
color: #fff;
}
.pagination a:active {
background: rgba(190, 190, 190, 0.75);
}
.pagination strong {
color: #fff;
background-color: #FFAB80;
}
/*
* -- ALERTS --
*
* From https://isabelcastillo.com/error-info-messages-css
*/
.alert {
margin: 10px 0;
padding: 12px;
border-radius: .5em;
}
.alert span {
float: right;
margin-top: -10px;
padding-left: 5px;
cursor: pointer;
text-transform: uppercase;
}
.alert.info {
color: #00529B;
background-color: #BDE5F8;
}
.alert.success {
color: #4F8A10;
background-color: #DFF2BF;
}
.alert.warning {
color: #9F6000;
background-color: #FEEFB3;
}
.alert.error {
color: #D8000C;
background-color: #FFBABA;
}
/*
* -- LABELS --
*
* From http://www.gumbyframework.com/docs/ui-kit/#!/indicators
*/
.label_info, .label_success, .label_warning, .label_error, .label_prerelease {
padding: 0 5px;
font-size: 12px;
border-radius: 2px;
height: 20px;
display: inline-block;
font-weight: bold;
line-height: 20px;
text-align: center;
color: #fff;
}
.label_info {
background: #4a4d50;
}
.label_success {
background: #58c026;
}
.label_warning {
background: #f6b83f;
color: #644405;
}
.label_error {
background: #ca3838;
}
.label_prerelease {
background: #ffab80;
}
.feed-status {
display: inline-block;
min-width: 5.5em;
padding: 0.15em 0.55em;
border-radius: 999px;
background: #EAF2F5;
color: #10556B;
font-size: 12px;
font-weight: bold;
line-height: 1.5;
text-align: center;
}
.feed-status-muted {
background: #FFF0E8;
color: #AF5D37;
}
.feed-toggle-form {
display: inline;
margin-left: 0.45em;
}
.feed-toggle-button {
-webkit-appearance: none;
appearance: none;
background: none;
background-color: transparent;
border: 0;
border-radius: 0;
box-shadow: none;
color: #10556B;
cursor: pointer;
display: inline;
font: inherit;
font-size: 14px;
font-weight: 600;
line-height: inherit;
margin: 0;
outline: none;
padding: 0;
text-decoration: underline;
text-underline-offset: 2px;
vertical-align: baseline;
}
.feed-toggle-button:hover,
.feed-toggle-button:focus {
color: #2B687F;
}
.included-indicator {
color: #58c026;
display: inline-block;
font-size: 15px;
line-height: 1;
vertical-align: middle;
}
.excluded-indicator {
color: #ca3838;
display: inline-block;
font-size: 15px;
line-height: 1;
vertical-align: middle;
}
/* This is the class used for the footer */
.footer {
background: #10556B;
color: #E6E6E6;
padding: 1em;
}
.footer a {
color: #FFAB80;
text-decoration: none;
}
.footer a:hover {
text-decoration: underline
}
/*
* -- TABLET (AND UP) MEDIA QUERIES --
*/
@media (min-width: 48em) {
/* We increase the body font size */
body {
font-size: 16px;
}
/* We can align the menu header to the left, but float the menu items to the right. */
.home-menu {
text-align: left;
}
.home-menu ul {
float: right;
}
.pure-menu-item.item-logged-in,
.pure-menu-item.item-github {
display: inline-block;
}
.menu-can-transform {
text-align: right;
}
.menu-toggle {
display: none;
}
.splash-head {
font-size: 250%;
}
/* We remove the border-separator assigned to .l-box-lrg */
.l-box-lrg {
border: none;
}
.content {
padding: 1em 1em 3em;
}
.image-productivity,
.image-megaphone {
display: initial;
}
.pure-table td:before {
display: none;
}
.pure-table tr {
border-top: 0;
border-bottom: 0;
}
.pure-table th, .pure-table td {
display: table-cell;
border-left: 1px solid #cbcbcb;
}
.pagination a.previous,
.pagination a.next {
display: inline-block;
}
}
/*
* -- DESKTOP (AND UP) MEDIA QUERIES --
*/
@media (min-width: 78em) {
/* We increase the header font size even more */
.splash-head {
font-size: 300%;
}
.middle-content {
width: 980px;
margin: 0 auto;
}
.l-box {
padding: 1em;
}
}
================================================
FILE: public/css/grids-responsive-min.css
================================================
/*!
Pure v3.0.0
Copyright 2013 Yahoo!
Licensed under the BSD License.
https://github.com/pure-css/pure/blob/master/LICENSE
*/
@media screen and (min-width:35.5em){.pure-u-sm-1,.pure-u-sm-1-1,.pure-u-sm-1-12,.pure-u-sm-1-2,.pure-u-sm-1-24,.pure-u-sm-1-3,.pure-u-sm-1-4,.pure-u-sm-1-5,.pure-u-sm-1-6,.pure-u-sm-1-8,.pure-u-sm-10-24,.pure-u-sm-11-12,.pure-u-sm-11-24,.pure-u-sm-12-24,.pure-u-sm-13-24,.pure-u-sm-14-24,.pure-u-sm-15-24,.pure-u-sm-16-24,.pure-u-sm-17-24,.pure-u-sm-18-24,.pure-u-sm-19-24,.pure-u-sm-2-24,.pure-u-sm-2-3,.pure-u-sm-2-5,.pure-u-sm-20-24,.pure-u-sm-21-24,.pure-u-sm-22-24,.pure-u-sm-23-24,.pure-u-sm-24-24,.pure-u-sm-3-24,.pure-u-sm-3-4,.pure-u-sm-3-5,.pure-u-sm-3-8,.pure-u-sm-4-24,.pure-u-sm-4-5,.pure-u-sm-5-12,.pure-u-sm-5-24,.pure-u-sm-5-5,.pure-u-sm-5-6,.pure-u-sm-5-8,.pure-u-sm-6-24,.pure-u-sm-7-12,.pure-u-sm-7-24,.pure-u-sm-7-8,.pure-u-sm-8-24,.pure-u-sm-9-24{display:inline-block;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-u-sm-1-24{width:4.1667%}.pure-u-sm-1-12,.pure-u-sm-2-24{width:8.3333%}.pure-u-sm-1-8,.pure-u-sm-3-24{width:12.5%}.pure-u-sm-1-6,.pure-u-sm-4-24{width:16.6667%}.pure-u-sm-1-5{width:20%}.pure-u-sm-5-24{width:20.8333%}.pure-u-sm-1-4,.pure-u-sm-6-24{width:25%}.pure-u-sm-7-24{width:29.1667%}.pure-u-sm-1-3,.pure-u-sm-8-24{width:33.3333%}.pure-u-sm-3-8,.pure-u-sm-9-24{width:37.5%}.pure-u-sm-2-5{width:40%}.pure-u-sm-10-24,.pure-u-sm-5-12{width:41.6667%}.pure-u-sm-11-24{width:45.8333%}.pure-u-sm-1-2,.pure-u-sm-12-24{width:50%}.pure-u-sm-13-24{width:54.1667%}.pure-u-sm-14-24,.pure-u-sm-7-12{width:58.3333%}.pure-u-sm-3-5{width:60%}.pure-u-sm-15-24,.pure-u-sm-5-8{width:62.5%}.pure-u-sm-16-24,.pure-u-sm-2-3{width:66.6667%}.pure-u-sm-17-24{width:70.8333%}.pure-u-sm-18-24,.pure-u-sm-3-4{width:75%}.pure-u-sm-19-24{width:79.1667%}.pure-u-sm-4-5{width:80%}.pure-u-sm-20-24,.pure-u-sm-5-6{width:83.3333%}.pure-u-sm-21-24,.pure-u-sm-7-8{width:87.5%}.pure-u-sm-11-12,.pure-u-sm-22-24{width:91.6667%}.pure-u-sm-23-24{width:95.8333%}.pure-u-sm-1,.pure-u-sm-1-1,.pure-u-sm-24-24,.pure-u-sm-5-5{width:100%}}@media screen and (min-width:48em){.pure-u-md-1,.pure-u-md-1-1,.pure-u-md-1-12,.pure-u-md-1-2,.pure-u-md-1-24,.pure-u-md-1-3,.pure-u-md-1-4,.pure-u-md-1-5,.pure-u-md-1-6,.pure-u-md-1-8,.pure-u-md-10-24,.pure-u-md-11-12,.pure-u-md-11-24,.pure-u-md-12-24,.pure-u-md-13-24,.pure-u-md-14-24,.pure-u-md-15-24,.pure-u-md-16-24,.pure-u-md-17-24,.pure-u-md-18-24,.pure-u-md-19-24,.pure-u-md-2-24,.pure-u-md-2-3,.pure-u-md-2-5,.pure-u-md-20-24,.pure-u-md-21-24,.pure-u-md-22-24,.pure-u-md-23-24,.pure-u-md-24-24,.pure-u-md-3-24,.pure-u-md-3-4,.pure-u-md-3-5,.pure-u-md-3-8,.pure-u-md-4-24,.pure-u-md-4-5,.pure-u-md-5-12,.pure-u-md-5-24,.pure-u-md-5-5,.pure-u-md-5-6,.pure-u-md-5-8,.pure-u-md-6-24,.pure-u-md-7-12,.pure-u-md-7-24,.pure-u-md-7-8,.pure-u-md-8-24,.pure-u-md-9-24{display:inline-block;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-u-md-1-24{width:4.1667%}.pure-u-md-1-12,.pure-u-md-2-24{width:8.3333%}.pure-u-md-1-8,.pure-u-md-3-24{width:12.5%}.pure-u-md-1-6,.pure-u-md-4-24{width:16.6667%}.pure-u-md-1-5{width:20%}.pure-u-md-5-24{width:20.8333%}.pure-u-md-1-4,.pure-u-md-6-24{width:25%}.pure-u-md-7-24{width:29.1667%}.pure-u-md-1-3,.pure-u-md-8-24{width:33.3333%}.pure-u-md-3-8,.pure-u-md-9-24{width:37.5%}.pure-u-md-2-5{width:40%}.pure-u-md-10-24,.pure-u-md-5-12{width:41.6667%}.pure-u-md-11-24{width:45.8333%}.pure-u-md-1-2,.pure-u-md-12-24{width:50%}.pure-u-md-13-24{width:54.1667%}.pure-u-md-14-24,.pure-u-md-7-12{width:58.3333%}.pure-u-md-3-5{width:60%}.pure-u-md-15-24,.pure-u-md-5-8{width:62.5%}.pure-u-md-16-24,.pure-u-md-2-3{width:66.6667%}.pure-u-md-17-24{width:70.8333%}.pure-u-md-18-24,.pure-u-md-3-4{width:75%}.pure-u-md-19-24{width:79.1667%}.pure-u-md-4-5{width:80%}.pure-u-md-20-24,.pure-u-md-5-6{width:83.3333%}.pure-u-md-21-24,.pure-u-md-7-8{width:87.5%}.pure-u-md-11-12,.pure-u-md-22-24{width:91.6667%}.pure-u-md-23-24{width:95.8333%}.pure-u-md-1,.pure-u-md-1-1,.pure-u-md-24-24,.pure-u-md-5-5{width:100%}}@media screen and (min-width:64em){.pure-u-lg-1,.pure-u-lg-1-1,.pure-u-lg-1-12,.pure-u-lg-1-2,.pure-u-lg-1-24,.pure-u-lg-1-3,.pure-u-lg-1-4,.pure-u-lg-1-5,.pure-u-lg-1-6,.pure-u-lg-1-8,.pure-u-lg-10-24,.pure-u-lg-11-12,.pure-u-lg-11-24,.pure-u-lg-12-24,.pure-u-lg-13-24,.pure-u-lg-14-24,.pure-u-lg-15-24,.pure-u-lg-16-24,.pure-u-lg-17-24,.pure-u-lg-18-24,.pure-u-lg-19-24,.pure-u-lg-2-24,.pure-u-lg-2-3,.pure-u-lg-2-5,.pure-u-lg-20-24,.pure-u-lg-21-24,.pure-u-lg-22-24,.pure-u-lg-23-24,.pure-u-lg-24-24,.pure-u-lg-3-24,.pure-u-lg-3-4,.pure-u-lg-3-5,.pure-u-lg-3-8,.pure-u-lg-4-24,.pure-u-lg-4-5,.pure-u-lg-5-12,.pure-u-lg-5-24,.pure-u-lg-5-5,.pure-u-lg-5-6,.pure-u-lg-5-8,.pure-u-lg-6-24,.pure-u-lg-7-12,.pure-u-lg-7-24,.pure-u-lg-7-8,.pure-u-lg-8-24,.pure-u-lg-9-24{display:inline-block;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-u-lg-1-24{width:4.1667%}.pure-u-lg-1-12,.pure-u-lg-2-24{width:8.3333%}.pure-u-lg-1-8,.pure-u-lg-3-24{width:12.5%}.pure-u-lg-1-6,.pure-u-lg-4-24{width:16.6667%}.pure-u-lg-1-5{width:20%}.pure-u-lg-5-24{width:20.8333%}.pure-u-lg-1-4,.pure-u-lg-6-24{width:25%}.pure-u-lg-7-24{width:29.1667%}.pure-u-lg-1-3,.pure-u-lg-8-24{width:33.3333%}.pure-u-lg-3-8,.pure-u-lg-9-24{width:37.5%}.pure-u-lg-2-5{width:40%}.pure-u-lg-10-24,.pure-u-lg-5-12{width:41.6667%}.pure-u-lg-11-24{width:45.8333%}.pure-u-lg-1-2,.pure-u-lg-12-24{width:50%}.pure-u-lg-13-24{width:54.1667%}.pure-u-lg-14-24,.pure-u-lg-7-12{width:58.3333%}.pure-u-lg-3-5{width:60%}.pure-u-lg-15-24,.pure-u-lg-5-8{width:62.5%}.pure-u-lg-16-24,.pure-u-lg-2-3{width:66.6667%}.pure-u-lg-17-24{width:70.8333%}.pure-u-lg-18-24,.pure-u-lg-3-4{width:75%}.pure-u-lg-19-24{width:79.1667%}.pure-u-lg-4-5{width:80%}.pure-u-lg-20-24,.pure-u-lg-5-6{width:83.3333%}.pure-u-lg-21-24,.pure-u-lg-7-8{width:87.5%}.pure-u-lg-11-12,.pure-u-lg-22-24{width:91.6667%}.pure-u-lg-23-24{width:95.8333%}.pure-u-lg-1,.pure-u-lg-1-1,.pure-u-lg-24-24,.pure-u-lg-5-5{width:100%}}@media screen and (min-width:80em){.pure-u-xl-1,.pure-u-xl-1-1,.pure-u-xl-1-12,.pure-u-xl-1-2,.pure-u-xl-1-24,.pure-u-xl-1-3,.pure-u-xl-1-4,.pure-u-xl-1-5,.pure-u-xl-1-6,.pure-u-xl-1-8,.pure-u-xl-10-24,.pure-u-xl-11-12,.pure-u-xl-11-24,.pure-u-xl-12-24,.pure-u-xl-13-24,.pure-u-xl-14-24,.pure-u-xl-15-24,.pure-u-xl-16-24,.pure-u-xl-17-24,.pure-u-xl-18-24,.pure-u-xl-19-24,.pure-u-xl-2-24,.pure-u-xl-2-3,.pure-u-xl-2-5,.pure-u-xl-20-24,.pure-u-xl-21-24,.pure-u-xl-22-24,.pure-u-xl-23-24,.pure-u-xl-24-24,.pure-u-xl-3-24,.pure-u-xl-3-4,.pure-u-xl-3-5,.pure-u-xl-3-8,.pure-u-xl-4-24,.pure-u-xl-4-5,.pure-u-xl-5-12,.pure-u-xl-5-24,.pure-u-xl-5-5,.pure-u-xl-5-6,.pure-u-xl-5-8,.pure-u-xl-6-24,.pure-u-xl-7-12,.pure-u-xl-7-24,.pure-u-xl-7-8,.pure-u-xl-8-24,.pure-u-xl-9-24{display:inline-block;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-u-xl-1-24{width:4.1667%}.pure-u-xl-1-12,.pure-u-xl-2-24{width:8.3333%}.pure-u-xl-1-8,.pure-u-xl-3-24{width:12.5%}.pure-u-xl-1-6,.pure-u-xl-4-24{width:16.6667%}.pure-u-xl-1-5{width:20%}.pure-u-xl-5-24{width:20.8333%}.pure-u-xl-1-4,.pure-u-xl-6-24{width:25%}.pure-u-xl-7-24{width:29.1667%}.pure-u-xl-1-3,.pure-u-xl-8-24{width:33.3333%}.pure-u-xl-3-8,.pure-u-xl-9-24{width:37.5%}.pure-u-xl-2-5{width:40%}.pure-u-xl-10-24,.pure-u-xl-5-12{width:41.6667%}.pure-u-xl-11-24{width:45.8333%}.pure-u-xl-1-2,.pure-u-xl-12-24{width:50%}.pure-u-xl-13-24{width:54.1667%}.pure-u-xl-14-24,.pure-u-xl-7-12{width:58.3333%}.pure-u-xl-3-5{width:60%}.pure-u-xl-15-24,.pure-u-xl-5-8{width:62.5%}.pure-u-xl-16-24,.pure-u-xl-2-3{width:66.6667%}.pure-u-xl-17-24{width:70.8333%}.pure-u-xl-18-24,.pure-u-xl-3-4{width:75%}.pure-u-xl-19-24{width:79.1667%}.pure-u-xl-4-5{width:80%}.pure-u-xl-20-24,.pure-u-xl-5-6{width:83.3333%}.pure-u-xl-21-24,.pure-u-xl-7-8{width:87.5%}.pure-u-xl-11-12,.pure-u-xl-22-24{width:91.6667%}.pure-u-xl-23-24{width:95.8333%}.pure-u-xl-1,.pure-u-xl-1-1,.pure-u-xl-24-24,.pure-u-xl-5-5{width:100%}}@media screen and (min-width:120em){.pure-u-xxl-1,.pure-u-xxl-1-1,.pure-u-xxl-1-12,.pure-u-xxl-1-2,.pure-u-xxl-1-24,.pure-u-xxl-1-3,.pure-u-xxl-1-4,.pure-u-xxl-1-5,.pure-u-xxl-1-6,.pure-u-xxl-1-8,.pure-u-xxl-10-24,.pure-u-xxl-11-12,.pure-u-xxl-11-24,.pure-u-xxl-12-24,.pure-u-xxl-13-24,.pure-u-xxl-14-24,.pure-u-xxl-15-24,.pure-u-xxl-16-24,.pure-u-xxl-17-24,.pure-u-xxl-18-24,.pure-u-xxl-19-24,.pure-u-xxl-2-24,.pure-u-xxl-2-3,.pure-u-xxl-2-5,.pure-u-xxl-20-24,.pure-u-xxl-21-24,.pure-u-xxl-22-24,.pure-u-xxl-23-24,.pure-u-xxl-24-24,.pure-u-xxl-3-24,.pure-u-xxl-3-4,.pure-u-xxl-3-5,.pure-u-xxl-3-8,.pure-u-xxl-4-24,.pure-u-xxl-4-5,.pure-u-xxl-5-12,.pure-u-xxl-5-24,.pure-u-xxl-5-5,.pure-u-xxl-5-6,.pure-u-xxl-5-8,.pure-u-xxl-6-24,.pure-u-xxl-7-12,.pure-u-xxl-7-24,.pure-u-xxl-7-8,.pure-u-xxl-8-24,.pure-u-xxl-9-24{display:inline-block;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-u-xxl-1-24{width:4.1667%}.pure-u-xxl-1-12,.pure-u-xxl-2-24{width:8.3333%}.pure-u-xxl-1-8,.pure-u-xxl-3-24{width:12.5%}.pure-u-xxl-1-6,.pure-u-xxl-4-24{width:16.6667%}.pure-u-xxl-1-5{width:20%}.pure-u-xxl-5-24{width:20.8333%}.pure-u-xxl-1-4,.pure-u-xxl-6-24{width:25%}.pure-u-xxl-7-24{width:29.1667%}.pure-u-xxl-1-3,.pure-u-xxl-8-24{width:33.3333%}.pure-u-xxl-3-8,.pure-u-xxl-9-24{width:37.5%}.pure-u-xxl-2-5{width:40%}.pure-u-xxl-10-24,.pure-u-xxl-5-12{width:41.6667%}.pure-u-xxl-11-24{width:45.8333%}.pure-u-xxl-1-2,.pure-u-xxl-12-24{width:50%}.pure-u-xxl-13-24{width:54.1667%}.pure-u-xxl-14-24,.pure-u-xxl-7-12{width:58.3333%}.pure-u-xxl-3-5{width:60%}.pure-u-xxl-15-24,.pure-u-xxl-5-8{width:62.5%}.pure-u-xxl-16-24,.pure-u-xxl-2-3{width:66.6667%}.pure-u-xxl-17-24{width:70.8333%}.pure-u-xxl-18-24,.pure-u-xxl-3-4{width:75%}.pure-u-xxl-19-24{width:79.1667%}.pure-u-xxl-4-5{width:80%}.pure-u-xxl-20-24,.pure-u-xxl-5-6{width:83.3333%}.pure-u-xxl-21-24,.pure-u-xxl-7-8{width:87.5%}.pure-u-xxl-11-12,.pure-u-xxl-22-24{width:91.6667%}.pure-u-xxl-23-24{width:95.8333%}.pure-u-xxl-1,.pure-u-xxl-1-1,.pure-u-xxl-24-24,.pure-u-xxl-5-5{width:100%}}@media screen and (min-width:160em){.pure-u-xxxl-1,.pure-u-xxxl-1-1,.pure-u-xxxl-1-12,.pure-u-xxxl-1-2,.pure-u-xxxl-1-24,.pure-u-xxxl-1-3,.pure-u-xxxl-1-4,.pure-u-xxxl-1-5,.pure-u-xxxl-1-6,.pure-u-xxxl-1-8,.pure-u-xxxl-10-24,.pure-u-xxxl-11-12,.pure-u-xxxl-11-24,.pure-u-xxxl-12-24,.pure-u-xxxl-13-24,.pure-u-xxxl-14-24,.pure-u-xxxl-15-24,.pure-u-xxxl-16-24,.pure-u-xxxl-17-24,.pure-u-xxxl-18-24,.pure-u-xxxl-19-24,.pure-u-xxxl-2-24,.pure-u-xxxl-2-3,.pure-u-xxxl-2-5,.pure-u-xxxl-20-24,.pure-u-xxxl-21-24,.pure-u-xxxl-22-24,.pure-u-xxxl-23-24,.pure-u-xxxl-24-24,.pure-u-xxxl-3-24,.pure-u-xxxl-3-4,.pure-u-xxxl-3-5,.pure-u-xxxl-3-8,.pure-u-xxxl-4-24,.pure-u-xxxl-4-5,.pure-u-xxxl-5-12,.pure-u-xxxl-5-24,.pure-u-xxxl-5-5,.pure-u-xxxl-5-6,.pure-u-xxxl-5-8,.pure-u-xxxl-6-24,.pure-u-xxxl-7-12,.pure-u-xxxl-7-24,.pure-u-xxxl-7-8,.pure-u-xxxl-8-24,.pure-u-xxxl-9-24{display:inline-block;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-u-xxxl-1-24{width:4.1667%}.pure-u-xxxl-1-12,.pure-u-xxxl-2-24{width:8.3333%}.pure-u-xxxl-1-8,.pure-u-xxxl-3-24{width:12.5%}.pure-u-xxxl-1-6,.pure-u-xxxl-4-24{width:16.6667%}.pure-u-xxxl-1-5{width:20%}.pure-u-xxxl-5-24{width:20.8333%}.pure-u-xxxl-1-4,.pure-u-xxxl-6-24{width:25%}.pure-u-xxxl-7-24{width:29.1667%}.pure-u-xxxl-1-3,.pure-u-xxxl-8-24{width:33.3333%}.pure-u-xxxl-3-8,.pure-u-xxxl-9-24{width:37.5%}.pure-u-xxxl-2-5{width:40%}.pure-u-xxxl-10-24,.pure-u-xxxl-5-12{width:41.6667%}.pure-u-xxxl-11-24{width:45.8333%}.pure-u-xxxl-1-2,.pure-u-xxxl-12-24{width:50%}.pure-u-xxxl-13-24{width:54.1667%}.pure-u-xxxl-14-24,.pure-u-xxxl-7-12{width:58.3333%}.pure-u-xxxl-3-5{width:60%}.pure-u-xxxl-15-24,.pure-u-xxxl-5-8{width:62.5%}.pure-u-xxxl-16-24,.pure-u-xxxl-2-3{width:66.6667%}.pure-u-xxxl-17-24{width:70.8333%}.pure-u-xxxl-18-24,.pure-u-xxxl-3-4{width:75%}.pure-u-xxxl-19-24{width:79.1667%}.pure-u-xxxl-4-5{width:80%}.pure-u-xxxl-20-24,.pure-u-xxxl-5-6{width:83.3333%}.pure-u-xxxl-21-24,.pure-u-xxxl-7-8{width:87.5%}.pure-u-xxxl-11-12,.pure-u-xxxl-22-24{width:91.6667%}.pure-u-xxxl-23-24{width:95.8333%}.pure-u-xxxl-1,.pure-u-xxxl-1-1,.pure-u-xxxl-24-24,.pure-u-xxxl-5-5{width:100%}}@media screen and (min-width:240em){.pure-u-x4k-1,.pure-u-x4k-1-1,.pure-u-x4k-1-12,.pure-u-x4k-1-2,.pure-u-x4k-1-24,.pure-u-x4k-1-3,.pure-u-x4k-1-4,.pure-u-x4k-1-5,.pure-u-x4k-1-6,.pure-u-x4k-1-8,.pure-u-x4k-10-24,.pure-u-x4k-11-12,.pure-u-x4k-11-24,.pure-u-x4k-12-24,.pure-u-x4k-13-24,.pure-u-x4k-14-24,.pure-u-x4k-15-24,.pure-u-x4k-16-24,.pure-u-x4k-17-24,.pure-u-x4k-18-24,.pure-u-x4k-19-24,.pure-u-x4k-2-24,.pure-u-x4k-2-3,.pure-u-x4k-2-5,.pure-u-x4k-20-24,.pure-u-x4k-21-24,.pure-u-x4k-22-24,.pure-u-x4k-23-24,.pure-u-x4k-24-24,.pure-u-x4k-3-24,.pure-u-x4k-3-4,.pure-u-x4k-3-5,.pure-u-x4k-3-8,.pure-u-x4k-4-24,.pure-u-x4k-4-5,.pure-u-x4k-5-12,.pure-u-x4k-5-24,.pure-u-x4k-5-5,.pure-u-x4k-5-6,.pure-u-x4k-5-8,.pure-u-x4k-6-24,.pure-u-x4k-7-12,.pure-u-x4k-7-24,.pure-u-x4k-7-8,.pure-u-x4k-8-24,.pure-u-x4k-9-24{display:inline-block;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-u-x4k-1-24{width:4.1667%}.pure-u-x4k-1-12,.pure-u-x4k-2-24{width:8.3333%}.pure-u-x4k-1-8,.pure-u-x4k-3-24{width:12.5%}.pure-u-x4k-1-6,.pure-u-x4k-4-24{width:16.6667%}.pure-u-x4k-1-5{width:20%}.pure-u-x4k-5-24{width:20.8333%}.pure-u-x4k-1-4,.pure-u-x4k-6-24{width:25%}.pure-u-x4k-7-24{width:29.1667%}.pure-u-x4k-1-3,.pure-u-x4k-8-24{width:33.3333%}.pure-u-x4k-3-8,.pure-u-x4k-9-24{width:37.5%}.pure-u-x4k-2-5{width:40%}.pure-u-x4k-10-24,.pure-u-x4k-5-12{width:41.6667%}.pure-u-x4k-11-24{width:45.8333%}.pure-u-x4k-1-2,.pure-u-x4k-12-24{width:50%}.pure-u-x4k-13-24{width:54.1667%}.pure-u-x4k-14-24,.pure-u-x4k-7-12{width:58.3333%}.pure-u-x4k-3-5{width:60%}.pure-u-x4k-15-24,.pure-u-x4k-5-8{width:62.5%}.pure-u-x4k-16-24,.pure-u-x4k-2-3{width:66.6667%}.pure-u-x4k-17-24{width:70.8333%}.pure-u-x4k-18-24,.pure-u-x4k-3-4{width:75%}.pure-u-x4k-19-24{width:79.1667%}.pure-u-x4k-4-5{width:80%}.pure-u-x4k-20-24,.pure-u-x4k-5-6{width:83.3333%}.pure-u-x4k-21-24,.pure-u-x4k-7-8{width:87.5%}.pure-u-x4k-11-12,.pure-u-x4k-22-24{width:91.6667%}.pure-u-x4k-23-24{width:95.8333%}.pure-u-x4k-1,.pure-u-x4k-1-1,.pure-u-x4k-24-24,.pure-u-x4k-5-5{width:100%}}
================================================
FILE: public/css/pure-min.css
================================================
/*!
Pure v3.0.0
Copyright 2013 Yahoo!
Licensed under the BSD License.
https://github.com/pure-css/pure/blob/master/LICENSE
*/
/*!
normalize.css v | MIT License | https://necolas.github.io/normalize.css/
Copyright (c) Nicolas Gallagher and Jonathan Neal
*/
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,selec
gitextract_xx2gl39y/
├── .editorconfig
├── .github/
│ ├── FUNDING.yml
│ ├── dependabot.yml
│ ├── release.yml
│ └── workflows/
│ ├── coding-standards.yml
│ ├── continuous-integration.yml
│ └── coverage.yml
├── .gitignore
├── .nvmrc
├── .php-cs-fixer.dist.php
├── CONTRIBUTING.md
├── LICENSE
├── Makefile
├── README.md
├── bin/
│ └── console
├── composer.json
├── config/
│ ├── bundles.php
│ ├── packages/
│ │ ├── cache.yaml
│ │ ├── debug.yaml
│ │ ├── doctrine.yaml
│ │ ├── doctrine_migrations.yaml
│ │ ├── framework.yaml
│ │ ├── github_api.yaml
│ │ ├── http_discovery.yaml
│ │ ├── knpu_oauth2_client.yaml
│ │ ├── messenger.yaml
│ │ ├── monolog.yaml
│ │ ├── routing.yaml
│ │ ├── security.yaml
│ │ ├── sentry.yaml
│ │ ├── snc_redis.yaml
│ │ ├── twig.yaml
│ │ ├── validator.yaml
│ │ └── web_profiler.yaml
│ ├── preload.php
│ ├── reference.php
│ ├── routes/
│ │ ├── framework.yaml
│ │ ├── security.yaml
│ │ └── web_profiler.yaml
│ ├── routes.yaml
│ ├── services.yaml
│ └── services_test.yaml
├── data/
│ └── supervisor.conf
├── migrations/
│ ├── .gitignore
│ ├── Version20170222055642.php
│ ├── Version20170329095349.php
│ ├── Version20180827105910.php
│ ├── Version20200511062812.php
│ ├── Version20200613153754.php
│ └── Version20260408120000.php
├── phpstan.dist.neon
├── phpunit.xml.dist
├── public/
│ ├── css/
│ │ ├── banditore.css
│ │ ├── grids-responsive-min.css
│ │ └── pure-min.css
│ ├── fonts/
│ │ ├── .gitkeep
│ │ └── FontAwesome.otf
│ ├── index.php
│ ├── js/
│ │ └── banditore.js
│ └── robots.txt
├── rector.php
├── src/
│ ├── Cache/
│ │ ├── CustomRedisCachePool.php
│ │ ├── HierarchicalCachePoolTrait.php
│ │ └── PredisCachePool.php
│ ├── Command/
│ │ ├── SyncStarredReposCommand.php
│ │ └── SyncVersionsCommand.php
│ ├── Controller/
│ │ └── DefaultController.php
│ ├── DataFixtures/
│ │ └── AppFixtures.php
│ ├── Entity/
│ │ ├── Repo.php
│ │ ├── Star.php
│ │ ├── User.php
│ │ └── Version.php
│ ├── Github/
│ │ ├── ClientDiscovery.php
│ │ └── RateLimitTrait.php
│ ├── Kernel.php
│ ├── Message/
│ │ ├── StarredReposSync.php
│ │ └── VersionsSync.php
│ ├── MessageHandler/
│ │ ├── StarredReposSyncHandler.php
│ │ └── VersionsSyncHandler.php
│ ├── Pagination/
│ │ ├── Exception/
│ │ │ ├── CallbackNotFoundException.php
│ │ │ └── InvalidPageNumberException.php
│ │ ├── Pagination.php
│ │ ├── Paginator.php
│ │ └── PaginatorInterface.php
│ ├── PubSubHubbub/
│ │ └── Publisher.php
│ ├── Repository/
│ │ ├── RepoRepository.php
│ │ ├── StarRepository.php
│ │ ├── UserRepository.php
│ │ └── VersionRepository.php
│ ├── Rss/
│ │ └── Generator.php
│ ├── Security/
│ │ └── GithubAuthenticator.php
│ ├── Twig/
│ │ ├── PaginationExtension.php
│ │ └── RepoVersionExtension.php
│ └── Webfeeds/
│ ├── Webfeeds.php
│ └── WebfeedsWriter.php
├── templates/
│ ├── base.html.twig
│ ├── bundles/
│ │ └── TwigBundle/
│ │ └── Exception/
│ │ └── error.html.twig
│ └── default/
│ ├── _line_version.html.twig
│ ├── _pagination.html.twig
│ ├── dashboard.html.twig
│ ├── index.html.twig
│ └── stats.html.twig
└── tests/
├── Cache/
│ └── CustomRedisCachePoolTest.php
├── Command/
│ ├── SyncStarredReposCommandTest.php
│ └── SyncVersionsCommandTest.php
├── Controller/
│ └── DefaultControllerTest.php
├── Github/
│ └── ClientDiscoveryTest.php
├── MessageHandler/
│ ├── StarredReposSyncHandlerTest.php
│ └── VersionsSyncHandlerTest.php
├── PubSubHubbub/
│ └── PublisherTest.php
├── Repository/
│ ├── UserRepositoryTest.php
│ └── VersionRepositoryTest.php
├── Rss/
│ └── GeneratorTest.php
├── Security/
│ └── GithubAuthenticatorTest.php
├── Twig/
│ └── RepoVersionExtensionTest.php
├── Webfeeds/
│ ├── WebfeedsTest.php
│ └── WebfeedsWriterTest.php
├── bootstrap.php
├── console-application.php
└── object-manager.php
SYMBOL INDEX (380 symbols across 57 files)
FILE: config/reference.php
class App (line 1707) | final class App
method config (line 1714) | public static function config(array $config): array
class Routes (line 1787) | final class Routes
method config (line 1794) | public static function config(array $config): array
FILE: migrations/Version20170222055642.php
class Version20170222055642 (line 12) | final class Version20170222055642 extends AbstractMigration
method getDescription (line 14) | public function getDescription(): string
method up (line 19) | public function up(Schema $schema): void
method down (line 29) | public function down(Schema $schema): void
FILE: migrations/Version20170329095349.php
class Version20170329095349 (line 12) | final class Version20170329095349 extends AbstractMigration
method getDescription (line 14) | public function getDescription(): string
method up (line 19) | public function up(Schema $schema): void
method down (line 26) | public function down(Schema $schema): void
FILE: migrations/Version20180827105910.php
class Version20180827105910 (line 12) | final class Version20180827105910 extends AbstractMigration
method getDescription (line 14) | public function getDescription(): string
method up (line 19) | public function up(Schema $schema): void
method down (line 26) | public function down(Schema $schema): void
FILE: migrations/Version20200511062812.php
class Version20200511062812 (line 12) | final class Version20200511062812 extends AbstractMigration
method getDescription (line 14) | public function getDescription(): string
method up (line 19) | public function up(Schema $schema): void
method down (line 26) | public function down(Schema $schema): void
FILE: migrations/Version20200613153754.php
class Version20200613153754 (line 12) | final class Version20200613153754 extends AbstractMigration
method getDescription (line 14) | public function getDescription(): string
method up (line 19) | public function up(Schema $schema): void
method down (line 27) | public function down(Schema $schema): void
FILE: migrations/Version20260408120000.php
class Version20260408120000 (line 9) | final class Version20260408120000 extends AbstractMigration
method getDescription (line 11) | public function getDescription(): string
method up (line 16) | public function up(Schema $schema): void
method down (line 23) | public function down(Schema $schema): void
FILE: public/js/banditore.js
function toggleHorizontal (line 26) | function toggleHorizontal() {
function toggleMenu (line 35) | function toggleMenu() {
function closeMenu (line 48) | function closeMenu() {
FILE: src/Cache/CustomRedisCachePool.php
class CustomRedisCachePool (line 20) | class CustomRedisCachePool extends PredisCachePool
method storeItemInCache (line 22) | protected function storeItemInCache(PhpCacheItem $item, $ttl): bool
FILE: src/Cache/HierarchicalCachePoolTrait.php
type HierarchicalCachePoolTrait (line 19) | trait HierarchicalCachePoolTrait
method getDirectValue (line 33) | abstract public function getDirectValue($name);
method getHierarchyKey (line 44) | protected function getHierarchyKey($key, &$pathKey = null)
method clearHierarchyKeyCache (line 82) | protected function clearHierarchyKeyCache(): void
method isHierarchyKey (line 94) | private function isHierarchyKey($key)
method explodeKey (line 107) | private function explodeKey($string)
FILE: src/Cache/PredisCachePool.php
class PredisCachePool (line 12) | class PredisCachePool extends AbstractCachePool
method __construct (line 16) | public function __construct(protected Client $cache)
method fetchObjectFromCache (line 20) | protected function fetchObjectFromCache($key): array
method clearAllObjectsFromCache (line 35) | protected function clearAllObjectsFromCache(): bool
method clearOneObjectFromCache (line 40) | protected function clearOneObjectFromCache($key): bool
method storeItemInCache (line 52) | protected function storeItemInCache(PhpCacheItem $item, $ttl): bool
method getDirectValue (line 68) | protected function getDirectValue($key): mixed
method appendListItem (line 73) | protected function appendListItem($name, $value): void
method getList (line 78) | protected function getList($name): array
method removeList (line 83) | protected function removeList($name): bool
method removeListItem (line 88) | protected function removeListItem($name, $key): int
FILE: src/Command/SyncStarredReposCommand.php
class SyncStarredReposCommand (line 23) | #[AsCommand(name: 'banditore:sync:starred-repos', description: 'Sync sta...
method __construct (line 26) | public function __construct(private readonly UserRepository $userRepos...
method __invoke (line 30) | public function __invoke(
method retrieveUsers (line 79) | private function retrieveUsers(?string $id, ?string $username): array
FILE: src/Command/SyncVersionsCommand.php
class SyncVersionsCommand (line 24) | #[AsCommand(name: 'banditore:sync:versions', description: 'Sync new vers...
method __construct (line 27) | public function __construct(private readonly RepoRepository $repoRepos...
method __invoke (line 31) | public function __invoke(
method retrieveRepos (line 80) | private function retrieveRepos(?string $repoId, ?string $repoName): array
FILE: src/Controller/DefaultController.php
class DefaultController (line 27) | class DefaultController extends AbstractController
method __construct (line 29) | public function __construct(private readonly VersionRepository $repoVe...
method indexAction (line 33) | #[Route(path: '/', name: 'homepage')]
method statusAction (line 43) | #[Route(path: '/status', name: 'status')]
method dashboardAction (line 61) | #[Route(path: '/dashboard', name: 'dashboard')]
method updateDashboardRepoFeedAction (line 96) | #[Route(path: '/dashboard/repositories/{repoId}/feed', name: 'dashboar...
method githubCallbackAction (line 132) | #[Route(path: '/callback', name: 'github_callback')]
method connectAction (line 141) | #[Route(path: '/connect', name: 'github_connect')]
method rssAction (line 153) | #[Route(path: '/{uuid}.atom', name: 'rss_user')]
method statsAction (line 172) | #[Route(path: '/stats', name: 'stats')]
FILE: src/DataFixtures/AppFixtures.php
class AppFixtures (line 12) | class AppFixtures extends Fixture
method load (line 14) | public function load(ObjectManager $manager): void
method loadUsers (line 22) | private function loadUsers(ObjectManager $manager): void
method loadRepos (line 37) | private function loadRepos(ObjectManager $manager): void
method loadStars (line 88) | private function loadStars(ObjectManager $manager): void
method loadVersions (line 108) | private function loadVersions(ObjectManager $manager): void
FILE: src/Entity/Repo.php
class Repo (line 12) | #[ORM\Entity(repositoryClass: RepoRepository::class)]
method __construct (line 91) | public function __construct()
method setId (line 104) | public function setId($id)
method getId (line 116) | public function getId()
method setName (line 128) | public function setName($name)
method getName (line 140) | public function getName()
method setFullName (line 152) | public function setFullName($fullName)
method getFullName (line 164) | public function getFullName()
method setDescription (line 176) | public function setDescription($description)
method getDescription (line 188) | public function getDescription()
method setHomepage (line 200) | public function setHomepage($homepage)
method getHomepage (line 212) | public function getHomepage()
method setLanguage (line 224) | public function setLanguage($language)
method getLanguage (line 236) | public function getLanguage()
method setOwnerAvatar (line 248) | public function setOwnerAvatar($ownerAvatar)
method getOwnerAvatar (line 260) | public function getOwnerAvatar()
method setCreatedAt (line 272) | public function setCreatedAt($createdAt)
method getCreatedAt (line 284) | public function getCreatedAt()
method setUpdatedAt (line 296) | public function setUpdatedAt($updatedAt)
method getUpdatedAt (line 308) | public function getUpdatedAt()
method timestamps (line 313) | #[ORM\PrePersist]
method hydrateFromGithub (line 323) | public function hydrateFromGithub(array $data): void
method setRemovedAt (line 341) | public function setRemovedAt($removedAt)
method getRemovedAt (line 353) | public function getRemovedAt()
FILE: src/Entity/Star.php
class Star (line 11) | #[ORM\Entity(repositoryClass: StarRepository::class)]
method __construct (line 33) | public function __construct(#[ORM\ManyToOne(targetEntity: User::class,...
method getId (line 47) | public function getId()
method setCreatedAt (line 59) | public function setCreatedAt($createdAt)
method getCreatedAt (line 71) | public function getCreatedAt()
method getUser (line 76) | public function getUser(): User
method getRepo (line 81) | public function getRepo(): Repo
method isIgnoredInFeed (line 86) | public function isIgnoredInFeed(): bool
method setIgnoredInFeed (line 91) | public function setIgnoredInFeed(bool $ignoredInFeed): self
FILE: src/Entity/User.php
class User (line 16) | #[ORM\Entity(repositoryClass: UserRepository::class)]
method __construct (line 84) | public function __construct()
method setId (line 97) | public function setId($id)
method getId (line 109) | public function getId()
method setUsername (line 121) | public function setUsername($username)
method getUsername (line 133) | public function getUsername()
method getUuid (line 143) | public function getUuid()
method setAvatar (line 155) | public function setAvatar($avatar)
method getAvatar (line 167) | public function getAvatar()
method setName (line 179) | public function setName($name)
method getName (line 191) | public function getName()
method setCreatedAt (line 203) | public function setCreatedAt($createdAt)
method getCreatedAt (line 215) | public function getCreatedAt()
method setUpdatedAt (line 227) | public function setUpdatedAt($updatedAt)
method getUpdatedAt (line 239) | public function getUpdatedAt()
method timestamps (line 244) | #[ORM\PrePersist]
method hydrateFromGithub (line 257) | public function hydrateFromGithub(GithubResourceOwner $data): void
method getRoles (line 267) | public function getRoles(): array
method getPassword (line 272) | public function getPassword(): ?string
method getSalt (line 277) | public function getSalt(): ?string
method eraseCredentials (line 282) | public function eraseCredentials(): void
method setAccessToken (line 293) | public function setAccessToken($accessToken)
method getAccessToken (line 305) | public function getAccessToken()
method setRemovedAt (line 317) | public function setRemovedAt($removedAt)
method getRemovedAt (line 329) | public function getRemovedAt()
method isEqualTo (line 340) | public function isEqualTo(UserInterface $user): bool
method getUserIdentifier (line 359) | public function getUserIdentifier(): string
FILE: src/Entity/Version.php
class Version (line 12) | #[ORM\Entity(repositoryClass: VersionRepository::class)]
method __construct (line 57) | public function __construct(
method getId (line 69) | public function getId()
method setTagName (line 81) | public function setTagName($tagName)
method getTagName (line 93) | public function getTagName()
method setName (line 105) | public function setName($name)
method getName (line 122) | public function getName()
method setPrerelease (line 134) | public function setPrerelease($prerelease)
method getPrerelease (line 146) | public function getPrerelease()
method setCreatedAt (line 158) | public function setCreatedAt($createdAt)
method getCreatedAt (line 170) | public function getCreatedAt()
method setBody (line 182) | public function setBody($body)
method getBody (line 194) | public function getBody()
method hydrateFromGithub (line 199) | public function hydrateFromGithub(array $data): void
FILE: src/Github/ClientDiscovery.php
class ClientDiscovery (line 18) | class ClientDiscovery
method __construct (line 26) | public function __construct(private UserRepository $userRepository, pr...
method setGithubClient (line 35) | public function setGithubClient(GithubClient $client): void
method find (line 48) | public function find()
FILE: src/Github/RateLimitTrait.php
type RateLimitTrait (line 10) | trait RateLimitTrait
method getRateLimits (line 18) | private function getRateLimits(Client $client, LoggerInterface $logger)
FILE: src/Kernel.php
class Kernel (line 8) | class Kernel extends BaseKernel
FILE: src/Message/StarredReposSync.php
class StarredReposSync (line 5) | class StarredReposSync
method __construct (line 7) | public function __construct(private readonly int $userId)
method getUserId (line 11) | public function getUserId(): int
FILE: src/Message/VersionsSync.php
class VersionsSync (line 5) | class VersionsSync
method __construct (line 7) | public function __construct(private readonly int $repoId)
method getRepoId (line 11) | public function getRepoId(): int
FILE: src/MessageHandler/StarredReposSyncHandler.php
class StarredReposSyncHandler (line 28) | #[AsMessageHandler]
method __construct (line 38) | public function __construct(private ManagerRegistry $doctrine, private...
method __invoke (line 42) | public function __invoke(StarredReposSync $message): bool
method doSyncRepo (line 93) | private function doSyncRepo(User $user): ?int
method doCleanOldStar (line 181) | private function doCleanOldStar(User $user, array $newStars): void
FILE: src/MessageHandler/VersionsSyncHandler.php
class VersionsSyncHandler (line 23) | #[AsMessageHandler]
method __construct (line 31) | public function __construct(private ManagerRegistry $doctrine, private...
method __invoke (line 35) | public function __invoke(VersionsSync $message): bool
method doSyncVersions (line 85) | private function doSyncVersions(Repo $repo): ?int
method removePgpSignature (line 246) | private function removePgpSignature(string $message): string
FILE: src/Pagination/Exception/CallbackNotFoundException.php
class CallbackNotFoundException (line 10) | class CallbackNotFoundException extends \RuntimeException
FILE: src/Pagination/Exception/InvalidPageNumberException.php
class InvalidPageNumberException (line 10) | class InvalidPageNumberException extends \InvalidArgumentException
FILE: src/Pagination/Pagination.php
class Pagination (line 12) | class Pagination implements \IteratorAggregate, \Countable
method getItems (line 30) | public function getItems(): array
method setItems (line 40) | public function setItems(array $items)
method getCurrentPageNumber (line 52) | public function getCurrentPageNumber()
method setCurrentPageNumber (line 64) | public function setCurrentPageNumber($currentPageNumber)
method getFirstPageNumber (line 76) | public function getFirstPageNumber()
method setFirstPageNumber (line 88) | public function setFirstPageNumber($firstPageNumber)
method getFirstPageNumberInRange (line 100) | public function getFirstPageNumberInRange()
method setFirstPageNumberInRange (line 112) | public function setFirstPageNumberInRange($firstPageNumberInRange)
method getItemsPerPage (line 124) | public function getItemsPerPage()
method setItemsPerPage (line 136) | public function setItemsPerPage($itemsPerPage)
method getLastPageNumber (line 148) | public function getLastPageNumber()
method setLastPageNumber (line 160) | public function setLastPageNumber($lastPageNumber)
method getLastPageNumberInRange (line 172) | public function getLastPageNumberInRange()
method setLastPageNumberInRange (line 184) | public function setLastPageNumberInRange($lastPageNumberInRange)
method getNextPageNumber (line 196) | public function getNextPageNumber()
method setNextPageNumber (line 208) | public function setNextPageNumber($nextPageNumber)
method getPages (line 220) | public function getPages()
method setPages (line 230) | public function setPages(array $pages)
method getPreviousPageNumber (line 242) | public function getPreviousPageNumber()
method setPreviousPageNumber (line 254) | public function setPreviousPageNumber($previousPageNumber)
method getTotalNumberOfItems (line 266) | public function getTotalNumberOfItems()
method setTotalNumberOfItems (line 278) | public function setTotalNumberOfItems($totalNumberOfItems)
method getTotalNumberOfPages (line 290) | public function getTotalNumberOfPages()
method setTotalNumberOfPages (line 302) | public function setTotalNumberOfPages($totalNumberOfPages)
method getIterator (line 309) | public function getIterator(): \Traversable
method count (line 314) | public function count(): int
FILE: src/Pagination/Paginator.php
class Paginator (line 13) | class Paginator implements PaginatorInterface
method __construct (line 61) | public function __construct(?array $config = null)
method paginate (line 77) | public function paginate($currentPageNumber = 1)
method getSliceCallback (line 173) | public function getSliceCallback()
method setSliceCallback (line 178) | public function setSliceCallback(\Closure $sliceCallback)
method getItemTotalCallback (line 185) | public function getItemTotalCallback()
method getBeforeQueryCallback (line 190) | public function getBeforeQueryCallback()
method setBeforeQueryCallback (line 195) | public function setBeforeQueryCallback(\Closure $beforeQueryCallback)
method getAfterQueryCallback (line 202) | public function getAfterQueryCallback()
method setAfterQueryCallback (line 207) | public function setAfterQueryCallback(\Closure $afterQueryCallback)
method setItemTotalCallback (line 214) | public function setItemTotalCallback(\Closure $itemTotalCallback)
method getItemsPerPage (line 221) | public function getItemsPerPage()
method setItemsPerPage (line 226) | public function setItemsPerPage($itemsPerPage)
method getPagesInRange (line 237) | public function getPagesInRange()
method setPagesInRange (line 242) | public function setPagesInRange($pagesInRange)
FILE: src/Pagination/PaginatorInterface.php
type PaginatorInterface (line 10) | interface PaginatorInterface
method paginate (line 22) | public function paginate($currentPageNumber = 1);
method getSliceCallback (line 29) | public function getSliceCallback();
method setSliceCallback (line 36) | public function setSliceCallback(\Closure $sliceCallback);
method getItemTotalCallback (line 43) | public function getItemTotalCallback();
method setItemTotalCallback (line 50) | public function setItemTotalCallback(\Closure $itemTotalCallback);
method getBeforeQueryCallback (line 55) | public function getBeforeQueryCallback();
method setBeforeQueryCallback (line 60) | public function setBeforeQueryCallback(\Closure $beforeQueryCallback);
method getAfterQueryCallback (line 65) | public function getAfterQueryCallback();
method setAfterQueryCallback (line 70) | public function setAfterQueryCallback(\Closure $afterQueryCallback);
method getItemsPerPage (line 77) | public function getItemsPerPage();
method setItemsPerPage (line 88) | public function setItemsPerPage($itemsPerPage);
method getPagesInRange (line 95) | public function getPagesInRange();
method setPagesInRange (line 106) | public function setPagesInRange($pagesInRange);
FILE: src/PubSubHubbub/Publisher.php
class Publisher (line 13) | class Publisher
method __construct (line 24) | public function __construct(protected $hub, protected RouterInterface ...
method pingHub (line 42) | public function pingHub(array $repoIds)
method retrieveFeedUrls (line 78) | private function retrieveFeedUrls(array $repoIds)
FILE: src/Repository/RepoRepository.php
class RepoRepository (line 14) | class RepoRepository extends ServiceEntityRepository
method __construct (line 16) | public function __construct(ManagerRegistry $registry)
method findAllForRelease (line 26) | public function findAllForRelease()
method countTotal (line 47) | public function countTotal()
method mostVersionsPerRepo (line 61) | public function mostVersionsPerRepo()
FILE: src/Repository/StarRepository.php
class StarRepository (line 12) | class StarRepository extends ServiceEntityRepository
method __construct (line 14) | public function __construct(ManagerRegistry $registry)
method findAllByUser (line 26) | public function findAllByUser($userId)
method removeFromUser (line 46) | public function removeFromUser(array $repoIds, int $userId): void
method countTotal (line 61) | public function countTotal()
method findOneByUserAndRepo (line 69) | public function findOneByUserAndRepo(int $userId, int $repoId): ?Star
FILE: src/Repository/UserRepository.php
class UserRepository (line 14) | class UserRepository extends ServiceEntityRepository
method __construct (line 16) | public function __construct(ManagerRegistry $registry)
method findByRepoIds (line 26) | public function findByRepoIds(array $repoIds)
method findAllToSync (line 43) | public function findAllToSync()
method findAllTokens (line 65) | public function findAllTokens()
method countTotal (line 81) | public function countTotal()
FILE: src/Repository/VersionRepository.php
class VersionRepository (line 13) | class VersionRepository extends ServiceEntityRepository
method __construct (line 15) | public function __construct(ManagerRegistry $registry)
method findExistingOne (line 31) | public function findExistingOne($tagName, $repoId)
method findForUser (line 53) | public function findForUser($userId, $offset = 0, $length = 20)
method countForUser (line 75) | public function countForUser($userId)
method findForFeedUser (line 89) | public function findForFeedUser(int $userId, int $offset = 0, int $len...
method findLastVersionForEachRepo (line 111) | public function findLastVersionForEachRepo($length = 10)
method countTotal (line 133) | public function countTotal()
method findLatest (line 146) | public function findLatest()
FILE: src/Rss/Generator.php
class Generator (line 15) | class Generator
method generate (line 29) | public function generate(User $user, array $releases, $feedUrl)
FILE: src/Security/GithubAuthenticator.php
class GithubAuthenticator (line 25) | class GithubAuthenticator extends OAuth2Authenticator
method __construct (line 27) | public function __construct(private readonly ClientRegistry $clientReg...
method supports (line 31) | public function supports(Request $request): ?bool
method authenticate (line 37) | public function authenticate(Request $request): Passport
method onAuthenticationSuccess (line 66) | public function onAuthenticationSuccess(Request $request, TokenInterfa...
method onAuthenticationFailure (line 91) | public function onAuthenticationFailure(Request $request, Authenticati...
FILE: src/Twig/PaginationExtension.php
class PaginationExtension (line 9) | class PaginationExtension
method render (line 11) | #[AsTwigFunction(name: 'pagination_render', isSafe: ['html'], needsEnv...
FILE: src/Twig/RepoVersionExtension.php
class RepoVersionExtension (line 10) | class RepoVersionExtension
method linkToVersion (line 12) | #[AsTwigFilter('link_to_version')]
FILE: src/Webfeeds/Webfeeds.php
class Webfeeds (line 12) | class Webfeeds
method setLogo (line 31) | public function setLogo(?string $logo): self
method getLogo (line 38) | public function getLogo(): ?string
method setIcon (line 43) | public function setIcon(?string $icon): self
method getIcon (line 50) | public function getIcon(): ?string
method setAccentColor (line 55) | public function setAccentColor(?string $accentColor): self
method getAccentColor (line 62) | public function getAccentColor(): ?string
FILE: src/Webfeeds/WebfeedsWriter.php
class WebfeedsWriter (line 15) | class WebfeedsWriter implements WriterRegistererInterface
method getRegisteredWriters (line 17) | public function getRegisteredWriters(): array
method getRegisteredNamespaces (line 24) | public function getRegisteredNamespaces(): array
method write (line 31) | public function write(RssWriter $rssWriter, Webfeeds $extension): void
FILE: tests/Cache/CustomRedisCachePoolTest.php
class CustomRedisCachePoolTest (line 12) | class CustomRedisCachePoolTest extends WebTestCase
method testResponseWithEmptyBody (line 14) | public function testResponseWithEmptyBody(): void
method testResponseWith404 (line 41) | public function testResponseWith404(): void
method testResponseWithRelease (line 62) | public function testResponseWithRelease(): void
method testResponseWithRefTags (line 93) | public function testResponseWithRefTags(): void
method testResponseWithTag (line 138) | public function testResponseWithTag(): void
method testResponseWithStarredRepos (line 173) | public function testResponseWithStarredRepos(): void
FILE: tests/Command/SyncStarredReposCommandTest.php
class SyncStarredReposCommandTest (line 16) | class SyncStarredReposCommandTest extends KernelTestCase
method testCommandSyncAllUsersWithoutQueue (line 18) | public function testCommandSyncAllUsersWithoutQueue(): void
method testCommandSyncAllUsersWithQueue (line 52) | public function testCommandSyncAllUsersWithQueue(): void
method testCommandSyncAllUsersWithQueueFull (line 87) | public function testCommandSyncAllUsersWithQueueFull(): void
method testCommandSyncOneUserById (line 118) | public function testCommandSyncOneUserById(): void
method testCommandSyncOneUserByUsername (line 156) | public function testCommandSyncOneUserByUsername(): void
method testCommandSyncOneUserNotFound (line 191) | public function testCommandSyncOneUserNotFound(): void
method getTransportMessageCount (line 222) | private function getTransportMessageCount(int $totalMessage = 0): Amqp...
FILE: tests/Command/SyncVersionsCommandTest.php
class SyncVersionsCommandTest (line 16) | class SyncVersionsCommandTest extends KernelTestCase
method testCommandSyncAllUsersWithoutQueue (line 18) | public function testCommandSyncAllUsersWithoutQueue(): void
method testCommandSyncAllUsersWithQueue (line 49) | public function testCommandSyncAllUsersWithQueue(): void
method testCommandSyncAllUsersWithQueueFull (line 81) | public function testCommandSyncAllUsersWithQueueFull(): void
method testCommandSyncOneUserById (line 112) | public function testCommandSyncOneUserById(): void
method testCommandSyncOneUserByUsername (line 150) | public function testCommandSyncOneUserByUsername(): void
method testCommandSyncOneUserNotFound (line 187) | public function testCommandSyncOneUserNotFound(): void
method getTransportMessageCount (line 218) | private function getTransportMessageCount(int $totalMessage = 0): Amqp...
FILE: tests/Controller/DefaultControllerTest.php
class DefaultControllerTest (line 14) | class DefaultControllerTest extends WebTestCase
method setUp (line 19) | protected function setUp(): void
method testIndexNotLoggedIn (line 25) | public function testIndexNotLoggedIn(): void
method testIndexLoggedIn (line 33) | public function testIndexLoggedIn(): void
method testConnect (line 44) | public function testConnect(): void
method testConnectWithLoggedInUser (line 54) | public function testConnectWithLoggedInUser(): void
method testDashboardNotLoggedIn (line 65) | public function testDashboardNotLoggedIn(): void
method testDashboard (line 72) | public function testDashboard(): void
method testDashboardRepoFeedToggle (line 95) | public function testDashboardRepoFeedToggle(): void
method testDashboardPageTooHigh (line 116) | public function testDashboardPageTooHigh(): void
method testDashboardBadPage (line 127) | public function testDashboardBadPage(): void
method testRss (line 138) | public function testRss(): void
method testStats (line 161) | public function testStats(): void
method testStatus (line 168) | public function testStatus(): void
FILE: tests/Github/ClientDiscoveryTest.php
class ClientDiscoveryTest (line 19) | class ClientDiscoveryTest extends WebTestCase
method testUseApplicationDefaultClient (line 21) | public function testUseApplicationDefaultClient(): void
method testUseUserToken (line 63) | public function testUseUserToken(): void
method testNoTokenAvailable (line 124) | public function testNoTokenAvailable(): void
method testOneCallFail (line 179) | public function testOneCallFail(): void
method testFunctionnal (line 237) | public function testFunctionnal(): void
FILE: tests/MessageHandler/StarredReposSyncHandlerTest.php
class StarredReposSyncHandlerTest (line 27) | class StarredReposSyncHandlerTest extends WebTestCase
method testProcessNoUser (line 29) | public function testProcessNoUser(): void
method testProcessSuccessfulMessage (line 80) | public function testProcessSuccessfulMessage(): void
method testUserRemovedFromGitHub (line 195) | public function testUserRemovedFromGitHub(): void
method testProcessUnexpectedError (line 281) | public function testProcessUnexpectedError(): void
method testProcessSuccessfulMessageNoStarToRemove (line 381) | public function testProcessSuccessfulMessageNoStarToRemove(): void
method testProcessWithBadClient (line 494) | public function testProcessWithBadClient(): void
method testProcessWithRateLimitReached (line 550) | public function testProcessWithRateLimitReached(): void
method testFunctionalConsumer (line 633) | public function testFunctionalConsumer(): void
method getOKResponse (line 703) | private function getOKResponse(array $body): Response
method restoreFunctionalState (line 712) | private function restoreFunctionalState(): void
method getMockClient (line 742) | private function getMockClient(MockHandler $responses): GithubClient
FILE: tests/MessageHandler/VersionsSyncHandlerTest.php
class VersionsSyncHandlerTest (line 28) | class VersionsSyncHandlerTest extends WebTestCase
method testProcessNoRepo (line 30) | public function testProcessNoRepo(): void
method getWorkingResponses (line 72) | public function getWorkingResponses(): MockHandler
method testProcessSuccessfulMessage (line 201) | public function testProcessSuccessfulMessage(): void
method testProcessRepoTagFailed (line 299) | public function testProcessRepoTagFailed(): void
method testProcessRepoNotFound (line 383) | public function testProcessRepoNotFound(): void
method testProcessCallsRemaingLow (line 469) | public function testProcessCallsRemaingLow(): void
method testProcessMarkdownFailed (line 547) | public function testProcessMarkdownFailed(): void
method testProcessNoTagFound (line 675) | public function testProcessNoTagFound(): void
method testProcessUnexpectedError (line 759) | public function testProcessUnexpectedError(): void
method testProcessGitRefTagFailed (line 860) | public function testProcessGitRefTagFailed(): void
method testProcessWithBadClient (line 951) | public function testProcessWithBadClient(): void
method testFunctionalConsumer (line 998) | #[Group('only')]
method testFunctionalConsumerWithTagCaseInsensitive (line 1046) | public function testFunctionalConsumerWithTagCaseInsensitive(): void
method testProcessSuccessfulMessageWithBlobTag (line 1136) | public function testProcessSuccessfulMessageWithBlobTag(): void
method testBadTagObjectType (line 1271) | public function testBadTagObjectType(): void
method getOKResponse (line 1391) | private function getOKResponse(array $body): Response
method restoreFunctionalState (line 1400) | private function restoreFunctionalState(): void
FILE: tests/PubSubHubbub/PublisherTest.php
class PublisherTest (line 18) | class PublisherTest extends TestCase
method setUp (line 23) | protected function setUp(): void
method testNoHubDefined (line 33) | public function testNoHubDefined(): void
method testBadResponse (line 49) | public function testBadResponse(): void
method testGoodResponse (line 73) | public function testGoodResponse(): void
method testUrlGeneration (line 96) | public function testUrlGeneration(): void
method getServiceContainer (line 121) | private function getServiceContainer(RouteCollection $routes): Container
FILE: tests/Repository/UserRepositoryTest.php
class UserRepositoryTest (line 9) | class UserRepositoryTest extends WebTestCase
method setUp (line 11) | protected function setUp(): void
method testFindByRepoIdsExcludesIgnoredStars (line 17) | public function testFindByRepoIdsExcludesIgnoredStars(): void
FILE: tests/Repository/VersionRepositoryTest.php
class VersionRepositoryTest (line 14) | class VersionRepositoryTest extends WebTestCase
method setUp (line 16) | protected function setUp(): void
method testFindForFeedUserExcludesIgnoredStars (line 58) | public function testFindForFeedUserExcludesIgnoredStars(): void
FILE: tests/Rss/GeneratorTest.php
class GeneratorTest (line 9) | class GeneratorTest extends TestCase
method test (line 11) | public function test(): void
FILE: tests/Security/GithubAuthenticatorTest.php
class GithubAuthenticatorTest (line 19) | class GithubAuthenticatorTest extends WebTestCase
method testCallbackWithExistingUser (line 21) | public function testCallbackWithExistingUser(): void
method testCallbackWithNewUser (line 87) | public function testCallbackWithNewUser(): void
FILE: tests/Twig/RepoVersionExtensionTest.php
class RepoVersionExtensionTest (line 8) | class RepoVersionExtensionTest extends TestCase
method test (line 10) | public function test(): void
method testEncodedTagName (line 21) | public function testEncodedTagName(): void
FILE: tests/Webfeeds/WebfeedsTest.php
class WebfeedsTest (line 8) | class WebfeedsTest extends TestCase
method test (line 10) | public function test(): void
FILE: tests/Webfeeds/WebfeedsWriterTest.php
class WebfeedsWriterTest (line 10) | class WebfeedsWriterTest extends TestCase
method test (line 12) | public function test(): void
Condensed preview — 120 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (503K chars).
[
{
"path": ".editorconfig",
"chars": 322,
"preview": "# editorconfig.org\n\nroot = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\nindent_size = 4\nindent_style = space\ninsert_final_"
},
{
"path": ".github/FUNDING.yml",
"chars": 14,
"preview": "github: j0k3r\n"
},
{
"path": ".github/dependabot.yml",
"chars": 444,
"preview": "version: 2\nupdates:\n- package-ecosystem: composer\n directory: \"/\"\n schedule:\n interval: weekly\n open-pull-requests"
},
{
"path": ".github/release.yml",
"chars": 87,
"preview": "changelog:\n exclude:\n labels:\n - dependencies\n authors:\n - dependabot\n"
},
{
"path": ".github/workflows/coding-standards.yml",
"chars": 1049,
"preview": "name: CS\n\non:\n pull_request:\n branches:\n - master\n push:\n branches:\n - master\n\njobs:\n coding-standard"
},
{
"path": ".github/workflows/continuous-integration.yml",
"chars": 1648,
"preview": "name: CI\n\non:\n pull_request:\n branches:\n - \"master\"\n push:\n branches:\n - \"master\"\n\nenv:\n fail-fast: t"
},
{
"path": ".github/workflows/coverage.yml",
"chars": 1789,
"preview": "name: Coverage\n\non:\n pull_request:\n branches:\n - \"master\"\n push:\n branches:\n - \"master\"\n\nenv:\n APP_EN"
},
{
"path": ".gitignore",
"chars": 760,
"preview": "/build/\n/coverage/\n/var/*\n!/var/cache\n/var/cache/*\n!var/cache/.gitkeep\n!/var/log\n/var/log/*\n!var/log/.gitkeep\n!/var/sess"
},
{
"path": ".nvmrc",
"chars": 3,
"preview": "22\n"
},
{
"path": ".php-cs-fixer.dist.php",
"chars": 1083,
"preview": "<?php\n\nuse PhpCsFixer\\Finder;\nuse PhpCsFixer\\Config;\n\n$finder = (new Finder())\n ->in(__DIR__)\n ->exclude(['vendor'"
},
{
"path": "CONTRIBUTING.md",
"chars": 944,
"preview": "# Contributing\n\nContributions are welcome, of course.\n\n## Setting up an Environment\n\nYou locally need:\n\n - PHP >= 8.2 (w"
},
{
"path": "LICENSE",
"chars": 1079,
"preview": "MIT License\n\nCopyright (c) 2017-present Jérémy Benoist\n\nPermission is hereby granted, free of charge, to any person obta"
},
{
"path": "Makefile",
"chars": 834,
"preview": ".PHONY: build local prepare test\n\nbuild: prepare test\n\nlocal:\n\tphp bin/console doctrine:database:create --if-not-exists "
},
{
"path": "README.md",
"chars": 8617,
"preview": "<img src=\"https://i.imgur.com/kAvg4w9.png\" align=\"right\" />\n\n# Banditore\n\n%'\n # driver: pdo_mysql\n # host: \"%database_ho"
},
{
"path": "config/packages/doctrine_migrations.yaml",
"chars": 268,
"preview": "doctrine_migrations:\n migrations_paths:\n # namespace is arbitrary but should be different from App\\Migrations\n"
},
{
"path": "config/packages/framework.yaml",
"chars": 782,
"preview": "# see https://symfony.com/doc/current/reference/configuration/framework.html\nframework:\n secret: '%env(APP_SECRET)%'\n"
},
{
"path": "config/packages/github_api.yaml",
"chars": 448,
"preview": "services:\n Github\\Client:\n arguments:\n - '@Github\\HttpClient\\Builder'\n # Uncomment to enable"
},
{
"path": "config/packages/http_discovery.yaml",
"chars": 563,
"preview": "services:\n Psr\\Http\\Message\\RequestFactoryInterface: '@http_discovery.psr17_factory'\n Psr\\Http\\Message\\ResponseFac"
},
{
"path": "config/packages/knpu_oauth2_client.yaml",
"chars": 435,
"preview": "knpu_oauth2_client:\n clients:\n # will create service: \"knpu.oauth2.client.github\"\n # an instance of: Kn"
},
{
"path": "config/packages/messenger.yaml",
"chars": 1561,
"preview": "framework:\n messenger:\n # Uncomment this (and the failed transport below) to send failed messages to this tran"
},
{
"path": "config/packages/monolog.yaml",
"chars": 1732,
"preview": "monolog:\n channels:\n - deprecation # Deprecations are logged in the dedicated \"deprecation\" channel when it ex"
},
{
"path": "config/packages/routing.yaml",
"chars": 318,
"preview": "framework:\n router:\n # Configure how to generate URLs in non-HTTP contexts, such as CLI commands.\n # Se"
},
{
"path": "config/packages/security.yaml",
"chars": 1736,
"preview": "security:\n # https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords\n password_hasher"
},
{
"path": "config/packages/sentry.yaml",
"chars": 1527,
"preview": "when@prod:\n sentry:\n dsn: '%env(SENTRY_DSN)%'\n options:\n integrations:\n - 'Se"
},
{
"path": "config/packages/snc_redis.yaml",
"chars": 493,
"preview": "# Define your clients here. The example below connects to database 0 of the default Redis server.\n#\n# See https://github"
},
{
"path": "config/packages/twig.yaml",
"chars": 91,
"preview": "twig:\n file_name_pattern: '*.twig'\n\nwhen@test:\n twig:\n strict_variables: true\n"
},
{
"path": "config/packages/validator.yaml",
"chars": 383,
"preview": "framework:\n validation:\n enable_attributes: true\n email_validation_mode: html5\n\n # Enables valid"
},
{
"path": "config/packages/web_profiler.yaml",
"chars": 344,
"preview": "when@dev:\n web_profiler:\n toolbar: true\n\n framework:\n profiler:\n collect_serializer_data:"
},
{
"path": "config/preload.php",
"chars": 188,
"preview": "<?php\n\nif (file_exists(dirname(__DIR__) . '/var/cache/prod/App_KernelProdContainer.preload.php')) {\n require dirname("
},
{
"path": "config/reference.php",
"chars": 110981,
"preview": "<?php\n\n// This file is auto-generated and is for apps only. Bundles SHOULD NOT rely on its content.\n\nnamespace Symfony\\C"
},
{
"path": "config/routes/framework.yaml",
"chars": 120,
"preview": "when@dev:\n _errors:\n resource: '@FrameworkBundle/Resources/config/routing/errors.php'\n prefix: /_error\n"
},
{
"path": "config/routes/security.yaml",
"chars": 79,
"preview": "_security_logout:\n resource: security.route_loader.logout\n type: service\n"
},
{
"path": "config/routes/web_profiler.yaml",
"chars": 258,
"preview": "when@dev:\n web_profiler_wdt:\n resource: '@WebProfilerBundle/Resources/config/routing/wdt.php'\n prefix: "
},
{
"path": "config/routes.yaml",
"chars": 514,
"preview": "# yaml-language-server: $schema=../vendor/symfony/routing/Loader/schema/routing.schema.json\n\n# This file is the entry po"
},
{
"path": "config/services.yaml",
"chars": 4051,
"preview": "# yaml-language-server: $schema=../vendor/symfony/dependency-injection/Loader/schema/services.schema.json\n\n# This file i"
},
{
"path": "config/services_test.yaml",
"chars": 257,
"preview": "services:\n # see https://github.com/symfony/symfony/issues/24543\n banditore.client.github.test:\n alias: ban"
},
{
"path": "data/supervisor.conf",
"chars": 2292,
"preview": "[group:sync_repo]\nprograms=sync_repo_1,sync_repo_2\n\n[program:sync_repo_1]\ndirectory=/path/to/banditore\ncommand=/usr/bin/"
},
{
"path": "migrations/.gitignore",
"chars": 0,
"preview": ""
},
{
"path": "migrations/Version20170222055642.php",
"chars": 1216,
"preview": "<?php\n\nnamespace DoctrineMigrations;\n\nuse Doctrine\\DBAL\\Platforms\\AbstractMySQLPlatform;\nuse Doctrine\\DBAL\\Schema\\Schema"
},
{
"path": "migrations/Version20170329095349.php",
"chars": 983,
"preview": "<?php\n\nnamespace DoctrineMigrations;\n\nuse Doctrine\\DBAL\\Platforms\\AbstractMySQLPlatform;\nuse Doctrine\\DBAL\\Schema\\Schema"
},
{
"path": "migrations/Version20180827105910.php",
"chars": 1021,
"preview": "<?php\n\nnamespace DoctrineMigrations;\n\nuse Doctrine\\DBAL\\Platforms\\AbstractMySQLPlatform;\nuse Doctrine\\DBAL\\Schema\\Schema"
},
{
"path": "migrations/Version20200511062812.php",
"chars": 1033,
"preview": "<?php\n\nnamespace DoctrineMigrations;\n\nuse Doctrine\\DBAL\\Platforms\\AbstractMySQLPlatform;\nuse Doctrine\\DBAL\\Schema\\Schema"
},
{
"path": "migrations/Version20200613153754.php",
"chars": 1223,
"preview": "<?php\n\nnamespace DoctrineMigrations;\n\nuse Doctrine\\DBAL\\Platforms\\AbstractMySQLPlatform;\nuse Doctrine\\DBAL\\Schema\\Schema"
},
{
"path": "migrations/Version20260408120000.php",
"chars": 939,
"preview": "<?php\n\nnamespace DoctrineMigrations;\n\nuse Doctrine\\DBAL\\Platforms\\AbstractMySQLPlatform;\nuse Doctrine\\DBAL\\Schema\\Schema"
},
{
"path": "phpstan.dist.neon",
"chars": 1525,
"preview": "parameters:\n level: max\n paths:\n - src\n - tests\n\n symfony:\n containerXmlPath: %rootDir%/.."
},
{
"path": "phpunit.xml.dist",
"chars": 966,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- https://phpunit.readthedocs.io/en/latest/configuration.html -->\n<phpunit xml"
},
{
"path": "public/css/banditore.css",
"chars": 11795,
"preview": "* {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\n\n/*\n * -- BASE ST"
},
{
"path": "public/css/grids-responsive-min.css",
"chars": 14282,
"preview": "/*!\nPure v3.0.0\nCopyright 2013 Yahoo!\nLicensed under the BSD License.\nhttps://github.com/pure-css/pure/blob/master/LICEN"
},
{
"path": "public/css/pure-min.css",
"chars": 15721,
"preview": "/*!\nPure v3.0.0\nCopyright 2013 Yahoo!\nLicensed under the BSD License.\nhttps://github.com/pure-css/pure/blob/master/LICEN"
},
{
"path": "public/fonts/.gitkeep",
"chars": 0,
"preview": ""
},
{
"path": "public/index.php",
"chars": 189,
"preview": "<?php\n\nuse App\\Kernel;\n\nrequire_once dirname(__DIR__) . '/vendor/autoload_runtime.php';\n\nreturn static fn (array $contex"
},
{
"path": "public/js/banditore.js",
"chars": 1972,
"preview": "(function (window, document) {\n // close alert messages\n var alerts = document.querySelectorAll('span.close')\n "
},
{
"path": "public/robots.txt",
"chars": 116,
"preview": "# www.robotstxt.org/\n# www.google.com/support/webmasters/bin/answer.py?hl=en&answer=156449\n\nUser-agent: *\nDisallow:\n"
},
{
"path": "rector.php",
"chars": 1483,
"preview": "<?php\n\nuse Rector\\Config\\RectorConfig;\nuse Rector\\Doctrine\\Set\\DoctrineSetList;\nuse Rector\\Php80\\Rector\\Class_\\ClassProp"
},
{
"path": "src/Cache/CustomRedisCachePool.php",
"chars": 3082,
"preview": "<?php\n\nnamespace App\\Cache;\n\nuse Cache\\Adapter\\Common\\PhpCacheItem;\n\n/**\n * Store lightweight response from GitHub to av"
},
{
"path": "src/Cache/HierarchicalCachePoolTrait.php",
"chars": 3619,
"preview": "<?php\n\n/*\n * This file is part of php-cache organization.\n *\n * (c) 2015 Aaron Scherer <aequasi@gmail.com>, Tobias Nyhol"
},
{
"path": "src/Cache/PredisCachePool.php",
"chars": 2271,
"preview": "<?php\n\nnamespace App\\Cache;\n\nuse Cache\\Adapter\\Common\\AbstractCachePool;\nuse Cache\\Adapter\\Common\\PhpCacheItem;\nuse Pred"
},
{
"path": "src/Command/SyncStarredReposCommand.php",
"chars": 3206,
"preview": "<?php\n\nnamespace App\\Command;\n\nuse App\\Message\\StarredReposSync;\nuse App\\MessageHandler\\StarredReposSyncHandler;\nuse App"
},
{
"path": "src/Command/SyncVersionsCommand.php",
"chars": 3291,
"preview": "<?php\n\nnamespace App\\Command;\n\nuse App\\Message\\VersionsSync;\nuse App\\MessageHandler\\VersionsSyncHandler;\nuse App\\Reposit"
},
{
"path": "src/Controller/DefaultController.php",
"chars": 6885,
"preview": "<?php\n\nnamespace App\\Controller;\n\nuse App\\Entity\\User;\nuse App\\Pagination\\Exception\\InvalidPageNumberException;\nuse App\\"
},
{
"path": "src/DataFixtures/AppFixtures.php",
"chars": 4561,
"preview": "<?php\n\nnamespace App\\DataFixtures;\n\nuse App\\Entity\\Repo;\nuse App\\Entity\\Star;\nuse App\\Entity\\User;\nuse App\\Entity\\Versio"
},
{
"path": "src/Entity/Repo.php",
"chars": 6366,
"preview": "<?php\n\nnamespace App\\Entity;\n\nuse App\\Repository\\RepoRepository;\nuse Doctrine\\Common\\Collections\\ArrayCollection;\nuse Do"
},
{
"path": "src/Entity/Star.php",
"chars": 2084,
"preview": "<?php\n\nnamespace App\\Entity;\n\nuse App\\Repository\\StarRepository;\nuse Doctrine\\ORM\\Mapping as ORM;\n\n/**\n * Repo.\n */\n#[OR"
},
{
"path": "src/Entity/User.php",
"chars": 6833,
"preview": "<?php\n\nnamespace App\\Entity;\n\nuse App\\Repository\\UserRepository;\nuse Doctrine\\Common\\Collections\\ArrayCollection;\nuse Do"
},
{
"path": "src/Entity/Version.php",
"chars": 4001,
"preview": "<?php\n\nnamespace App\\Entity;\n\nuse App\\Repository\\VersionRepository;\nuse Doctrine\\ORM\\Mapping as ORM;\n\n/**\n * Version\n * "
},
{
"path": "src/Github/ClientDiscovery.php",
"chars": 3345,
"preview": "<?php\n\nnamespace App\\Github;\n\nuse App\\Cache\\CustomRedisCachePool;\nuse App\\Repository\\UserRepository;\nuse Github\\AuthMeth"
},
{
"path": "src/Github/RateLimitTrait.php",
"chars": 1147,
"preview": "<?php\n\nnamespace App\\Github;\n\nuse Github\\Api\\RateLimit;\nuse Github\\Client;\nuse Http\\Client\\Exception\\HttpException;\nuse "
},
{
"path": "src/Kernel.php",
"chars": 201,
"preview": "<?php\n\nnamespace App;\n\nuse Symfony\\Bundle\\FrameworkBundle\\Kernel\\MicroKernelTrait;\nuse Symfony\\Component\\HttpKernel\\Kern"
},
{
"path": "src/Message/StarredReposSync.php",
"chars": 212,
"preview": "<?php\n\nnamespace App\\Message;\n\nclass StarredReposSync\n{\n public function __construct(private readonly int $userId)\n "
},
{
"path": "src/Message/VersionsSync.php",
"chars": 208,
"preview": "<?php\n\nnamespace App\\Message;\n\nclass VersionsSync\n{\n public function __construct(private readonly int $repoId)\n {\n"
},
{
"path": "src/MessageHandler/StarredReposSyncHandler.php",
"chars": 6474,
"preview": "<?php\n\nnamespace App\\MessageHandler;\n\nuse App\\Entity\\Repo;\nuse App\\Entity\\Star;\nuse App\\Entity\\User;\nuse App\\Github\\Rate"
},
{
"path": "src/MessageHandler/VersionsSyncHandler.php",
"chars": 9681,
"preview": "<?php\n\nnamespace App\\MessageHandler;\n\nuse App\\Entity\\Repo;\nuse App\\Entity\\Version;\nuse App\\Github\\RateLimitTrait;\nuse Ap"
},
{
"path": "src/Pagination/Exception/CallbackNotFoundException.php",
"chars": 206,
"preview": "<?php\n\nnamespace App\\Pagination\\Exception;\n\n/**\n * Class CallbackNotFoundException.\n *\n * @author Ashley Dawson <ashley@"
},
{
"path": "src/Pagination/Exception/InvalidPageNumberException.php",
"chars": 216,
"preview": "<?php\n\nnamespace App\\Pagination\\Exception;\n\n/**\n * Class InvalidPageNumberException.\n *\n * @author Ashley Dawson <ashley"
},
{
"path": "src/Pagination/Pagination.php",
"chars": 5859,
"preview": "<?php\n\nnamespace App\\Pagination;\n\n/**\n * Class Pagination.\n *\n * @implements \\IteratorAggregate<int, mixed>\n *\n * @autho"
},
{
"path": "src/Pagination/Paginator.php",
"chars": 7073,
"preview": "<?php\n\nnamespace App\\Pagination;\n\nuse App\\Pagination\\Exception\\CallbackNotFoundException;\nuse App\\Pagination\\Exception\\I"
},
{
"path": "src/Pagination/PaginatorInterface.php",
"chars": 2144,
"preview": "<?php\n\nnamespace App\\Pagination;\n\n/**\n * Interface PaginatorInterface.\n *\n * @author Ashley Dawson <ashley@ashleydawson."
},
{
"path": "src/PubSubHubbub/Publisher.php",
"chars": 2872,
"preview": "<?php\n\nnamespace App\\PubSubHubbub;\n\nuse App\\Repository\\UserRepository;\nuse GuzzleHttp\\Client;\nuse Symfony\\Component\\Rout"
},
{
"path": "src/Repository/RepoRepository.php",
"chars": 1845,
"preview": "<?php\n\nnamespace App\\Repository;\n\nuse App\\Entity\\Repo;\nuse Doctrine\\Bundle\\DoctrineBundle\\Repository\\ServiceEntityReposi"
},
{
"path": "src/Repository/StarRepository.php",
"chars": 2026,
"preview": "<?php\n\nnamespace App\\Repository;\n\nuse App\\Entity\\Star;\nuse Doctrine\\Bundle\\DoctrineBundle\\Repository\\ServiceEntityReposi"
},
{
"path": "src/Repository/UserRepository.php",
"chars": 2182,
"preview": "<?php\n\nnamespace App\\Repository;\n\nuse App\\Entity\\User;\nuse Doctrine\\Bundle\\DoctrineBundle\\Repository\\ServiceEntityReposi"
},
{
"path": "src/Repository/VersionRepository.php",
"chars": 5010,
"preview": "<?php\n\nnamespace App\\Repository;\n\nuse App\\Entity\\Version;\nuse Doctrine\\Bundle\\DoctrineBundle\\Repository\\ServiceEntityRep"
},
{
"path": "src/Rss/Generator.php",
"chars": 3702,
"preview": "<?php\n\nnamespace App\\Rss;\n\nuse App\\Entity\\User;\nuse App\\Webfeeds\\Webfeeds;\nuse MarcW\\RssWriter\\Extension\\Atom\\AtomLink;\n"
},
{
"path": "src/Security/GithubAuthenticator.php",
"chars": 3819,
"preview": "<?php\n\nnamespace App\\Security;\n\nuse App\\Entity\\User;\nuse App\\Entity\\Version;\nuse App\\Message\\StarredReposSync;\nuse App\\R"
},
{
"path": "src/Twig/PaginationExtension.php",
"chars": 688,
"preview": "<?php\n\nnamespace App\\Twig;\n\nuse App\\Pagination\\Pagination;\nuse Twig\\Attribute\\AsTwigFunction;\nuse Twig\\Environment;\n\ncla"
},
{
"path": "src/Twig/RepoVersionExtension.php",
"chars": 501,
"preview": "<?php\n\nnamespace App\\Twig;\n\nuse Twig\\Attribute\\AsTwigFilter;\n\n/**\n * Took a repo with version information to display a l"
},
{
"path": "src/Webfeeds/Webfeeds.php",
"chars": 1013,
"preview": "<?php\n\nnamespace App\\Webfeeds;\n\nuse Symfony\\Component\\Validator\\Constraints as Assert;\n\n/**\n * Webfeeds.\n *\n * @see http"
},
{
"path": "src/Webfeeds/WebfeedsWriter.php",
"chars": 1134,
"preview": "<?php\n\nnamespace App\\Webfeeds;\n\nuse MarcW\\RssWriter\\RssWriter;\nuse MarcW\\RssWriter\\WriterRegistererInterface;\n\n/**\n * We"
},
{
"path": "templates/base.html.twig",
"chars": 3250,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width"
},
{
"path": "templates/bundles/TwigBundle/Exception/error.html.twig",
"chars": 516,
"preview": "{% extends 'base.html.twig' %}\n\n{% block body %}\n<div class=\"content\">\n <div class=\"middle-content\">\n <h2 clas"
},
{
"path": "templates/default/_line_version.html.twig",
"chars": 1859,
"preview": "<tr class=\"{% if loop.index is odd %}pure-table-odd{% endif %}\">\n <td data-th=\"Repo\">\n <img class=\"repo-avatar"
},
{
"path": "templates/default/_pagination.html.twig",
"chars": 1380,
"preview": "\n<div class=\"pagination\">\n\n {% if pagination.firstPageNumber and pagination.firstPageNumber != pagination.currentPage"
},
{
"path": "templates/default/dashboard.html.twig",
"chars": 6167,
"preview": "{% extends 'base.html.twig' %}\n\n{% block body %}\n<div class=\"content\">\n <div class=\"middle-content\">\n {% if ap"
},
{
"path": "templates/default/index.html.twig",
"chars": 5378,
"preview": "{% extends 'base.html.twig' %}\n\n{% block body %}\n<div class=\"splash-container middle-content\">\n <div class=\"splash\">\n"
},
{
"path": "templates/default/stats.html.twig",
"chars": 3033,
"preview": "{% extends 'base.html.twig' %}\n\n{% block body %}\n<div class=\"content\">\n <div class=\"middle-content\">\n {% if ap"
},
{
"path": "tests/Cache/CustomRedisCachePoolTest.php",
"chars": 6292,
"preview": "<?php\n\nnamespace App\\Tests\\Cache;\n\nuse App\\Cache\\CustomRedisCachePool;\nuse Cache\\Adapter\\Common\\CacheItem;\nuse GuzzleHtt"
},
{
"path": "tests/Command/SyncStarredReposCommandTest.php",
"chars": 7310,
"preview": "<?php\n\nnamespace App\\Tests\\Command;\n\nuse App\\Command\\SyncStarredReposCommand;\nuse App\\Message\\StarredReposSync;\nuse App\\"
},
{
"path": "tests/Command/SyncVersionsCommandTest.php",
"chars": 7154,
"preview": "<?php\n\nnamespace App\\Tests\\Command;\n\nuse App\\Command\\SyncVersionsCommand;\nuse App\\Message\\VersionsSync;\nuse App\\MessageH"
},
{
"path": "tests/Controller/DefaultControllerTest.php",
"chars": 6283,
"preview": "<?php\n\nnamespace App\\Tests\\Controller;\n\nuse App\\Entity\\User;\nuse App\\Repository\\StarRepository;\nuse App\\Repository\\UserR"
},
{
"path": "tests/Github/ClientDiscoveryTest.php",
"chars": 10492,
"preview": "<?php\n\nnamespace App\\Tests\\Github;\n\nuse App\\Github\\ClientDiscovery;\nuse App\\Repository\\UserRepository;\nuse Github\\Client"
},
{
"path": "tests/MessageHandler/StarredReposSyncHandlerTest.php",
"chars": 26454,
"preview": "<?php\n\nnamespace App\\Tests\\MessageHandler;\n\nuse App\\Entity\\Repo;\nuse App\\Entity\\Star;\nuse App\\Entity\\User;\nuse App\\Messa"
},
{
"path": "tests/MessageHandler/VersionsSyncHandlerTest.php",
"chars": 55299,
"preview": "<?php\n\nnamespace App\\Tests\\MessageHandler;\n\nuse App\\Entity\\Repo;\nuse App\\Entity\\Version;\nuse App\\Message\\VersionsSync;\nu"
},
{
"path": "tests/PubSubHubbub/PublisherTest.php",
"chars": 4342,
"preview": "<?php\n\nnamespace App\\Tests\\PubSubHubbub;\n\nuse App\\PubSubHubbub\\Publisher;\nuse App\\Repository\\UserRepository;\nuse GuzzleH"
},
{
"path": "tests/Repository/UserRepositoryTest.php",
"chars": 835,
"preview": "<?php\n\nnamespace App\\Tests\\Repository;\n\nuse App\\Repository\\UserRepository;\nuse Doctrine\\DBAL\\Connection;\nuse Symfony\\Bun"
},
{
"path": "tests/Repository/VersionRepositoryTest.php",
"chars": 2578,
"preview": "<?php\n\nnamespace App\\Tests\\Repository;\n\nuse App\\Entity\\Repo;\nuse App\\Entity\\Star;\nuse App\\Entity\\User;\nuse App\\Entity\\Ve"
},
{
"path": "tests/Rss/GeneratorTest.php",
"chars": 2847,
"preview": "<?php\n\nnamespace App\\Tests\\Rss;\n\nuse App\\Entity\\User;\nuse App\\Rss\\Generator;\nuse PHPUnit\\Framework\\TestCase;\n\nclass Gene"
},
{
"path": "tests/Security/GithubAuthenticatorTest.php",
"chars": 6325,
"preview": "<?php\n\nnamespace App\\Tests\\Security;\n\nuse App\\Entity\\User;\nuse App\\Message\\StarredReposSync;\nuse App\\Repository\\UserRepo"
},
{
"path": "tests/Twig/RepoVersionExtensionTest.php",
"chars": 1075,
"preview": "<?php\n\nnamespace App\\Tests\\Twig;\n\nuse App\\Twig\\RepoVersionExtension;\nuse PHPUnit\\Framework\\TestCase;\n\nclass RepoVersionE"
},
{
"path": "tests/Webfeeds/WebfeedsTest.php",
"chars": 761,
"preview": "<?php\n\nnamespace App\\Tests\\Webfeeds;\n\nuse App\\Webfeeds\\Webfeeds;\nuse PHPUnit\\Framework\\TestCase;\n\nclass WebfeedsTest ext"
},
{
"path": "tests/Webfeeds/WebfeedsWriterTest.php",
"chars": 1053,
"preview": "<?php\n\nnamespace App\\Tests\\Webfeeds;\n\nuse App\\Webfeeds\\Webfeeds;\nuse App\\Webfeeds\\WebfeedsWriter;\nuse MarcW\\RssWriter\\Rs"
},
{
"path": "tests/bootstrap.php",
"chars": 252,
"preview": "<?php\n\nuse Symfony\\Component\\Dotenv\\Dotenv;\n\nrequire dirname(__DIR__) . '/vendor/autoload.php';\n\nif (method_exists(Doten"
},
{
"path": "tests/console-application.php",
"chars": 323,
"preview": "<?php\n\nuse App\\Kernel;\nuse Symfony\\Bundle\\FrameworkBundle\\Console\\Application;\n\n/**\n * @see https://github.com/phpstan/p"
},
{
"path": "tests/object-manager.php",
"chars": 230,
"preview": "<?php\n\nuse App\\Kernel;\n\nrequire dirname(__DIR__) . '/tests/bootstrap.php';\n\n$kernel = new Kernel($_SERVER['APP_ENV'], (b"
}
]
// ... and 1 more files (download for full content)
About this extraction
This page contains the full source code of the j0k3r/banditore GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 120 files (469.1 KB), approximately 123.4k tokens, and a symbol index with 380 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.