Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: symfony/demo
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v2.6.0
Choose a base ref
...
head repository: symfony/demo
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: main
Choose a head ref
Loading
Showing with 1,385 additions and 1,492 deletions.
  1. +7 −4 .devcontainer/devcontainer.json
  2. +10 −1 .editorconfig
  3. +5 −6 .env
  4. +1 −0 .env.dev
  5. +1 −1 .env.test
  6. +27 −18 .github/workflows/lint.yaml
  7. +2 −15 .github/workflows/tests.yaml
  8. +4 −0 .gitignore
  9. +0 −1 .php-cs-fixer.dist.php
  10. +0 −2 assets/app.js
  11. +0 −1 assets/bootstrap.js
  12. +79 −0 assets/controllers/csrf_protection_controller.js
  13. +1 −0 assets/icons/tabler/arrow-left.svg
  14. +1 −0 assets/icons/tabler/arrow-right.svg
  15. +1 −0 assets/icons/tabler/ban.svg
  16. +1 −0 assets/icons/tabler/brand-x.svg
  17. +1 −0 assets/icons/tabler/calendar-month.svg
  18. +1 −0 assets/icons/tabler/code.svg
  19. +1 −0 assets/icons/tabler/device-floppy.svg
  20. +1 −0 assets/icons/tabler/eye.svg
  21. +1 −0 assets/icons/tabler/home.svg
  22. +1 −0 assets/icons/tabler/id-badge-2.svg
  23. +1 −0 assets/icons/tabler/key.svg
  24. +1 −0 assets/icons/tabler/list.svg
  25. +1 −0 assets/icons/tabler/lock.svg
  26. +1 −0 assets/icons/tabler/login.svg
  27. +1 −0 assets/icons/tabler/logout.svg
  28. +1 −0 assets/icons/tabler/message.svg
  29. +1 −0 assets/icons/tabler/messages.svg
  30. +1 −0 assets/icons/tabler/pencil.svg
  31. +1 −0 assets/icons/tabler/rss.svg
  32. +1 −0 assets/icons/tabler/search.svg
  33. +1 −0 assets/icons/tabler/send.svg
  34. +1 −0 assets/icons/tabler/settings.svg
  35. +1 −0 assets/icons/tabler/tag.svg
  36. +1 −0 assets/icons/tabler/tags.svg
  37. +1 −0 assets/icons/tabler/trash.svg
  38. +1 −0 assets/icons/tabler/user.svg
  39. +1 −0 assets/icons/tabler/users-group.svg
  40. +1 −0 assets/icons/tabler/world.svg
  41. +3 −4 assets/styles/app.scss
  42. +33 −34 composer.json
  43. +913 −872 composer.lock
  44. +1 −0 config/bundles.php
  45. +6 −0 config/packages/asset_mapper.yaml
  46. +11 −0 config/packages/csrf.yaml
  47. +4 −2 config/packages/doctrine.yaml
  48. +2 −19 config/packages/framework.yaml
  49. +0 −7 config/packages/security.yaml
  50. +2 −2 config/packages/translation.yaml
  51. +8 −0 config/packages/ux_icons.yaml
  52. +2 −2 config/routes.yaml
  53. +5 −2 config/services.yaml
  54. +0 −8 importmap.php
  55. +3 −62 phpstan-baseline.neon
  56. +16 −4 phpstan.neon.dist → phpstan.dist.neon
  57. +1 −1 public/.htaccess
  58. +5 −5 src/Command/AddUserCommand.php
  59. +3 −3 src/Command/DeleteUserCommand.php
  60. +2 −2 src/Command/ListUsersCommand.php
  61. 0 src/Controller/.gitignore
  62. +9 −16 src/DataFixtures/AppFixtures.php
  63. 0 src/Entity/.gitignore
  64. +1 −1 src/Event/CommentCreatedEvent.php
  65. +1 −1 src/EventSubscriber/CheckRequirementsSubscriber.php
  66. +1 −1 src/EventSubscriber/CommentNotificationSubscriber.php
  67. +1 −1 src/EventSubscriber/ControllerSubscriber.php
  68. +2 −2 src/EventSubscriber/RedirectToPreferredLocaleSubscriber.php
  69. +1 −1 src/Form/DataTransformer/TagArrayToStringTransformer.php
  70. +1 −1 src/Form/PostType.php
  71. +1 −1 src/Form/Type/DateTimePickerType.php
  72. +2 −2 src/Form/Type/TagsInputType.php
  73. +1 −1 src/Kernel.php
  74. +1 −1 src/Pagination/Paginator.php
  75. 0 src/Repository/.gitignore
  76. +2 −2 src/Twig/SourceCodeExtension.php
  77. +100 −308 symfony.lock
  78. +1 −1 templates/admin/blog/_delete_form.html.twig
  79. +2 −2 templates/admin/blog/_form.html.twig
  80. +1 −1 templates/admin/blog/edit.html.twig
  81. +5 −5 templates/admin/blog/index.html.twig
  82. +2 −2 templates/admin/blog/new.html.twig
  83. +3 −3 templates/admin/blog/show.html.twig
  84. +2 −2 templates/admin/layout.html.twig
  85. +11 −11 templates/base.html.twig
  86. +2 −2 templates/blog/_comment_form.html.twig
  87. +2 −2 templates/blog/_delete_post_confirmation.html.twig
  88. +2 −2 templates/blog/_post.html.twig
  89. +1 −1 templates/blog/_post_tags.html.twig
  90. +1 −1 templates/blog/_rss.html.twig
  91. +4 −4 templates/blog/index.html.twig
  92. +1 −1 templates/blog/index.xml.twig
  93. +5 −5 templates/blog/post_show.html.twig
  94. +1 −1 templates/bundles/TwigBundle/Exception/error403.html.twig
  95. +2 −2 templates/debug/source_code.html.twig
  96. +4 −4 templates/default/_language_selector.html.twig
  97. +2 −2 templates/default/homepage.html.twig
  98. +2 −2 templates/form/fields.html.twig
  99. +11 −7 templates/security/login.html.twig
  100. +2 −2 templates/user/change_password.html.twig
  101. +2 −2 templates/user/edit.html.twig
  102. +0 −1 tests/Controller/Admin/BlogControllerTest.php
  103. +3 −3 tests/Controller/DefaultControllerTest.php
  104. +1 −2 tests/Controller/UserControllerTest.php
  105. +1 −1 translations/messages+intl-icu.bn.xlf
  106. +1 −1 translations/messages+intl-icu.ne.xlf
11 changes: 7 additions & 4 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -3,15 +3,18 @@
"features": {
"ghcr.io/shyim/devcontainers-features/symfony-cli:0": {},
"ghcr.io/shyim/devcontainers-features/php:0": {
"version": "8.2"
},
"version": "8.4"
}
},
"updateContentCommand": {
"composer install": ["composer", "install"],
"importmap:install": ["symfony", "console", "importmap:install"]
"composer install": ["composer", "install"]
},
"postAttachCommand": {
"server": "symfony server:start",
"sass build": ["symfony", "console", "sass:build", "-w"]
},
"containerEnv": {
"SYMFONY_TRUSTED_PROXIES": "127.0.0.1",
"SYMFONY_TRUSTED_HEADERS": "x-forwarded-for,x-forwarded-host,x-forwarded-proto,x-forwarded-port"
}
}
11 changes: 10 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
@@ -3,8 +3,17 @@ root = true

; Unix-style newlines
[*]
charset = utf-8
end_of_line = LF
insert_final_newline = true
trim_trailing_whitespace = true

[*.php]
[*.{php,html,twig}]
indent_style = space
indent_size = 4

[*.md]
max_line_length = 80

[COMMIT_EDITMSG]
max_line_length = 0
11 changes: 5 additions & 6 deletions .env
Original file line number Diff line number Diff line change
@@ -16,20 +16,19 @@

###> symfony/framework-bundle ###
APP_ENV=dev
APP_SECRET=2ca64f8d83b9e89f5f19d672841d6bb8
#TRUSTED_PROXIES=127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
#TRUSTED_HOSTS='^(localhost|example\.com)$'
APP_SECRET=
###< symfony/framework-bundle ###

###> doctrine/doctrine-bundle ###
# Format described at https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url
# IMPORTANT: You MUST configure your server version, either here or in config/packages/doctrine.yaml
#
DATABASE_URL=sqlite:///%kernel.project_dir%/data/database.sqlite
# DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=8&charset=utf8mb4"
DATABASE_URL="sqlite:///%kernel.project_dir%/data/database.sqlite"
# DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=8.0.32&charset=utf8mb4"
# DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=10.11.2-MariaDB&charset=utf8mb4"
# DATABASE_URL="postgresql://app:!ChangeMe!@127.0.0.1:5432/app?serverVersion=16&charset=utf8"
###< doctrine/doctrine-bundle ###

###> symfony/mailer ###
# MAILER_DSN=null://null
MAILER_DSN=null://null
###< symfony/mailer ###
1 change: 1 addition & 0 deletions .env.dev
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Define your env variables for the development environment here
2 changes: 1 addition & 1 deletion .env.test
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# define your env variables for the test env here
# Define your env variables for the test environment here
KERNEL_CLASS='App\Kernel'
APP_SECRET='$ecretf0rt3st'
SYMFONY_DEPRECATIONS_HELPER=999999
45 changes: 27 additions & 18 deletions .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
@@ -44,23 +44,9 @@ jobs:
php-version: ${{ matrix.php-version }}
tools: composer:v2

- name: "Set composer cache directory"
id: composer-cache
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT

- name: "Cache composer"
uses: actions/cache@v4
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('composer.lock') }}
restore-keys: ${{ runner.os }}-composer-

- name: "Install dependencies"
run: composer install --ansi --no-interaction --no-progress

- name: Install PHPUnit
id: install
run: vendor/bin/simple-phpunit install
run: composer install --ansi --no-interaction --no-progress

- name: Lint YAML files
if: always() && steps.install.outcome == 'success'
@@ -70,10 +56,14 @@ jobs:
if: always() && steps.install.outcome == 'success'
run: ./bin/console lint:twig templates --env=prod

- name: Lint XLIFF translations
- name: Lint XLIFF translation files
if: always() && steps.install.outcome == 'success'
run: ./bin/console lint:xliff translations

- name: Lint translation contents
if: always() && steps.install.outcome == 'success'
run: ./bin/console lint:translations

- name: Lint Parameters and Services
if: always() && steps.install.outcome == 'success'
run: ./bin/console lint:container --no-debug
@@ -90,6 +80,25 @@ jobs:
if: always() && steps.install.outcome == 'success'
run: composer audit

static-analysis:
name: PHPStan
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
coverage: none
php-version: '8.3'

- name: Install dependencies
run: composer install --ansi --no-interaction --no-progress

- name: Install PHPUnit
run: vendor/bin/simple-phpunit install

- name: Run PHPStan
if: always() && steps.install.outcome == 'success'
run: ./vendor/bin/phpstan analyze
run: vendor/bin/phpstan analyze --no-progress
17 changes: 2 additions & 15 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
@@ -24,10 +24,9 @@ jobs:
strategy:
matrix:
operating-system: ['ubuntu-latest']
php-version: ['8.2', '8.3']
php-version: ['8.2', '8.3', '8.4']
include:
# TODO: change this to 'macos-latest' on June 2024, when '14' will become 'latest'
- operating-system: 'macos-14'
- operating-system: 'macos-latest'
php-version: '8.2'
- operating-system: 'windows-latest'
php-version: '8.2'
@@ -47,18 +46,6 @@ jobs:
- name: "Add PHPUnit matcher"
run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"

- name: "Set composer cache directory"
id: composer-cache
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
shell: bash

- name: "Cache composer"
uses: actions/cache@v4
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('composer.lock') }}
restore-keys: ${{ runner.os }}-composer-

- name: "Install dependencies"
run: composer install --ansi --no-interaction --no-progress

4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -22,3 +22,7 @@
/public/assets/
/assets/vendor/
###< symfony/asset-mapper ###

###> phpstan/phpstan ###
phpstan.neon
###< phpstan/phpstan ###
1 change: 0 additions & 1 deletion .php-cs-fixer.dist.php
Original file line number Diff line number Diff line change
@@ -16,7 +16,6 @@
->exclude('public/bundles')
->exclude('public/build')
// exclude files generated by Symfony Flex recipes
->notPath('bin/console')
->notPath('public/index.php')
->notPath('importmap.php')
;
2 changes: 0 additions & 2 deletions assets/app.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// start the Stimulus application
import './bootstrap.js';
import './styles/app.scss';
import '@fortawesome/fontawesome-free/css/all.css';
import '@fortawesome/fontawesome-free/css/v4-shims.css';
import 'highlight.js/styles/github-dark-dimmed.css';
import 'lato-font/css/lato-font.css';

1 change: 0 additions & 1 deletion assets/bootstrap.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { startStimulusApp } from '@symfony/stimulus-bundle';

const app = startStimulusApp();

// register any custom, 3rd party controllers here
// app.register('some_controller_name', SomeImportedController);
79 changes: 79 additions & 0 deletions assets/controllers/csrf_protection_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
const nameCheck = /^[-_a-zA-Z0-9]{4,22}$/;
const tokenCheck = /^[-_\/+a-zA-Z0-9]{24,}$/;

// Generate and double-submit a CSRF token in a form field and a cookie, as defined by Symfony's SameOriginCsrfTokenManager
document.addEventListener('submit', function (event) {
generateCsrfToken(event.target);
}, true);

// When @hotwired/turbo handles form submissions, send the CSRF token in a header in addition to a cookie
// The `framework.csrf_protection.check_header` config option needs to be enabled for the header to be checked
document.addEventListener('turbo:submit-start', function (event) {
const h = generateCsrfHeaders(event.detail.formSubmission.formElement);
Object.keys(h).map(function (k) {
event.detail.formSubmission.fetchRequest.headers[k] = h[k];
});
});

// When @hotwired/turbo handles form submissions, remove the CSRF cookie once a form has been submitted
document.addEventListener('turbo:submit-end', function (event) {
removeCsrfToken(event.detail.formSubmission.formElement);
});

export function generateCsrfToken (formElement) {
const csrfField = formElement.querySelector('input[data-controller="csrf-protection"], input[name="_csrf_token"]');

if (!csrfField) {
return;
}

let csrfCookie = csrfField.getAttribute('data-csrf-protection-cookie-value');
let csrfToken = csrfField.value;

if (!csrfCookie && nameCheck.test(csrfToken)) {
csrfField.setAttribute('data-csrf-protection-cookie-value', csrfCookie = csrfToken);
csrfField.defaultValue = csrfToken = btoa(String.fromCharCode.apply(null, (window.crypto || window.msCrypto).getRandomValues(new Uint8Array(18))));
csrfField.dispatchEvent(new Event('change', { bubbles: true }));
}

if (csrfCookie && tokenCheck.test(csrfToken)) {
const cookie = csrfCookie + '_' + csrfToken + '=' + csrfCookie + '; path=/; samesite=strict';
document.cookie = window.location.protocol === 'https:' ? '__Host-' + cookie + '; secure' : cookie;
}
}

export function generateCsrfHeaders (formElement) {
const headers = {};
const csrfField = formElement.querySelector('input[data-controller="csrf-protection"], input[name="_csrf_token"]');

if (!csrfField) {
return headers;
}

const csrfCookie = csrfField.getAttribute('data-csrf-protection-cookie-value');

if (tokenCheck.test(csrfField.value) && nameCheck.test(csrfCookie)) {
headers[csrfCookie] = csrfField.value;
}

return headers;
}

export function removeCsrfToken (formElement) {
const csrfField = formElement.querySelector('input[data-controller="csrf-protection"], input[name="_csrf_token"]');

if (!csrfField) {
return;
}

const csrfCookie = csrfField.getAttribute('data-csrf-protection-cookie-value');

if (tokenCheck.test(csrfField.value) && nameCheck.test(csrfCookie)) {
const cookie = csrfCookie + '_' + csrfField.value + '=0; path=/; samesite=strict; max-age=0';

document.cookie = window.location.protocol === 'https:' ? '__Host-' + cookie + '; secure' : cookie;
}
}

/* stimulusFetch: 'lazy' */
export default 'csrf-protection-controller';
1 change: 1 addition & 0 deletions assets/icons/tabler/arrow-left.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/icons/tabler/arrow-right.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/icons/tabler/ban.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/icons/tabler/brand-x.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/icons/tabler/calendar-month.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/icons/tabler/code.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/icons/tabler/device-floppy.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/icons/tabler/eye.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/icons/tabler/home.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/icons/tabler/id-badge-2.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/icons/tabler/key.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/icons/tabler/list.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/icons/tabler/lock.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/icons/tabler/login.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/icons/tabler/logout.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/icons/tabler/message.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/icons/tabler/messages.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/icons/tabler/pencil.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/icons/tabler/rss.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/icons/tabler/search.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/icons/tabler/send.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/icons/tabler/settings.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/icons/tabler/tag.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/icons/tabler/tags.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/icons/tabler/trash.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/icons/tabler/user.svg
Loading