Compare commits

..

32 Commits

Author SHA1 Message Date
Younes ENNAJI ff2cd6e384 chore: update CHANGELOG 2024-09-19 07:44:09 +01:00
Younes ENNAJI 2012b6f5af Merge pull request #196 from php-flasher/issue-193
Introduce escapeHtml Option for Secure HTML Escaping in PHPFlasher
2024-09-19 07:41:45 +01:00
Younes ENNAJI 889fc4701e chore: add escapeHtml option for secure HTML escaping in notifications 2024-09-19 07:40:10 +01:00
Younes ENNAJI 74a71b36dc style: compile assets 2024-09-19 07:39:03 +01:00
Younes ENNAJI ae0b5e8f9a style: replace deprecated function darken with scss color module color.adjust 2024-09-19 07:38:53 +01:00
Younes ENNAJI e44c1d675e ci: fix phpstan errors 2024-09-19 07:32:04 +01:00
Younes ENNAJI 61bd5f7a96 chore: add rollup progress plugin 2024-09-19 07:00:51 +01:00
Younes ENNAJI faf827f248 docs: update inertia js documentation 2024-09-19 06:42:29 +01:00
Younes ENNAJI d59e37812d chore: run php-cs-fixer 2024-09-19 06:42:10 +01:00
Younes ENNAJI 51dd7dc6fb chore: upgrade dependencies 2024-09-19 06:39:52 +01:00
Younes ENNAJI 2c2326a4a9 chore: upgrade dependencies 2024-06-16 00:02:33 +01:00
Younes ENNAJI fb34c1525d chore: upgrade dependencies 2024-06-16 00:01:48 +01:00
Younes ENNAJI d496046d50 chore: upgrade dependencies 2024-06-15 21:34:46 +01:00
Younes ENNAJI 1c5b47ab52 chore: update dependencies 2024-05-31 16:02:55 +01:00
Younes ENNAJI 87f015341e chore: add parallel run php-cs-fixer config 2024-05-31 10:04:29 +01:00
Younes ENNAJI 6087a940c6 chore: upgrade npm dependencies 2024-05-31 10:01:33 +01:00
Younes ENNAJI be82ad0b69 chore: upgrade composer dependencies 2024-05-31 10:01:18 +01:00
Younes ENNAJI 88271276fc chore: add support for symfony v7.1 2024-05-31 09:59:01 +01:00
Younes ENNAJI 456e434474 chore: remove pr auto_closer github action 2024-05-27 00:40:47 +01:00
Younes ENNAJI b28525d718 chore: add and run phpstan phpunit 2024-05-27 00:34:47 +01:00
Younes ENNAJI a820277f25 chore: update CHANGELOG 2024-05-26 13:26:08 +01:00
Younes ENNAJI 10883353f2 Merge pull request #184 from php-flasher/issue-176
chore: Refactor middleware to use Symfony's base response class
2024-05-26 13:22:01 +01:00
Younes ENNAJI 6de67f7fb3 chore: Refactor middleware to use Symfony's base response class
This commit updates the FlasherMiddleware and SessionMiddleware to utilize Symfony's base response class instead of Laravel's. This change ensures broader compatibility and addresses the issue with flash message rendering after page refreshes as identified by the community. Preparing for release in v2.0.2.
2024-05-26 13:20:48 +01:00
Younes ENNAJI b08161f9ec docs: add Ahmed Gamal to the list of contributors 2024-05-26 01:51:51 +01:00
Younes ENNAJI c35e973524 Merge pull request #183 from AhmedGamal/2.x
Default configuration options
2024-05-26 01:21:49 +01:00
Ahmed Gamal f985ea2999 chore: Symfony config options update 2024-05-25 21:24:39 +03:00
Ahmed Gamal e42e91a1e0 chore: laravel config options update 2024-05-25 21:24:30 +03:00
Ahmed Gamal 08eb6089e1 docs: adding config options 2024-05-25 21:24:19 +03:00
Younes ENNAJI dd93f6e66d docs: allow users to switch between versions 2024-05-25 15:00:18 +01:00
Younes ENNAJI b6989336e7 chore: upgrade dependencies 2024-05-24 16:15:23 +01:00
Younes ENNAJI 79c6fc3bcb chore: restore .github/workflows/tests.yaml accidentally deleted in commit d2f019f 2024-05-24 13:39:01 +01:00
Younes ENNAJI f61a7d83ce test: add tests for FlasherMiddleware and SessionMiddleware registration 2024-05-24 13:33:25 +01:00
155 changed files with 2704 additions and 1626 deletions
+10
View File
@@ -85,6 +85,16 @@
"contributions": [
"design"
]
},
{
"login": "AhmedGamal",
"name": "Ahmed Gamal",
"avatar_url": "https://avatars.githubusercontent.com/u/11786167?v=4",
"profile": "https://github.com/AhmedGamal",
"contributions": [
"code",
"doc"
]
}
]
}
+171
View File
@@ -0,0 +1,171 @@
name: 🧪 Run Tests & 🛠️ Static Analysis
on:
push:
branches:
- main
- 2.x
pull_request:
schedule:
- cron: '0 0 * * *' # Daily at midnight
jobs:
static-analysis:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
php: [ 8.2 ]
name: 🐘 PHP ${{ matrix.php }} Static Analysis
steps:
- name: 📥 Checkout Code
uses: actions/checkout@v4
- name: 🔧 Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
coverage: none
- name: 🚚 Cache Composer Dependencies
uses: actions/cache@v4
with:
path: ~/.composer/cache
key: ${{ runner.os }}-composer-${{ matrix.php }}-${{ hashFiles('composer.json') }}
restore-keys: ${{ runner.os }}-composer-${{ matrix.php }}-
- name: 📦 Install Dependencies
run: |
composer config --global allow-plugins true
composer install
- name: 🧹 Run PHP CS Fixer (Code Style)
run: vendor/bin/php-cs-fixer fix --dry-run
- name: 🔍 Run PHPStan (Static Analysis)
run: vendor/bin/phpstan analyse
- name: 🚀 Run PHPLint (Syntax Check)
run: vendor/bin/phplint
prime-test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- { php: 8.4, phpunit: 10.5.* }
- { php: 8.3, phpunit: 10.5.* }
- { php: 8.2, phpunit: 10.5.* }
name: 🐘 PHP ${{ matrix.php }}
steps:
- name: 📥 Checkout code
uses: actions/checkout@v4
- name: 🔧 Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
coverage: none
- name: 🚚 Cache dependencies
uses: actions/cache@v4
with:
path: ~/.composer/cache
key: ${{ runner.os }}-composer-${{ matrix.php }}-${{ hashFiles('composer.json') }}
restore-keys: ${{ runner.os }}-composer-${{ matrix.php }}-
- name: 📦 Install dependencies
run: |
sed -i '/"require": {/,/},/d; /"require-dev": {/,/},/d' composer.json
composer config --global allow-plugins true
composer require "phpunit/phpunit:${{ matrix.phpunit }}" "mockery/mockery" "psr/container" --no-interaction --no-update
composer update --prefer-lowest -W
- name: ✅ Execute tests
run: vendor/bin/phpunit --testsuite prime
symfony-test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- { symfony: 7.2.*, php: 8.4, phpunit: 10.5.* }
- { symfony: 7.2.*, php: 8.3, phpunit: 10.5.* }
- { symfony: 7.2.*, php: 8.2, phpunit: 10.5.* }
- { symfony: 7.1.*, php: 8.2, phpunit: 10.5.* }
- { symfony: 7.0.*, php: 8.2, phpunit: 10.5.* }
name: 🌉 Symfony ${{ matrix.symfony }} PHP ${{ matrix.php }}
steps:
- name: 📥 Checkout code
uses: actions/checkout@v4
- name: 🔧 Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
coverage: none
- name: 🚚 Cache dependencies
uses: actions/cache@v4
with:
path: ~/.composer/cache
key: ${{ runner.os }}-composer-${{ matrix.php }}-${{ hashFiles('composer.json') }}
restore-keys: ${{ runner.os }}-composer-${{ matrix.php }}-
- name: 📦 Install dependencies
run: |
sed -i '/"require": {/,/},/d; /"require-dev": {/,/},/d' composer.json
composer config --global allow-plugins true
composer config extra.symfony.require "${{ matrix.symfony }}"
composer require "symfony/config:${{ matrix.symfony }}" "symfony/console:${{ matrix.symfony }}" "symfony/dependency-injection:${{ matrix.symfony }}" "symfony/framework-bundle:${{ matrix.symfony }}" "symfony/http-kernel:${{ matrix.symfony }}" "symfony/translation:${{ matrix.symfony }}" "symfony/twig-bundle:${{ matrix.symfony }}" "phpunit/phpunit:${{ matrix.phpunit }}" "mockery/mockery" "psr/container" "monolog/monolog" --no-interaction --no-update
composer update --prefer-lowest -W
- name: ✅ Execute tests
run: vendor/bin/phpunit --testsuite symfony
laravel-test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- { laravel: 11.*, testbench: 9.*, php: 8.3, phpunit: 10.5.* }
- { laravel: 11.*, testbench: 9.*, php: 8.2, phpunit: 10.5.* }
name: 🏗 Laravel ${{ matrix.laravel }} PHP ${{ matrix.php }}
steps:
- name: 📥 Checkout code
uses: actions/checkout@v4
- name: 🔧 Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: fileinfo
coverage: none
- name: 🚚 Cache dependencies
uses: actions/cache@v4
with:
path: ~/.composer/cache
key: ${{ matrix.php }}-composer-${{ hashFiles('composer.json') }}
restore-keys: ${{ matrix.php }}-composer
- name: 📦 Install dependencies
run: |
sed -i '/\"require\": {/,/},/d; /\"require-dev\": {/,/},/d' composer.json
composer config --global allow-plugins true
composer require "laravel/framework:${{ matrix.laravel }}" "phpunit/phpunit:${{ matrix.phpunit }}" "orchestra/testbench:${{ matrix.testbench }}" --no-interaction --no-update
composer update --prefer-lowest -W
- name: ✅ Execute tests
run: vendor/bin/phpunit --testsuite laravel
+1 -1
View File
@@ -1 +1 @@
20.11.0
22.9.0
+7 -2
View File
@@ -2,7 +2,11 @@
declare(strict_types=1);
$finder = PhpCsFixer\Finder::create()
use PhpCsFixer\Config;
use PhpCsFixer\Finder;
use PhpCsFixer\Runner\Parallel\ParallelConfigFactory;
$finder = Finder::create()
->in([
__DIR__.'/src',
__DIR__.'/tests',
@@ -11,7 +15,8 @@ $finder = PhpCsFixer\Finder::create()
->append([__FILE__])
;
return (new PhpCsFixer\Config())
return (new Config())
->setParallelConfig(ParallelConfigFactory::detect())
->setRiskyAllowed(true)
->setRules([
'@PSR12' => true,
+11 -5
View File
@@ -1,10 +1,16 @@
# CHANGELOG for 2.x
## [Unreleased](https://github.com/php-flasher/php-flasher/compare/v2.0.1...2.x)
## [Unreleased](https://github.com/php-flasher/php-flasher/compare/v2.0.2...2.x)
## [v2.0.2](https://github.com/php-flasher/php-flasher/compare/v2.0.1...v2.0.2) - 2024-09-19
* feature [Flasher] add escapeHtml option for secure HTML escaping in notifications. See [PR #196](https://github.com/php-flasher/php-flasher/pull/196) by [yoeunes](https://github.com/yoeunes)
* feature [Flasher] add Default configuration options. See [PR #183](https://github.com/php-flasher/php-flasher/pull/183) by [AhmedGamal](https://github.com/AhmedGamal)
* feature [Laravel] Refactor middleware to use Symfony's base response class, addressing compatibility issues. See [PR #184](https://github.com/php-flasher/php-flasher/pull/184) by [yoeunes](https://github.com/yoeunes)
## [v2.0.1](https://github.com/php-flasher/php-flasher/compare/v2.0.0...v2.0.1) - 2024-05-23
* bug [#176](https://github.com/php-flasher/php-flasher/issues/176) [Laravel] Correctly disable FlasherMiddleware when `inject_assets` is set to false. See [PR #177](https://github.com/php-flasher/php-flasher/pull/177)
* bug [#176](https://github.com/php-flasher/php-flasher/issues/176) [Flasher] Ensure global `timeout` option applies to all requests. See [PR #180](https://github.com/php-flasher/php-flasher/pull/180)
* bug [#176](https://github.com/php-flasher/php-flasher/issues/176) [Laravel] Allow disabling of default flash replacement by setting `flash_bag` to false. See [PR #181](https://github.com/php-flasher/php-flasher/pull/181)
* bug [#176](https://github.com/php-flasher/php-flasher/issues/176) [Flasher] Ensure `flash_bag` option overrides default values instead of appending. See [PR #182](https://github.com/php-flasher/php-flasher/pull/182)
* bug [#176](https://github.com/php-flasher/php-flasher/issues/176) [Laravel] Correctly disable FlasherMiddleware when `inject_assets` is set to false. See [PR #177](https://github.com/php-flasher/php-flasher/pull/177) by [yoeunes](https://github.com/yoeunes)
* bug [#176](https://github.com/php-flasher/php-flasher/issues/176) [Flasher] Ensure global `timeout` option applies to all requests. See [PR #180](https://github.com/php-flasher/php-flasher/pull/180) by [yoeunes](https://github.com/yoeunes)
* bug [#176](https://github.com/php-flasher/php-flasher/issues/176) [Laravel] Allow disabling of default flash replacement by setting `flash_bag` to false. See [PR #181](https://github.com/php-flasher/php-flasher/pull/181) by [yoeunes](https://github.com/yoeunes)
* bug [#176](https://github.com/php-flasher/php-flasher/issues/176) [Flasher] Ensure `flash_bag` option overrides default values instead of appending. See [PR #182](https://github.com/php-flasher/php-flasher/pull/182) by [yoeunes](https://github.com/yoeunes)
+2 -2
View File
@@ -36,7 +36,7 @@ Shining stars of our community:
<table>
<tbody>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://www.linkedin.com/in/younes-ennaji/"><img src="https://avatars.githubusercontent.com/u/10859693?v=4?s=100" width="100px;" alt="Younes ENNAJI"/><br /><sub><b>Younes ENNAJI</b></sub></a><br /><a href="https://github.com/php-flasher/php-flasher/commits?author=yoeunes" title="Code">💻</a> <a href="https://github.com/php-flasher/php-flasher/commits?author=yoeunes" title="Documentation">📖</a> <a href="#maintenance-yoeunes" title="Maintenance">🚧</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.linkedin.com/in/younes--ennaji/"><img src="https://avatars.githubusercontent.com/u/10859693?v=4?s=100" width="100px;" alt="Younes ENNAJI"/><br /><sub><b>Younes ENNAJI</b></sub></a><br /><a href="https://github.com/php-flasher/php-flasher/commits?author=yoeunes" title="Code">💻</a> <a href="https://github.com/php-flasher/php-flasher/commits?author=yoeunes" title="Documentation">📖</a> <a href="#maintenance-yoeunes" title="Maintenance">🚧</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/salmayno"><img src="https://avatars.githubusercontent.com/u/27933199?v=4?s=100" width="100px;" alt="Salma Mourad"/><br /><sub><b>Salma Mourad</b></sub></a><br /><a href="#financial-salmayno" title="Financial">💵</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.youtube.com/rstacode"><img src="https://avatars.githubusercontent.com/u/35005761?v=4?s=100" width="100px;" alt="Nashwan Abdullah"/><br /><sub><b>Nashwan Abdullah</b></sub></a><br /><a href="#financial-codenashwan" title="Financial">💵</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://darvis.nl/"><img src="https://avatars.githubusercontent.com/u/7394837?v=4?s=100" width="100px;" alt="Arvid de Jong"/><br /><sub><b>Arvid de Jong</b></sub></a><br /><a href="#financial-darviscommerce" title="Financial">💵</a></td>
@@ -46,7 +46,7 @@ Shining stars of our community:
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://www.instagram.com/lucas.maciel_z"><img src="https://avatars.githubusercontent.com/u/80225404?v=4?s=100" width="100px;" alt="Lucas Maciel"/><br /><sub><b>Lucas Maciel</b></sub></a><br /><a href="#design-LucasStorm" title="Design">🎨</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://siek.io/"><img src="https://avatars.githubusercontent.com/u/5730766?v=4?s=100" width="100px;" alt="Antoni Siek"/><br /><sub><b>Antoni Siek</b></sub></a><br /><a href="https://github.com/php-flasher/php-flasher/commits?author=ImJustToNy" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/AhmedGamal"><img src="https://avatars.githubusercontent.com/u/11786167?v=4?s=100" width="100px;" alt="Ahmed Gamal"/><br /><sub><b>Ahmed Gamal</b></sub></a><br /><a href="https://github.com/php-flasher/php-flasher/commits?author=AhmedGamal" title="Code">💻</a> <a href="https://github.com/php-flasher/php-flasher/commits?author=AhmedGamal" title="Documentation">📖</a></td>
</tr>
</tbody>
</table>
+16 -14
View File
@@ -26,20 +26,22 @@
"require-dev": {
"illuminate/routing": "^11.0",
"illuminate/support": "^11.0",
"larastan/larastan": "^2.9.6",
"larastan/larastan": "^2.9",
"laravel/octane": "^2.3",
"livewire/livewire": "^3.3",
"mockery/mockery": "^1.6.12",
"orchestra/testbench": "^9.0.4",
"overtrue/phplint": "^9.3.1",
"php-cs-fixer/shim": "^3.57.2",
"phpstan/phpstan": "^1.11.1",
"phpstan/phpstan-mockery": "^1.1.2",
"phpstan/phpstan-symfony": "^1.4.0",
"phpunit/phpunit": "^10.5.13",
"livewire/livewire": "^3.5",
"mockery/mockery": "^1.6",
"orchestra/testbench": "^9.4",
"overtrue/phplint": "^9.4",
"php-cs-fixer/shim": "^3.64",
"phpstan/phpstan": "^1.12",
"phpstan/phpstan-mockery": "^1.1",
"phpstan/phpstan-phpunit": "^1.4",
"phpstan/phpstan-symfony": "^1.4",
"phpunit/phpunit": "^10.5",
"psr/container": "^1.1|^2.0",
"rector/rector": "^1.1.0",
"rector/swiss-knife": "^0.2.3",
"rector/rector": "^1.2",
"rector/swiss-knife": "^0.2",
"spatie/ray": "^1.41",
"symfony/config": "^7.0",
"symfony/console": "^7.0",
"symfony/dependency-injection": "^7.0",
@@ -47,8 +49,8 @@
"symfony/http-kernel": "^7.0",
"symfony/translation": "^7.0",
"symfony/twig-bundle": "^7.0",
"symfony/ux-twig-component": "^2.14",
"symplify/monorepo-builder": "^11.2.20"
"symfony/ux-twig-component": "^2.19",
"symplify/monorepo-builder": "^11.2"
},
"autoload": {
"psr-4": {
Generated
+397 -196
View File
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -4,7 +4,8 @@ return [
'inject_assets' => true,
'options' => [
'timeout' => 5_000,
'timeout' => 5000, // in milliseconds
'position' => 'top-right',
],
'flash_bag' => [
+35
View File
@@ -0,0 +1,35 @@
flasher:
# Default notification library (e.g., 'flasher', 'toastr', 'noty', etc.)
default: flasher
# Path to the main JavaScript file of PHPFlasher
main_script: '/vendor/flasher/flasher.min.js'
# Path to the stylesheets for PHPFlasher notifications
styles:
- '/vendor/flasher/flasher.min.css'
# Enable translation of PHPFlasher messages using Symfony's translator service
translate: true
# Automatically inject PHPFlasher assets in HTML response
inject_assets: true
# Global options
options:
# timeout in milliseconds
timeout: 5000
position: 'top-right'
# Map Symfony session keys to PHPFlasher notification types
flash_bag:
success: ['success']
error: ['error', 'danger']
warning: ['warning', 'alarm']
info: ['info', 'notice', 'alert']
# Criteria to filter displayed notifications (limit, types)
filter:
# Limit number of displayed notifications
limit: 5
+2 -2
View File
@@ -1,6 +1,6 @@
{
"dist/main.css": "/dist/main.73b25228.css",
"dist/main.js": "/dist/main.09f63ce9.js",
"dist/main.css": "/dist/main.27d36c82.css",
"dist/main.js": "/dist/main.513c5cd1.js",
"dist/455.3a7b4474.css": "/dist/455.3a7b4474.css",
"dist/455.095e6545.js": "/dist/455.095e6545.js",
"dist/411.29cd993e.css": "/dist/411.29cd993e.css",
+4
View File
@@ -3,3 +3,7 @@ version: "2.x"
title: "Easily add flash messages to your #Laravel or #Symfony projects with PHPFlasher - a powerful, easy-to-use package for improved user engagement & experience"
description: "PHPFlasher - A powerful & easy-to-use package for adding flash messages to Laravel or Symfony projects. Provides feedback to users, improves engagement & enhances user experience. Intuitive design for beginners & experienced developers. A reliable, flexible solution."
versions:
2.x: "https://php-flasher.io/"
1.x: "https://php-flasher.github.io/"
+6 -4
View File
@@ -18,12 +18,14 @@
<div class="h-16 z-10 top-0 w-screen bg-white border-b border-indigo-200 shadow">
<div id="header-logo" class="lg:container lg:mx-auto px-4 py-2">
<div class="flex items-center flex-no-shrink pt-1">
<a href="/" class="flex items-center">
<span class="pr-2 font-normal font-normal leading-none text-3xl text-indigo-900 hidden sm:block">
<div class="flex items-center">
<span class="pr-2 font-normal leading-none text-3xl text-indigo-900 hidden sm:block">
<img class="fill-current h-8 mr-2" src="/static/images/php-flasher-logo.svg" />
<sup class="text-xs relative text-grey-dark" style="top: -20px;">{{ site.data.project.version }}</sup>
{% for version in site.data.project.versions %}
<a href="{{ version[1] }}" class="{% if forloop.first %}text-white bg-indigo-500{% else %}text-indigo-600{% endif %} p-1 rounded text-xs relative text-grey-dark hover:bg-indigo-500 hover:scale-110 hover:text-white" style="top: -20px;">{{ version[0] }}</a>
{% endfor %}
</span>
</a>
</div>
<div class="flex-grow"></div>
<a href="#" id="menu-toggle" class="block lg:hidden h-8 w-8 border p-1 border-transparent text-gray-200 hover:text-grey menu-closed">
<svg class="menu-closed:shown fill-current h-full w-full" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
+2 -2
View File
@@ -2,10 +2,10 @@
"entrypoints": {
"main": {
"css": [
"/dist/main.73b25228.css"
"/dist/main.27d36c82.css"
],
"js": [
"/dist/main.09f63ce9.js"
"/dist/main.513c5cd1.js"
]
}
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+4 -4
View File
@@ -20,7 +20,7 @@
"noty": "^3.2.0-beta-deprecated",
"notyf": "^3.10.0",
"prismjs": "^1.29.0",
"sweetalert2": "^11.10.8",
"sweetalert2": "^11.11.0",
"toastr": "^2.1.4"
},
"devDependencies": {
@@ -8157,9 +8157,9 @@
}
},
"node_modules/sweetalert2": {
"version": "11.10.8",
"resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.10.8.tgz",
"integrity": "sha512-oAkYROBfXBY+4sVbQEIcN+ZxAx69lsmz5WEBwdEpyS4m59vOBNlRU5/fJpAI1MVfiDwFZiGwVzB/KBpOyfLNtg==",
"version": "11.11.0",
"resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.11.0.tgz",
"integrity": "sha512-wKCTtoE6lQVDKaJ5FFq+znk/YykJmJlD8RnLZps8C7DyivctCoRlVeeOwnKfgwKS+QJYon7s++3dmNi3/am1tw==",
"funding": {
"type": "individual",
"url": "https://github.com/sponsors/limonte"
+1 -1
View File
@@ -21,7 +21,7 @@
"noty": "^3.2.0-beta-deprecated",
"notyf": "^3.10.0",
"prismjs": "^1.29.0",
"sweetalert2": "^11.10.8",
"sweetalert2": "^11.11.0",
"toastr": "^2.1.4"
},
"devDependencies": {
+1 -1
View File
@@ -37,7 +37,7 @@ class HandleInertiaRequests extends Middleware
public function share(Request $request): array
{
return array_merge(parent::share($request), [
'messages' => flash()->render([], 'array'),
'messages' => flash()->render('array'),
]);
}
}
+6
View File
@@ -68,6 +68,12 @@ return [
// Automatically inject PHPFlasher assets in HTML response
'inject_assets' => true,
// Global options
'options' => [
'timeout' => 5000, // in milliseconds
'position' => 'top-right',
],
// Configuration for the flash bag (converting Laravel flash messages)
// Map Laravel session keys to PHPFlasher types
'flash_bag' => [
+6
View File
@@ -66,6 +66,12 @@ flasher:
# Automatically inject PHPFlasher assets in HTML response
inject_assets: true
# Global options
options:
# timeout in milliseconds
timeout: 5000
position: 'top-right'
# Map Symfony session keys to PHPFlasher notification types
flash_bag:
success: ['success']
+1561 -834
View File
File diff suppressed because it is too large Load Diff
+16 -14
View File
@@ -19,39 +19,41 @@
},
"devDependencies": {
"@antfu/eslint-config": "2.12.2",
"@babel/core": "^7.24.5",
"@babel/preset-env": "^7.24.5",
"@babel/core": "^7.25.2",
"@babel/preset-env": "^7.25.4",
"@rollup/plugin-babel": "^6.0.4",
"@rollup/plugin-commonjs": "^25.0.8",
"@rollup/plugin-eslint": "^9.0.5",
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-terser": "^0.4.4",
"@rollup/plugin-typescript": "^11.1.6",
"@types/node": "^20.12.12",
"@types/node": "^20.16.5",
"@typescript-eslint/eslint-plugin": "7.5.0",
"@typescript-eslint/parser": "^7.10.0",
"autoprefixer": "^10.4.19",
"browserslist": "^4.23.0",
"@typescript-eslint/parser": "^7.18.0",
"all-contributors-cli": "^6.26.1",
"autoprefixer": "^10.4.20",
"browserslist": "^4.23.3",
"cross-env": "7.0.3",
"cssnano": "^6.1.2",
"eslint": "^8.57.0",
"eslint": "^8.57.1",
"eslint-config-airbnb-typescript": "^18.0.0",
"eslint-config-prettier": "^9.1.0",
"eslint-import-resolver-typescript": "^3.6.1",
"eslint-import-resolver-typescript": "^3.6.3",
"eslint-plugin-babel": "5.3.1",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-import": "^2.30.0",
"eslint-plugin-prettier": "^5.2.1",
"postcss-discard-comments": "^6.0.2",
"punycode": "2.3.1",
"rollup": "^4.18.0",
"rollup": "^4.22.0",
"rollup-plugin-cleanup": "^3.2.1",
"rollup-plugin-clear": "^2.0.7",
"rollup-plugin-copy": "3.5.0",
"rollup-plugin-filesize": "^10.0.0",
"rollup-plugin-postcss": "^4.0.2",
"sass": "^1.77.2",
"rollup-plugin-progress": "^1.1.2",
"sass": "^1.79.1",
"ts-node": "^10.9.2",
"tslib": "^2.6.2",
"typescript": "^5.4.5"
"tslib": "^2.7.0",
"typescript": "^5.6.2"
}
}
+5
View File
@@ -5,6 +5,8 @@ includes:
- vendor/phpstan/phpstan-symfony/rules.neon
- vendor/larastan/larastan/extension.neon
- vendor/phpstan/phpstan-mockery/extension.neon
- vendor/phpstan/phpstan-phpunit/extension.neon
- vendor/phpstan/phpstan-phpunit/rules.neon
parameters:
level: 9
@@ -14,3 +16,6 @@ parameters:
- tests/
tmpDir: .cache/phpstan
ignoreErrors:
- '#Call to method .+ with .+ will always evaluate to true.#'
+2
View File
@@ -12,6 +12,7 @@ import postcss from 'rollup-plugin-postcss'
import cssnano from 'cssnano'
import autoprefixer from 'autoprefixer'
import discardComments from 'postcss-discard-comments'
import progress from 'rollup-plugin-progress'
const isProduction = process.env.NODE_ENV === 'production'
@@ -68,6 +69,7 @@ function createPlugins({ name, path, assets }) {
: []
return [
progress(),
...(isProduction ? [clear({ targets: [`${path}/dist`, `${path}/public`] })] : []),
postcss({ extract: filename, plugins: isProduction ? postcssPlugins : [] }),
...commonPlugins(path),
-23
View File
@@ -1,23 +0,0 @@
name: Auto Closer PR
on:
pull_request_target:
types: [ opened ]
jobs:
run:
name: 🤖 PR Auto-Closure
runs-on: ubuntu-latest
steps:
- uses: superbrothers/close-pull-request@v3
with:
comment: |
Hi there 👋,
First off, thanks for your effort! 🎉 Unfortunately, this repository is read-only because it's split from our primary monorepo repository.
🙏 We kindly ask if you could direct your valuable contribution to our main repository at https://github.com/php-flasher/php-flasher.
Once you've moved your contribution there, we'll review it and provide feedback. 🕵️‍♂️
Thanks again for your understanding and cooperation. We really appreciate it! 🙌
+4 -4
View File
@@ -90,12 +90,12 @@ final class InstallCommand extends Command
$this->publishConfig($plugin, $configFile);
}
$status = sprintf('<fg=green;options=bold>%s</>', '\\' === \DIRECTORY_SEPARATOR ? 'OK' : "\xE2\x9C\x94" /* HEAVY CHECK MARK (U+2714) */);
$output->writeln(sprintf(' %s <fg=blue;options=bold>%s</>', $status, $plugin->getAlias()));
$status = \sprintf('<fg=green;options=bold>%s</>', '\\' === \DIRECTORY_SEPARATOR ? 'OK' : "\xE2\x9C\x94" /* HEAVY CHECK MARK (U+2714) */);
$output->writeln(\sprintf(' %s <fg=blue;options=bold>%s</>', $status, $plugin->getAlias()));
} catch (\Exception $e) {
$exitCode = self::FAILURE;
$status = sprintf('<fg=red;options=bold>%s</>', '\\' === \DIRECTORY_SEPARATOR ? 'ERROR' : "\xE2\x9C\x98" /* HEAVY BALLOT X (U+2718) */);
$output->writeln(sprintf(' %s <fg=blue;options=bold>%s</> <error>%s</error>', $status, $plugin->getAlias(), $e->getMessage()));
$status = \sprintf('<fg=red;options=bold>%s</>', '\\' === \DIRECTORY_SEPARATOR ? 'ERROR' : "\xE2\x9C\x98" /* HEAVY BALLOT X (U+2718) */);
$output->writeln(\sprintf(' %s <fg=blue;options=bold>%s</> <error>%s</error>', $status, $plugin->getAlias(), $e->getMessage()));
}
}
+10 -15
View File
@@ -13,37 +13,32 @@ use Illuminate\Support\Facades\Facade;
* @method static NotificationBuilder title(string $message)
* @method static NotificationBuilder message(string $message)
* @method static NotificationBuilder type(string $message)
* @method static NotificationBuilder options(array $options, bool $merge = true)
* @method static NotificationBuilder options(array<string, mixed> $options, bool $merge = true)
* @method static NotificationBuilder option(string $name, $value)
* @method static NotificationBuilder priority(int $priority)
* @method static NotificationBuilder hops(int $amount)
* @method static NotificationBuilder keep()
* @method static NotificationBuilder delay(int $delay)
* @method static NotificationBuilder translate(array $parameters = [], ?string $locale = null)
* @method static NotificationBuilder translate(array<string, mixed> $parameters = [], ?string $locale = null)
* @method static NotificationBuilder handler(string $handler)
* @method static NotificationBuilder context(array $context)
* @method static NotificationBuilder context(array<string, mixed> $context)
* @method static NotificationBuilder when(bool|\Closure $condition)
* @method static NotificationBuilder unless(bool|\Closure $condition)
* @method static NotificationBuilder with(StampInterface[] $stamps = array())
* @method static NotificationBuilder withStamp(StampInterface $stamp)
* @method static Envelope success(string $message, array $options = [], ?string $title = null)
* @method static Envelope error(string $message, array $options = [], ?string $title = null)
* @method static Envelope info(string $message, array $options = [], ?string $title = null)
* @method static Envelope warning(string $message, array $options = [], ?string $title = null)
* @method static Envelope flash(?string $type = null, ?string $message = null, array $options = [], ?string $title = null)
* @method static Envelope preset(string $preset, array $parameters = [])
* @method static Envelope success(string $message, array<string, mixed> $options = [], ?string $title = null)
* @method static Envelope error(string $message, array<string, mixed> $options = [], ?string $title = null)
* @method static Envelope info(string $message, array<string, mixed> $options = [], ?string $title = null)
* @method static Envelope warning(string $message, array<string, mixed> $options = [], ?string $title = null)
* @method static Envelope flash(?string $type = null, ?string $message = null, array<string, mixed> $options = [], ?string $title = null)
* @method static Envelope preset(string $preset, array<string, mixed> $parameters = [])
* @method static Envelope operation(string $operation, string|object|null $resource = null)
* @method static Envelope created(string|object|null $resource = null)
* @method static Envelope updated(string|object|null $resource = null)
* @method static Envelope saved(string|object|null $resource = null)
* @method static Envelope deleted(string|object|null $resource = null)
* @method static Envelope push()
* @method static Envelope addSuccess(string $message, array $options = [], ?string $title = null)
* @method static Envelope addError(string $message, array $options = [], ?string $title = null)
* @method static Envelope addInfo(string $message, array $options = [], ?string $title = null)
* @method static Envelope addWarning(string $message, array $options = [], ?string $title = null)
* @method static Envelope addFlash(?string $type = null, ?string $message = null, array $options = [], ?string $title = null)
* @method static Envelope addPreset(string $preset, array $parameters = [])
* @method static Envelope addPreset(string $preset, array<string, mixed> $parameters = [])
* @method static Envelope addCreated(string|object|null $resource = null)
* @method static Envelope addUpdated(string|object|null $resource = null)
* @method static Envelope addDeleted(string|object|null $resource = null)
+1 -1
View File
@@ -210,7 +210,7 @@ final class FlasherServiceProvider extends PluginServiceProvider
AboutCommand::add('PHPFlasher', [
'Version' => Flasher::VERSION,
'Factories' => implode(' <fg=gray;options=bold>/</> ', array_map(fn ($factory) => sprintf('<fg=yellow;options=bold>%s</>', $factory), $factories)),
'Factories' => implode(' <fg=gray;options=bold>/</> ', array_map(fn ($factory) => \sprintf('<fg=yellow;options=bold>%s</>', $factory), $factories)),
]);
}
+5 -4
View File
@@ -5,12 +5,13 @@ declare(strict_types=1);
namespace Flasher\Laravel\Http;
use Flasher\Prime\Http\ResponseInterface;
use Illuminate\Http\JsonResponse as LaravelJsonResponse;
use Illuminate\Http\Response as LaravelResponse;
use Symfony\Component\HttpFoundation\JsonResponse as SymfonyJsonResponse;
use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
final readonly class Response implements ResponseInterface
{
public function __construct(private LaravelJsonResponse|LaravelResponse $response)
public function __construct(private SymfonyResponse $response)
{
}
@@ -21,7 +22,7 @@ final readonly class Response implements ResponseInterface
public function isJson(): bool
{
return $this->response instanceof LaravelJsonResponse;
return $this->response instanceof SymfonyJsonResponse;
}
public function isHtml(): bool
@@ -66,7 +67,7 @@ final readonly class Response implements ResponseInterface
$this->response->setContent($content);
// Restore original response (eg. the View or Ajax data)
if ($original) {
if ($original && $this->response instanceof LaravelResponse) {
$this->response->original = $original;
}
}
+2 -3
View File
@@ -7,9 +7,8 @@ namespace Flasher\Laravel\Middleware;
use Flasher\Laravel\Http\Request;
use Flasher\Laravel\Http\Response;
use Flasher\Prime\Http\ResponseExtensionInterface;
use Illuminate\Http\JsonResponse as LaravelJsonResponse;
use Illuminate\Http\Request as LaravelRequest;
use Illuminate\Http\Response as LaravelResponse;
use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
final readonly class FlasherMiddleware
{
@@ -21,7 +20,7 @@ final readonly class FlasherMiddleware
{
$response = $next($request);
if ($response instanceof LaravelJsonResponse || $response instanceof LaravelResponse) {
if ($response instanceof SymfonyResponse) {
$this->responseExtension->render(new Request($request), new Response($response));
}
+2 -3
View File
@@ -7,9 +7,8 @@ namespace Flasher\Laravel\Middleware;
use Flasher\Laravel\Http\Request;
use Flasher\Laravel\Http\Response;
use Flasher\Prime\Http\RequestExtensionInterface;
use Illuminate\Http\JsonResponse as LaravelJsonResponse;
use Illuminate\Http\Request as LaravelRequest;
use Illuminate\Http\Response as LaravelResponse;
use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
final readonly class SessionMiddleware
{
@@ -21,7 +20,7 @@ final readonly class SessionMiddleware
{
$response = $next($request);
if ($response instanceof LaravelJsonResponse || $response instanceof LaravelResponse) {
if ($response instanceof SymfonyResponse) {
$this->requestExtension->flash(new Request($request), new Response($response));
}
+6
View File
@@ -22,6 +22,12 @@ return [
// Automatically inject PHPFlasher assets into HTML response
'inject_assets' => true,
// Global options
'options' => [
'timeout' => 5000, // in milliseconds
'position' => 'top-right',
],
// Configuration for the flash bag (converting Laravel flash messages)
// Map Laravel session keys to PHPFlasher types
'flash_bag' => [
-23
View File
@@ -1,23 +0,0 @@
name: Auto Closer PR
on:
pull_request_target:
types: [ opened ]
jobs:
run:
name: 🤖 PR Auto-Closure
runs-on: ubuntu-latest
steps:
- uses: superbrothers/close-pull-request@v3
with:
comment: |
Hi there 👋,
First off, thanks for your effort! 🎉 Unfortunately, this repository is read-only because it's split from our primary monorepo repository.
🙏 We kindly ask if you could direct your valuable contribution to our main repository at https://github.com/php-flasher/php-flasher.
Once you've moved your contribution there, we'll review it and provide feedback. 🕵️‍♂️
Thanks again for your understanding and cooperation. We really appreciate it! 🙌
+8 -15
View File
@@ -6,25 +6,18 @@ namespace Flasher\Noty\Laravel\Facade;
use Flasher\Noty\Prime\NotyBuilder;
use Flasher\Prime\Notification\Envelope;
use Flasher\Prime\Notification\NotificationInterface;
use Flasher\Prime\Stamp\StampInterface;
use Illuminate\Support\Facades\Facade;
/**
* @method static NotyBuilder addSuccess(string $message, array $options = array())
* @method static NotyBuilder addError(string $message, array $options = array())
* @method static NotyBuilder addWarning(string $message, array $options = array())
* @method static NotyBuilder addInfo(string $message, array $options = array())
* @method static NotyBuilder addFlash(NotificationInterface|string $type, string $message = null, array $options = array())
* @method static NotyBuilder success(string $message, array<string, mixed> $options = array())
* @method static NotyBuilder error(string $message, array<string, mixed> $options = array())
* @method static NotyBuilder warning(string $message, array<string, mixed> $options = array())
* @method static NotyBuilder info(string $message, array<string, mixed> $options = array())
* @method static NotyBuilder flash(StampInterface[] $stamps = array())
* @method static NotyBuilder type(string $type, string $message = null, array $options = array())
* @method static NotyBuilder message(string $message)
* @method static NotyBuilder options(array $options, bool $merge = true)
* @method static NotyBuilder options(array<string, mixed> $options, bool $merge = true)
* @method static NotyBuilder option(string $name, string $value)
* @method static NotyBuilder success(string $message = null, array $options = array())
* @method static NotyBuilder error(string $message = null, array $options = array())
* @method static NotyBuilder info(string $message = null, array $options = array())
* @method static NotyBuilder warning(string $message = null, array $options = array())
* @method static NotyBuilder priority(int $priority)
* @method static NotyBuilder hops(int $amount)
* @method static NotyBuilder keep()
@@ -35,12 +28,12 @@ use Illuminate\Support\Facades\Facade;
* @method static NotyBuilder handler(string $handler)
* @method static Envelope getEnvelope()
* @method static NotyBuilder text(string $text)
* @method static NotyBuilder alert(string $message = null, array $options = array())
* @method static NotyBuilder alert(string $message = null, array<string, mixed> $options = array())
* @method static NotyBuilder layout(string $layout)
* @method static NotyBuilder theme(string $theme)
* @method static NotyBuilder timeout(bool|int $timeout)
* @method static NotyBuilder progressBar(bool $progressBar = false)
* @method static NotyBuilder closeWith(array|string $closeWith)
* @method static NotyBuilder closeWith(string|string[] $closeWith)
* @method static NotyBuilder animation(string $animation, string $effect)
* @method static NotyBuilder sounds(string $option, mixed $value)
* @method static NotyBuilder docTitle(string $option, mixed $docTitle)
@@ -50,7 +43,7 @@ use Illuminate\Support\Facades\Facade;
* @method static NotyBuilder queue(string $queue)
* @method static NotyBuilder killer(bool|string $killer)
* @method static NotyBuilder container(bool|string $container)
* @method static NotyBuilder buttons(array $buttons)
* @method static NotyBuilder buttons(string[] $buttons)
* @method static NotyBuilder visibilityControl(bool $visibilityControl)
*/
final class Noty extends Facade
-23
View File
@@ -1,23 +0,0 @@
name: Auto Closer PR
on:
pull_request_target:
types: [ opened ]
jobs:
run:
name: 🤖 PR Auto-Closure
runs-on: ubuntu-latest
steps:
- uses: superbrothers/close-pull-request@v3
with:
comment: |
Hi there 👋,
First off, thanks for your effort! 🎉 Unfortunately, this repository is read-only because it's split from our primary monorepo repository.
🙏 We kindly ask if you could direct your valuable contribution to our main repository at https://github.com/php-flasher/php-flasher.
Once you've moved your contribution there, we'll review it and provide feedback. 🕵️‍♂️
Thanks again for your understanding and cooperation. We really appreciate it! 🙌
-23
View File
@@ -1,23 +0,0 @@
name: Auto Closer PR
on:
pull_request_target:
types: [ opened ]
jobs:
run:
name: 🤖 PR Auto-Closure
runs-on: ubuntu-latest
steps:
- uses: superbrothers/close-pull-request@v3
with:
comment: |
Hi there 👋,
First off, thanks for your effort! 🎉 Unfortunately, this repository is read-only because it's split from our primary monorepo repository.
🙏 We kindly ask if you could direct your valuable contribution to our main repository at https://github.com/php-flasher/php-flasher.
Once you've moved your contribution there, we'll review it and provide feedback. 🕵️‍♂️
Thanks again for your understanding and cooperation. We really appreciate it! 🙌
-23
View File
@@ -1,23 +0,0 @@
name: Auto Closer PR
on:
pull_request_target:
types: [ opened ]
jobs:
run:
name: 🤖 PR Auto-Closure
runs-on: ubuntu-latest
steps:
- uses: superbrothers/close-pull-request@v3
with:
comment: |
Hi there 👋,
First off, thanks for your effort! 🎉 Unfortunately, this repository is read-only because it's split from our primary monorepo repository.
🙏 We kindly ask if you could direct your valuable contribution to our main repository at https://github.com/php-flasher/php-flasher.
Once you've moved your contribution there, we'll review it and provide feedback. 🕵️‍♂️
Thanks again for your understanding and cooperation. We really appreciate it! 🙌
+5 -12
View File
@@ -6,25 +6,18 @@ namespace Flasher\Notyf\Laravel\Facade;
use Flasher\Notyf\Prime\NotyfBuilder;
use Flasher\Prime\Notification\Envelope;
use Flasher\Prime\Notification\NotificationInterface;
use Flasher\Prime\Stamp\StampInterface;
use Illuminate\Support\Facades\Facade;
/**
* @method static NotyfBuilder addSuccess(string $message, array $options = array())
* @method static NotyfBuilder addError(string $message, array $options = array())
* @method static NotyfBuilder addWarning(string $message, array $options = array())
* @method static NotyfBuilder addInfo(string $message, array $options = array())
* @method static NotyfBuilder addFlash(NotificationInterface|string $type, string $message = null, array $options = array())
* @method static NotyfBuilder success(string $message, array<string, mixed> $options = array())
* @method static NotyfBuilder error(string $message, array<string, mixed> $options = array())
* @method static NotyfBuilder warning(string $message, array<string, mixed> $options = array())
* @method static NotyfBuilder info(string $message, array<string, mixed> $options = array())
* @method static NotyfBuilder flash(StampInterface[] $stamps = array())
* @method static NotyfBuilder type(string $type, string $message = null, array $options = array())
* @method static NotyfBuilder message(string $message)
* @method static NotyfBuilder options(array $options, bool $merge = true)
* @method static NotyfBuilder options(array<string, mixed> $options, bool $merge = true)
* @method static NotyfBuilder option(string $name, string $value)
* @method static NotyfBuilder success(string $message = null, array $options = array())
* @method static NotyfBuilder error(string $message = null, array $options = array())
* @method static NotyfBuilder info(string $message = null, array $options = array())
* @method static NotyfBuilder warning(string $message = null, array $options = array())
* @method static NotyfBuilder priority(int $priority)
* @method static NotyfBuilder hops(int $amount)
* @method static NotyfBuilder keep()
-23
View File
@@ -1,23 +0,0 @@
name: Auto Closer PR
on:
pull_request_target:
types: [ opened ]
jobs:
run:
name: 🤖 PR Auto-Closure
runs-on: ubuntu-latest
steps:
- uses: superbrothers/close-pull-request@v3
with:
comment: |
Hi there 👋,
First off, thanks for your effort! 🎉 Unfortunately, this repository is read-only because it's split from our primary monorepo repository.
🙏 We kindly ask if you could direct your valuable contribution to our main repository at https://github.com/php-flasher/php-flasher.
Once you've moved your contribution there, we'll review it and provide feedback. 🕵️‍♂️
Thanks again for your understanding and cooperation. We really appreciate it! 🙌
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-23
View File
@@ -1,23 +0,0 @@
name: Auto Closer PR
on:
pull_request_target:
types: [ opened ]
jobs:
run:
name: 🤖 PR Auto-Closure
runs-on: ubuntu-latest
steps:
- uses: superbrothers/close-pull-request@v3
with:
comment: |
Hi there 👋,
First off, thanks for your effort! 🎉 Unfortunately, this repository is read-only because it's split from our primary monorepo repository.
🙏 We kindly ask if you could direct your valuable contribution to our main repository at https://github.com/php-flasher/php-flasher.
Once you've moved your contribution there, we'll review it and provide feedback. 🕵️‍♂️
Thanks again for your understanding and cooperation. We really appreciate it! 🙌
-23
View File
@@ -1,23 +0,0 @@
name: Auto Closer PR
on:
pull_request_target:
types: [ opened ]
jobs:
run:
name: 🤖 PR Auto-Closure
runs-on: ubuntu-latest
steps:
- uses: superbrothers/close-pull-request@v3
with:
comment: |
Hi there 👋,
First off, thanks for your effort! 🎉 Unfortunately, this repository is read-only because it's split from our primary monorepo repository.
🙏 We kindly ask if you could direct your valuable contribution to our main repository at https://github.com/php-flasher/php-flasher.
Once you've moved your contribution there, we'll review it and provide feedback. 🕵️‍♂️
Thanks again for your understanding and cooperation. We really appreciate it! 🙌
+2 -2
View File
@@ -44,7 +44,7 @@ final class AssetManager implements AssetManagerInterface
}
if (false === file_put_contents($this->manifestPath, json_encode($this->entries, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES))) {
throw new \RuntimeException(sprintf('Failed to write manifest file to "%s"', $this->manifestPath));
throw new \RuntimeException(\sprintf('Failed to write manifest file to "%s"', $this->manifestPath));
}
}
@@ -67,7 +67,7 @@ final class AssetManager implements AssetManagerInterface
$entries = json_decode($content ?: '', true);
if (!\is_array($entries)) {
throw new \InvalidArgumentException(sprintf('There was a problem JSON decoding the "%s" file.', $this->manifestPath));
throw new \InvalidArgumentException(\sprintf('There was a problem JSON decoding the "%s" file.', $this->manifestPath));
}
return $this->entries = $entries; // @phpstan-ignore-line
+3 -3
View File
@@ -57,13 +57,13 @@ final class FlasherContainer
public static function create(string $id): FlasherInterface|NotificationFactoryInterface
{
if (!self::has($id)) {
throw new \InvalidArgumentException(sprintf('The container does not have the requested service "%s".', $id));
throw new \InvalidArgumentException(\sprintf('The container does not have the requested service "%s".', $id));
}
$factory = self::getContainer()->get($id);
if (!$factory instanceof FlasherInterface && !$factory instanceof NotificationFactoryInterface) {
throw new \InvalidArgumentException(sprintf('Expected an instance of "%s" or "%s", got "%s".', FlasherInterface::class, NotificationFactoryInterface::class, get_debug_type($factory)));
throw new \InvalidArgumentException(\sprintf('Expected an instance of "%s" or "%s", got "%s".', FlasherInterface::class, NotificationFactoryInterface::class, get_debug_type($factory)));
}
return $factory;
@@ -93,7 +93,7 @@ final class FlasherContainer
$resolved = $container instanceof \Closure || \is_callable($container) ? $container() : $container;
if (!$resolved instanceof ContainerInterface) {
throw new \InvalidArgumentException(sprintf('Expected an instance of "%s", got "%s".', ContainerInterface::class, get_debug_type($resolved)));
throw new \InvalidArgumentException(\sprintf('Expected an instance of "%s", got "%s".', ContainerInterface::class, get_debug_type($resolved)));
}
return $resolved;
@@ -34,7 +34,7 @@ final class EventDispatcher implements EventDispatcherInterface
}
if (!\is_callable($listener)) {
throw new \InvalidArgumentException(sprintf('Listener "%s" is not callable. Listeners must implement __invoke method.', $listener::class));
throw new \InvalidArgumentException(\sprintf('Listener "%s" is not callable. Listeners must implement __invoke method.', $listener::class));
}
$listener($event);
@@ -66,7 +66,7 @@ final readonly class TranslationListener implements EventListenerInterface
foreach ($preset->getParameters() as $key => $value) {
if (!\is_string($value)) {
throw new \InvalidArgumentException(sprintf('Value must be "string", got "%s".', get_debug_type($value)));
throw new \InvalidArgumentException(\sprintf('Value must be "string", got "%s".', get_debug_type($value)));
}
$parameters[$key] = $this->translator->translate($value, $parameters, $locale);
@@ -11,10 +11,10 @@ final class CriteriaNotRegisteredException extends \Exception
*/
public static function create(string $alias, array $availableCriteria = []): self
{
$message = sprintf('Criteria "%s" is not found, did you forget to register it?', $alias);
$message = \sprintf('Criteria "%s" is not found, did you forget to register it?', $alias);
if ([] !== $availableCriteria) {
$message .= sprintf(' Available criteria: [%s]', implode(', ', $availableCriteria));
$message .= \sprintf(' Available criteria: [%s]', implode(', ', $availableCriteria));
}
return new self($message);
@@ -11,10 +11,10 @@ final class FactoryNotFoundException extends \Exception
*/
public static function create(string $alias, array $availableFactories = []): self
{
$message = sprintf('Factory "%s" not found, did you forget to register it?', $alias);
$message = \sprintf('Factory "%s" not found, did you forget to register it?', $alias);
if ([] !== $availableFactories) {
$message .= sprintf(' Available factories: [%s]', implode(', ', $availableFactories));
$message .= \sprintf(' Available factories: [%s]', implode(', ', $availableFactories));
}
return new self($message);
@@ -11,10 +11,10 @@ final class PresenterNotFoundException extends \Exception
*/
public static function create(string $alias, array $availablePresenters = []): self
{
$message = sprintf('Presenter "%s" not found, did you forget to register it?', $alias);
$message = \sprintf('Presenter "%s" not found, did you forget to register it?', $alias);
if ([] !== $availablePresenters) {
$message .= sprintf(' Available presenters: [%s]', implode(', ', $availablePresenters));
$message .= \sprintf(' Available presenters: [%s]', implode(', ', $availablePresenters));
}
return new self($message);
@@ -12,10 +12,10 @@ final class PresetNotFoundException extends \Exception
*/
public static function create(string $preset, array $availablePresets = []): self
{
$message = sprintf('Preset "%s" not found, did you forget to register it?', $preset);
$message = \sprintf('Preset "%s" not found, did you forget to register it?', $preset);
if ([] !== $availablePresets) {
$message .= sprintf(' Available presets: "%s"', implode('", "', $availablePresets));
$message .= \sprintf(' Available presets: "%s"', implode('", "', $availablePresets));
}
return new self($message);
@@ -136,7 +136,7 @@ final class ContentSecurityPolicyHandler implements ContentSecurityPolicyHandler
if (!\in_array('\'unsafe-inline\'', $headers[$header][$type], true)) {
$headers[$header][$type][] = '\'unsafe-inline\'';
}
$headers[$header][$type][] = sprintf('\'nonce-%s\'', $nonces[$tokenName]);
$headers[$header][$type][] = \sprintf('\'nonce-%s\'', $nonces[$tokenName]);
}
}
@@ -166,7 +166,7 @@ final class ContentSecurityPolicyHandler implements ContentSecurityPolicyHandler
*/
private function generateCspHeader(array $directives): string
{
return array_reduce(array_keys($directives), fn ($res, $name) => ('' !== $res ? $res.'; ' : '').sprintf('%s %s', $name, implode(' ', $directives[$name])), '');
return array_reduce(array_keys($directives), fn ($res, $name) => ('' !== $res ? $res.'; ' : '').\sprintf('%s %s', $name, implode(' ', $directives[$name])), '');
}
/**
+1 -1
View File
@@ -55,7 +55,7 @@ final readonly class ResponseExtension implements ResponseExtensionInterface
}
if ($alreadyRendered) {
$htmlResponse = sprintf('options.push(%s);', $htmlResponse);
$htmlResponse = \sprintf('options.push(%s);', $htmlResponse);
}
// $htmlResponse = "\n".str_replace("\n", '', (string) $htmlResponse)."\n";
@@ -160,7 +160,7 @@ trait NotificationBuilderMethods
if (!\is_bool($condition)) {
$type = \gettype($condition);
throw new \InvalidArgumentException(sprintf('The condition must be a boolean or a closure that returns a boolean. Got: %s', $type));
throw new \InvalidArgumentException(\sprintf('The condition must be a boolean or a closure that returns a boolean. Got: %s', $type));
}
return $condition;
+5 -1
View File
@@ -100,7 +100,11 @@ final class FlasherPlugin extends Plugin
* scripts: string[],
* styles: string[],
* options: array<string, mixed>,
* plugins?: array<string, array<string, mixed>>,
* plugins?: array<string, array{
* scripts?: string[],
* styles?: string[],
* options?: array<string, mixed>,
* }>,
* } $config
*
* @return array{
+28 -2
View File
@@ -19,6 +19,7 @@ export default class FlasherPlugin extends AbstractPlugin {
direction: 'top',
rtl: false,
style: {} as Properties,
escapeHtml: false,
}
constructor(theme: Theme) {
@@ -31,11 +32,12 @@ export default class FlasherPlugin extends AbstractPlugin {
const render = () =>
envelopes.forEach((envelope) => {
// @ts-expect-error
const typeTimeout = this.options.timeout ?? this.options.timeouts[envelope.type] ?? 5000;
const typeTimeout = this.options.timeout ?? this.options.timeouts[envelope.type] ?? 5000
const options = {
...this.options,
...envelope.options,
timeout: envelope.options.timeout ?? typeTimeout,
escapeHtml: (envelope.options.escapeHtml ?? this.options.escapeHtml) as boolean,
}
this.addToContainer(this.createContainer(options), envelope, options)
@@ -64,7 +66,12 @@ export default class FlasherPlugin extends AbstractPlugin {
return container
}
private addToContainer(container: HTMLDivElement, envelope: Envelope, options: { direction: string, timeout: number, fps: number, rtl: boolean }): void {
private addToContainer(container: HTMLDivElement, envelope: Envelope, options: { direction: string, timeout: number, fps: number, rtl: boolean, escapeHtml: boolean }): void {
if (options.escapeHtml) {
envelope.title = this.escapeHtml(envelope.title)
envelope.message = this.escapeHtml(envelope.message)
}
const notification = this.stringToHTML(this.theme.render(envelope))
notification.classList.add(...`fl-container${options.rtl ? ' fl-rtl' : ''}`.split(' '))
@@ -126,4 +133,23 @@ export default class FlasherPlugin extends AbstractPlugin {
template.innerHTML = str.trim()
return template.content.firstElementChild as HTMLElement
}
private escapeHtml(str: string | null | undefined): string {
if (str == null) {
return ''
}
return str.replace(/[&<>"'`=\/]/g, (char) => {
return {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
'\'': '&#39;',
'`': '&#96;',
'=': '&#61;',
'/': '&#47;',
}[char] as string
})
}
}
@@ -1,3 +1,5 @@
@use "sass:color";
body.fl-dark .fl-flasher,
html.fl-dark .fl-flasher {
--background-color: var(--dark-background-color);
@@ -69,7 +71,7 @@ html.fl-dark .fl-flasher {
transition: color 0.3s ease, transform 0.3s ease;
&:hover {
color: darken(#a8aaab, 10%);
color: color.adjust(#a8aaab, $lightness: -10%);
transform: scale(1.1);
}
}
+1
View File
@@ -15,4 +15,5 @@ export default class FlasherPlugin extends AbstractPlugin {
}): void;
private removeNotification;
private stringToHTML;
private escapeHtml;
}
+24 -2
View File
@@ -92,14 +92,15 @@ class FlasherPlugin extends AbstractPlugin {
direction: 'top',
rtl: false,
style: {},
escapeHtml: false,
};
this.theme = theme;
}
renderEnvelopes(envelopes) {
const render = () => envelopes.forEach((envelope) => {
var _a, _b, _c;
var _a, _b, _c, _d;
const typeTimeout = (_b = (_a = this.options.timeout) !== null && _a !== void 0 ? _a : this.options.timeouts[envelope.type]) !== null && _b !== void 0 ? _b : 5000;
const options = Object.assign(Object.assign(Object.assign({}, this.options), envelope.options), { timeout: (_c = envelope.options.timeout) !== null && _c !== void 0 ? _c : typeTimeout });
const options = Object.assign(Object.assign(Object.assign({}, this.options), envelope.options), { timeout: (_c = envelope.options.timeout) !== null && _c !== void 0 ? _c : typeTimeout, escapeHtml: ((_d = envelope.options.escapeHtml) !== null && _d !== void 0 ? _d : this.options.escapeHtml) });
this.addToContainer(this.createContainer(options), envelope, options);
});
document.readyState === 'loading' ? document.addEventListener('DOMContentLoaded', render) : render();
@@ -121,6 +122,10 @@ class FlasherPlugin extends AbstractPlugin {
}
addToContainer(container, envelope, options) {
var _a;
if (options.escapeHtml) {
envelope.title = this.escapeHtml(envelope.title);
envelope.message = this.escapeHtml(envelope.message);
}
const notification = this.stringToHTML(this.theme.render(envelope));
notification.classList.add(...`fl-container${options.rtl ? ' fl-rtl' : ''}`.split(' '));
options.direction === 'bottom' ? container.append(notification) : container.prepend(notification);
@@ -170,6 +175,23 @@ class FlasherPlugin extends AbstractPlugin {
template.innerHTML = str.trim();
return template.content.firstElementChild;
}
escapeHtml(str) {
if (str == null) {
return '';
}
return str.replace(/[&<>"'`=\/]/g, (char) => {
return {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
'\'': '&#39;',
'`': '&#96;',
'=': '&#61;',
'/': '&#47;',
}[char];
});
}
}
class Flasher extends AbstractPlugin {
+24 -2
View File
@@ -98,14 +98,15 @@
direction: 'top',
rtl: false,
style: {},
escapeHtml: false,
};
this.theme = theme;
}
renderEnvelopes(envelopes) {
const render = () => envelopes.forEach((envelope) => {
var _a, _b, _c;
var _a, _b, _c, _d;
const typeTimeout = (_b = (_a = this.options.timeout) !== null && _a !== void 0 ? _a : this.options.timeouts[envelope.type]) !== null && _b !== void 0 ? _b : 5000;
const options = Object.assign(Object.assign(Object.assign({}, this.options), envelope.options), { timeout: (_c = envelope.options.timeout) !== null && _c !== void 0 ? _c : typeTimeout });
const options = Object.assign(Object.assign(Object.assign({}, this.options), envelope.options), { timeout: (_c = envelope.options.timeout) !== null && _c !== void 0 ? _c : typeTimeout, escapeHtml: ((_d = envelope.options.escapeHtml) !== null && _d !== void 0 ? _d : this.options.escapeHtml) });
this.addToContainer(this.createContainer(options), envelope, options);
});
document.readyState === 'loading' ? document.addEventListener('DOMContentLoaded', render) : render();
@@ -127,6 +128,10 @@
}
addToContainer(container, envelope, options) {
var _a;
if (options.escapeHtml) {
envelope.title = this.escapeHtml(envelope.title);
envelope.message = this.escapeHtml(envelope.message);
}
const notification = this.stringToHTML(this.theme.render(envelope));
notification.classList.add(...`fl-container${options.rtl ? ' fl-rtl' : ''}`.split(' '));
options.direction === 'bottom' ? container.append(notification) : container.prepend(notification);
@@ -176,6 +181,23 @@
template.innerHTML = str.trim();
return template.content.firstElementChild;
}
escapeHtml(str) {
if (str == null) {
return '';
}
return str.replace(/[&<>"'`=\/]/g, (char) => {
return {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
'\'': '&#39;',
'`': '&#96;',
'=': '&#61;',
'/': '&#47;',
}[char];
});
}
}
class Flasher extends AbstractPlugin {
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -21,6 +21,7 @@ final class HtmlPresenter implements PresenterInterface
/** @var array{csp_script_nonce?: ?string, envelopes_only?: bool} $context */
$context = $response->getContext();
/** @var array{envelopes: array<int, array{metadata: array{html?: string}}>} $options */
$options = $response->toArray();
$html = '';
+1 -1
View File
@@ -9,7 +9,7 @@ final readonly class PresenterStamp implements StampInterface
public function __construct(private string $pattern)
{
if (false === @preg_match($pattern, '')) {
throw new \InvalidArgumentException(sprintf("The provided regex pattern '%s' is invalid for the presenter stamp. Please ensure it is a valid regex expression.", $pattern));
throw new \InvalidArgumentException(\sprintf("The provided regex pattern '%s' is invalid for the presenter stamp. Please ensure it is a valid regex expression.", $pattern));
}
}
@@ -17,13 +17,13 @@ final class FilterCriteria implements CriteriaInterface
public function __construct(mixed $criteria)
{
if (!$criteria instanceof \Closure && !\is_array($criteria)) {
throw new \InvalidArgumentException(sprintf('Invalid type for criteria "filter". Expect a closure or array of closure, got "%s".', get_debug_type($criteria)));
throw new \InvalidArgumentException(\sprintf('Invalid type for criteria "filter". Expect a closure or array of closure, got "%s".', get_debug_type($criteria)));
}
$criteria = $criteria instanceof \Closure ? [$criteria] : $criteria;
foreach ($criteria as $callback) {
if (!$callback instanceof \Closure) {
throw new \InvalidArgumentException(sprintf('Each element must be a closure, got got "%s".', get_debug_type($callback)));
throw new \InvalidArgumentException(\sprintf('Each element must be a closure, got got "%s".', get_debug_type($callback)));
}
$this->callbacks[] = $callback;
@@ -49,7 +49,7 @@ final class OrderByCriteria implements CriteriaInterface
public function __construct(mixed $criteria)
{
if (!\is_string($criteria) && !\is_array($criteria)) {
throw new \InvalidArgumentException(sprintf('Invalid type for criteria "order_by". Expect a "string" or an "array", got "%s".', get_debug_type($criteria)));
throw new \InvalidArgumentException(\sprintf('Invalid type for criteria "order_by". Expect a "string" or an "array", got "%s".', get_debug_type($criteria)));
}
foreach ((array) $criteria as $field => $direction) {
@@ -59,22 +59,22 @@ final class OrderByCriteria implements CriteriaInterface
}
if (!\is_string($field)) {
throw new \InvalidArgumentException(sprintf('Invalid Field value, must be "string", got "%s".', get_debug_type($field)));
throw new \InvalidArgumentException(\sprintf('Invalid Field value, must be "string", got "%s".', get_debug_type($field)));
}
if (!\is_string($direction)) {
throw new \InvalidArgumentException(sprintf('Invalid Direction value, must be "string", got "%s".', get_debug_type($direction)));
throw new \InvalidArgumentException(\sprintf('Invalid Direction value, must be "string", got "%s".', get_debug_type($direction)));
}
$direction = strtoupper($direction);
if (!\in_array($direction, [self::ASC, self::DESC], true)) {
throw new \InvalidArgumentException(sprintf('Invalid ordering direction: must be "ASC" or "DESC", got "%s".', $direction));
throw new \InvalidArgumentException(\sprintf('Invalid ordering direction: must be "ASC" or "DESC", got "%s".', $direction));
}
$field = $this->aliases[$field] ?? $field;
if (!is_a($field, StampInterface::class, true)) {
throw new \InvalidArgumentException(sprintf('Field "%s" is not a valid class-string of "%s".', $field, StampInterface::class));
throw new \InvalidArgumentException(\sprintf('Field "%s" is not a valid class-string of "%s".', $field, StampInterface::class));
}
$this->orderings[$field] = $direction;
@@ -19,7 +19,7 @@ trait RangeExtractor
private function extractRange(string $name, mixed $criteria): array
{
if (!\is_int($criteria) && !\is_array($criteria)) {
throw new \InvalidArgumentException(sprintf('Invalid type for criteria "%s". Expected int or array, got "%s".', $name, get_debug_type($criteria)));
throw new \InvalidArgumentException(\sprintf('Invalid type for criteria "%s". Expected int or array, got "%s".', $name, get_debug_type($criteria)));
}
if (\is_int($criteria)) {
@@ -30,11 +30,11 @@ trait RangeExtractor
$max = $criteria['max'] ?? null;
if (null !== $min && !\is_int($min)) {
throw new \InvalidArgumentException(sprintf('Invalid type for "min" in criteria "%s". Expected int, got "%s".', $name, get_debug_type($min)));
throw new \InvalidArgumentException(\sprintf('Invalid type for "min" in criteria "%s". Expected int, got "%s".', $name, get_debug_type($min)));
}
if (null !== $max && !\is_int($max)) {
throw new \InvalidArgumentException(sprintf('Invalid type for "max" in criteria "%s". Expected int, got "%s".', $name, get_debug_type($max)));
throw new \InvalidArgumentException(\sprintf('Invalid type for "max" in criteria "%s". Expected int, got "%s".', $name, get_debug_type($max)));
}
return ['min' => $min, 'max' => $max];
+1 -1
View File
@@ -71,7 +71,7 @@ final class FilterFactory implements FilterFactoryInterface
$criteria = \is_callable($criteria) ? $criteria($value) : $criteria;
if (!$criteria instanceof CriteriaInterface) {
throw new \UnexpectedValueException(sprintf('Expected an instance of "%s", got "%s" instead.', CriteriaInterface::class, get_debug_type($criteria)));
throw new \UnexpectedValueException(\sprintf('Expected an instance of "%s", got "%s" instead.', CriteriaInterface::class, get_debug_type($criteria)));
}
return $criteria;
+1 -1
View File
@@ -70,6 +70,6 @@ trait ForwardsCalls
*/
protected static function throwBadMethodCallException(string $method): never
{
throw new \BadMethodCallException(sprintf('Call to undefined method %s::%s()', static::class, $method));
throw new \BadMethodCallException(\sprintf('Call to undefined method %s::%s()', static::class, $method));
}
}
+5 -5
View File
@@ -56,7 +56,7 @@ trait Macroable
$macro = $method->invoke($mixin);
if (!\is_callable($macro) && !\is_object($macro)) {
throw new \InvalidArgumentException(sprintf('Expect the result of method %s::%s from the mixin object to be be a callable or an object, got "%s".', $mixin::class, $method->name, get_debug_type($macro)));
throw new \InvalidArgumentException(\sprintf('Expect the result of method %s::%s from the mixin object to be be a callable or an object, got "%s".', $mixin::class, $method->name, get_debug_type($macro)));
}
if ($replace || !static::hasMacro($method->name)) {
@@ -83,7 +83,7 @@ trait Macroable
public static function __callStatic(string $method, array $parameters): mixed
{
if (!static::hasMacro($method)) {
throw new \BadMethodCallException(sprintf('Method %s::%s does not exist.', static::class, $method));
throw new \BadMethodCallException(\sprintf('Method %s::%s does not exist.', static::class, $method));
}
$macro = static::$macros[$method];
@@ -93,7 +93,7 @@ trait Macroable
}
if (!\is_callable($macro)) {
throw new \BadMethodCallException(sprintf('Macro %s is not callable.', $method));
throw new \BadMethodCallException(\sprintf('Macro %s is not callable.', $method));
}
return $macro(...$parameters);
@@ -109,7 +109,7 @@ trait Macroable
public function __call(string $method, array $parameters): mixed
{
if (!static::hasMacro($method)) {
throw new \BadMethodCallException(sprintf('Method %s::%s does not exist.', static::class, $method));
throw new \BadMethodCallException(\sprintf('Method %s::%s does not exist.', static::class, $method));
}
$macro = static::$macros[$method];
@@ -119,7 +119,7 @@ trait Macroable
}
if (!\is_callable($macro)) {
throw new \BadMethodCallException(sprintf('Macro %s is not callable.', $method));
throw new \BadMethodCallException(\sprintf('Macro %s is not callable.', $method));
}
return $macro(...$parameters);
+1 -1
View File
@@ -9,7 +9,7 @@ final class PHPTemplateEngine implements TemplateEngineInterface
public function render(string $name, array $context = []): string
{
if (!file_exists($name) || !is_readable($name)) {
throw new \InvalidArgumentException(sprintf('Template file "%s" does not exist or is not readable.', $name));
throw new \InvalidArgumentException(\sprintf('Template file "%s" does not exist or is not readable.', $name));
}
ob_start();
+5 -5
View File
@@ -32,15 +32,15 @@ final class Notification extends Constraint
public function toString(): string
{
$details = [
sprintf('type: "%s"', $this->expectedType),
\sprintf('type: "%s"', $this->expectedType),
];
if (null !== $this->expectedMessage) {
$details[] = sprintf('message: "%s"', $this->expectedMessage);
$details[] = \sprintf('message: "%s"', $this->expectedMessage);
}
if (null !== $this->expectedTitle) {
$details[] = sprintf('title: "%s"', $this->expectedTitle);
$details[] = \sprintf('title: "%s"', $this->expectedTitle);
}
if (!empty($this->expectedOptions)) {
@@ -82,7 +82,7 @@ final class Notification extends Constraint
protected function failureDescription(mixed $other): string
{
$foundNotifications = array_map(function (NotificationInterface $notification) {
return sprintf(
return \sprintf(
'type: "%s", title: "%s", message: "%s", options: [%s]',
$notification->getType(),
$notification->getTitle(),
@@ -95,7 +95,7 @@ final class Notification extends Constraint
$foundNotifications[] = 'No notifications found';
}
return sprintf(
return \sprintf(
'Failed asserting that NotificationEvents %s. Found: [%s].',
$this->toString(),
implode('; ', $foundNotifications)
@@ -15,7 +15,7 @@ final class NotificationCount extends Constraint
public function toString(): string
{
return sprintf('matches the expected notification count of %d.', $this->expectedValue);
return \sprintf('matches the expected notification count of %d.', $this->expectedValue);
}
/**
@@ -45,7 +45,7 @@ final class NotificationCount extends Constraint
{
$actualCount = $this->countNotifications($other);
return sprintf('Expected the notification count to be %d, but got %d instead.', $this->expectedValue, $actualCount);
return \sprintf('Expected the notification count to be %d, but got %d instead.', $this->expectedValue, $actualCount);
}
/**
@@ -19,7 +19,7 @@ final class NotificationMessage extends Constraint
public function toString(): string
{
return sprintf('contains a notification with message "%s"', $this->expectedMessage);
return \sprintf('contains a notification with message "%s"', $this->expectedMessage);
}
protected function matches(mixed $other): bool
@@ -44,17 +44,17 @@ final class NotificationMessage extends Constraint
}
$foundMessages = array_map(function (NotificationInterface $notification) {
return sprintf('"%s"', $notification->getMessage());
return \sprintf('"%s"', $notification->getMessage());
}, $other->getNotifications());
if (empty($foundMessages)) {
return sprintf(
return \sprintf(
'Expected to find a notification with a message containing "%s", but no notifications were found.',
$this->expectedMessage
);
}
return sprintf(
return \sprintf(
'Expected to find a notification with a message containing "%s". Found messages: %s.',
$this->expectedMessage,
implode(', ', $foundMessages)
@@ -23,10 +23,10 @@ final class NotificationOption extends Constraint
public function toString(): string
{
$description = sprintf('contains a notification with an option "%s"', $this->expectedKey);
$description = \sprintf('contains a notification with an option "%s"', $this->expectedKey);
if ($this->expectedValue) {
$description .= sprintf(' having the value "%s"', json_encode($this->expectedValue));
$description .= \sprintf(' having the value "%s"', json_encode($this->expectedValue));
}
return $description;
@@ -50,7 +50,7 @@ final class NotificationOptions extends Constraint
$actualOptionsString = implode('; ', $actualOptions) ?: 'none found';
return sprintf(
return \sprintf(
'Failed asserting that NotificationEvents %s. Actual options in notifications: [%s].',
$this->toString(),
$actualOptionsString
@@ -22,7 +22,7 @@ final class NotificationTitle extends Constraint
public function toString(): string
{
return sprintf('contains a notification with a title containing "%s"', $this->expectedTitle);
return \sprintf('contains a notification with a title containing "%s"', $this->expectedTitle);
}
protected function matches(mixed $other): bool
@@ -47,17 +47,17 @@ final class NotificationTitle extends Constraint
}
$foundTitles = array_map(function (NotificationInterface $notification) {
return sprintf('"%s"', $notification->getTitle());
return \sprintf('"%s"', $notification->getTitle());
}, $other->getNotifications());
if (empty($foundTitles)) {
return sprintf(
return \sprintf(
'Expected to find a notification with a title containing "%s", but no notifications were found.',
$this->expectedTitle
);
}
return sprintf(
return \sprintf(
'Expected to find a notification with a title containing "%s". Found titles: %s.',
$this->expectedTitle,
implode(', ', $foundTitles)
@@ -23,7 +23,7 @@ final class NotificationType extends Constraint
public function toString(): string
{
return sprintf('contains a notification of type "%s".', $this->expectedType);
return \sprintf('contains a notification of type "%s".', $this->expectedType);
}
/**
@@ -65,7 +65,7 @@ final class NotificationType extends Constraint
$uniqueTypes = array_unique($actualTypes);
$typesList = implode(', ', $uniqueTypes);
return sprintf(
return \sprintf(
'Expected the NotificationEvents to contain a notification of type "%s", but found types: %s.',
$this->expectedType,
$typesList ?: 'none'
@@ -1,23 +0,0 @@
name: Auto Closer PR
on:
pull_request_target:
types: [ opened ]
jobs:
run:
name: 🤖 PR Auto-Closure
runs-on: ubuntu-latest
steps:
- uses: superbrothers/close-pull-request@v3
with:
comment: |
Hi there 👋,
First off, thanks for your effort! 🎉 Unfortunately, this repository is read-only because it's split from our primary monorepo repository.
🙏 We kindly ask if you could direct your valuable contribution to our main repository at https://github.com/php-flasher/php-flasher.
Once you've moved your contribution there, we'll review it and provide feedback. 🕵️‍♂️
Thanks again for your understanding and cooperation. We really appreciate it! 🙌
+6 -13
View File
@@ -5,26 +5,19 @@ declare(strict_types=1);
namespace Flasher\SweetAlert\Laravel\Facade;
use Flasher\Prime\Notification\Envelope;
use Flasher\Prime\Notification\NotificationInterface;
use Flasher\Prime\Stamp\StampInterface;
use Flasher\SweetAlert\Prime\SweetAlertBuilder;
use Illuminate\Support\Facades\Facade;
/**
* @method static SweetAlertBuilder addSuccess(string $message, array $options = array())
* @method static SweetAlertBuilder addError(string $message, array $options = array())
* @method static SweetAlertBuilder addWarning(string $message, array $options = array())
* @method static SweetAlertBuilder addInfo(string $message, array $options = array())
* @method static SweetAlertBuilder addFlash(NotificationInterface|string $type, string $message = null, array $options = array())
* @method static SweetAlertBuilder success(string $message, array<string, mixed> $options = array())
* @method static SweetAlertBuilder error(string $message, array<string, mixed> $options = array())
* @method static SweetAlertBuilder warning(string $message, array<string, mixed> $options = array())
* @method static SweetAlertBuilder info(string $message, array<string, mixed> $options = array())
* @method static SweetAlertBuilder flash(StampInterface[] $stamps = array())
* @method static SweetAlertBuilder type(string $type, string $message = null, array $options = array())
* @method static SweetAlertBuilder message(string $message)
* @method static SweetAlertBuilder options(array $options, bool $merge = true)
* @method static SweetAlertBuilder options(array<string, mixed> $options, bool $merge = true)
* @method static SweetAlertBuilder option(string $name, string $value)
* @method static SweetAlertBuilder success(string $message = null, array $options = array())
* @method static SweetAlertBuilder error(string $message = null, array $options = array())
* @method static SweetAlertBuilder info(string $message = null, array $options = array())
* @method static SweetAlertBuilder warning(string $message = null, array $options = array())
* @method static SweetAlertBuilder priority(int $priority)
* @method static SweetAlertBuilder hops(int $amount)
* @method static SweetAlertBuilder keep()
@@ -34,7 +27,7 @@ use Illuminate\Support\Facades\Facade;
* @method static SweetAlertBuilder withStamp(StampInterface $stamp)
* @method static SweetAlertBuilder handler(string $handler)
* @method static Envelope getEnvelope()
* @method static SweetAlertBuilder question(string $message = null, array $options = array())
* @method static SweetAlertBuilder question(string $message = null, array<string, mixed> $options = array())
* @method static SweetAlertBuilder title(string $title)
* @method static SweetAlertBuilder titleText(string $titleText)
* @method static SweetAlertBuilder html(string $html)
-23
View File
@@ -1,23 +0,0 @@
name: Auto Closer PR
on:
pull_request_target:
types: [ opened ]
jobs:
run:
name: 🤖 PR Auto-Closure
runs-on: ubuntu-latest
steps:
- uses: superbrothers/close-pull-request@v3
with:
comment: |
Hi there 👋,
First off, thanks for your effort! 🎉 Unfortunately, this repository is read-only because it's split from our primary monorepo repository.
🙏 We kindly ask if you could direct your valuable contribution to our main repository at https://github.com/php-flasher/php-flasher.
Once you've moved your contribution there, we'll review it and provide feedback. 🕵️‍♂️
Thanks again for your understanding and cooperation. We really appreciate it! 🙌
@@ -1,23 +0,0 @@
name: Auto Closer PR
on:
pull_request_target:
types: [ opened ]
jobs:
run:
name: 🤖 PR Auto-Closure
runs-on: ubuntu-latest
steps:
- uses: superbrothers/close-pull-request@v3
with:
comment: |
Hi there 👋,
First off, thanks for your effort! 🎉 Unfortunately, this repository is read-only because it's split from our primary monorepo repository.
🙏 We kindly ask if you could direct your valuable contribution to our main repository at https://github.com/php-flasher/php-flasher.
Once you've moved your contribution there, we'll review it and provide feedback. 🕵️‍♂️
Thanks again for your understanding and cooperation. We really appreciate it! 🙌
-23
View File
@@ -1,23 +0,0 @@
name: Auto Closer PR
on:
pull_request_target:
types: [ opened ]
jobs:
run:
name: 🤖 PR Auto-Closure
runs-on: ubuntu-latest
steps:
- uses: superbrothers/close-pull-request@v3
with:
comment: |
Hi there 👋,
First off, thanks for your effort! 🎉 Unfortunately, this repository is read-only because it's split from our primary monorepo repository.
🙏 We kindly ask if you could direct your valuable contribution to our main repository at https://github.com/php-flasher/php-flasher.
Once you've moved your contribution there, we'll review it and provide feedback. 🕵️‍♂️
Thanks again for your understanding and cooperation. We really appreciate it! 🙌
+4 -4
View File
@@ -93,12 +93,12 @@ final class InstallCommand extends Command
$this->publishConfig($plugin, $configDir, $configFile);
}
$status = sprintf('<fg=green;options=bold>%s</>', '\\' === \DIRECTORY_SEPARATOR ? 'OK' : "\xE2\x9C\x94" /* HEAVY CHECK MARK (U+2714) */);
$output->writeln(sprintf(' %s <fg=blue;options=bold>%s</>', $status, $plugin->getAlias()));
$status = \sprintf('<fg=green;options=bold>%s</>', '\\' === \DIRECTORY_SEPARATOR ? 'OK' : "\xE2\x9C\x94" /* HEAVY CHECK MARK (U+2714) */);
$output->writeln(\sprintf(' %s <fg=blue;options=bold>%s</>', $status, $plugin->getAlias()));
} catch (\Exception $e) {
$exitCode = self::FAILURE;
$status = sprintf('<fg=red;options=bold>%s</>', '\\' === \DIRECTORY_SEPARATOR ? 'ERROR' : "\xE2\x9C\x98" /* HEAVY BALLOT X (U+2718) */);
$output->writeln(sprintf(' %s <fg=blue;options=bold>%s</> <error>%s</error>', $status, $plugin->getAlias(), $e->getMessage()));
$status = \sprintf('<fg=red;options=bold>%s</>', '\\' === \DIRECTORY_SEPARATOR ? 'ERROR' : "\xE2\x9C\x98" /* HEAVY BALLOT X (U+2718) */);
$output->writeln(\sprintf(' %s <fg=blue;options=bold>%s</> <error>%s</error>', $status, $plugin->getAlias(), $e->getMessage()));
}
}
+6
View File
@@ -15,6 +15,12 @@ flasher:
# Automatically inject PHPFlasher assets in HTML response
inject_assets: true
# Global options
options:
# timeout in milliseconds
timeout: 5000
position: 'top-right'
# Map Symfony session keys to PHPFlasher notification types
flash_bag:
success: ['success']
-23
View File
@@ -1,23 +0,0 @@
name: Auto Closer PR
on:
pull_request_target:
types: [ opened ]
jobs:
run:
name: 🤖 PR Auto-Closure
runs-on: ubuntu-latest
steps:
- uses: superbrothers/close-pull-request@v3
with:
comment: |
Hi there 👋,
First off, thanks for your effort! 🎉 Unfortunately, this repository is read-only because it's split from our primary monorepo repository.
🙏 We kindly ask if you could direct your valuable contribution to our main repository at https://github.com/php-flasher/php-flasher.
Once you've moved your contribution there, we'll review it and provide feedback. 🕵️‍♂️
Thanks again for your understanding and cooperation. We really appreciate it! 🙌
+6 -6
View File
@@ -11,14 +11,14 @@ use Illuminate\Support\Facades\Facade;
/**
* @method static ToastrBuilder flash(StampInterface[] $stamps = array())
* @method static ToastrBuilder type(string $type, string $message = null, array $options = array())
* @method static ToastrBuilder type(string $type, string $message = null, array<string, mixed> $options = array())
* @method static ToastrBuilder message(string $message)
* @method static ToastrBuilder options(array $options, bool $merge = true)
* @method static ToastrBuilder options(array<string, mixed> $options, bool $merge = true)
* @method static ToastrBuilder option(string $name, $value)
* @method static ToastrBuilder success(string $message = null, array $options = array())
* @method static ToastrBuilder error(string $message = null, array $options = array())
* @method static ToastrBuilder info(string $message = null, array $options = array())
* @method static ToastrBuilder warning(string $message = null, array $options = array())
* @method static ToastrBuilder success(string $message = null, array<string, mixed> $options = array())
* @method static ToastrBuilder error(string $message = null, array<string, mixed> $options = array())
* @method static ToastrBuilder info(string $message = null, array<string, mixed> $options = array())
* @method static ToastrBuilder warning(string $message = null, array<string, mixed> $options = array())
* @method static ToastrBuilder priority(int $priority)
* @method static ToastrBuilder hops(int $amount)
* @method static ToastrBuilder keep()
-23
View File
@@ -1,23 +0,0 @@
name: Auto Closer PR
on:
pull_request_target:
types: [ opened ]
jobs:
run:
name: 🤖 PR Auto-Closure
runs-on: ubuntu-latest
steps:
- uses: superbrothers/close-pull-request@v3
with:
comment: |
Hi there 👋,
First off, thanks for your effort! 🎉 Unfortunately, this repository is read-only because it's split from our primary monorepo repository.
🙏 We kindly ask if you could direct your valuable contribution to our main repository at https://github.com/php-flasher/php-flasher.
Once you've moved your contribution there, we'll review it and provide feedback. 🕵️‍♂️
Thanks again for your understanding and cooperation. We really appreciate it! 🙌
-23
View File
@@ -1,23 +0,0 @@
name: Auto Closer PR
on:
pull_request_target:
types: [ opened ]
jobs:
run:
name: 🤖 PR Auto-Closure
runs-on: ubuntu-latest
steps:
- uses: superbrothers/close-pull-request@v3
with:
comment: |
Hi there 👋,
First off, thanks for your effort! 🎉 Unfortunately, this repository is read-only because it's split from our primary monorepo repository.
🙏 We kindly ask if you could direct your valuable contribution to our main repository at https://github.com/php-flasher/php-flasher.
Once you've moved your contribution there, we'll review it and provide feedback. 🕵️‍♂️
Thanks again for your understanding and cooperation. We really appreciate it! 🙌
+2 -2
View File
@@ -29,8 +29,8 @@ tasks:
lint:
desc: "🔍 Run various linting tools to ensure code quality."
cmds:
- vendor/bin/php-cs-fixer fix --dry-run
- vendor/bin/phpstan analyse
- vendor/bin/php-cs-fixer fix
- vendor/bin/phpstan analyse --memory-limit=-1
- composer validate --strict
- vendor/bin/phplint
- find src/ -name "composer.json" -exec composer validate --strict {} \;
@@ -21,6 +21,8 @@ final class FlasherComponentTest extends TestCase
protected function setUp(): void
{
parent::setUp();
$flasherServiceMock = \Mockery::mock(FlasherInterface::class);
$flasherServiceMock->allows('render')
->andReturns('Your expected result');
+2
View File
@@ -19,6 +19,8 @@ final class RequestTest extends TestCase
protected function setUp(): void
{
parent::setUp();
$this->laravelRequestMock = \Mockery::mock(LaravelRequest::class);
}
+2
View File
@@ -21,6 +21,8 @@ final class ResponseTest extends TestCase
protected function setUp(): void
{
parent::setUp();
$this->responseHeaderBagMock = \Mockery::mock(ResponseHeaderBag::class);
$this->responseMock = \Mockery::mock(LaravelResponse::class);
@@ -24,6 +24,8 @@ final class FlasherMiddlewareTest extends TestCase
protected function setUp(): void
{
parent::setUp();
$this->responseExtensionMock = \Mockery::mock(ResponseExtensionInterface::class);
$this->middleware = new FlasherMiddleware($this->responseExtensionMock);
}
@@ -30,6 +30,8 @@ final class SessionMiddlewareTest extends TestCase
protected function setUp(): void
{
parent::setUp();
$this->requestExtensionMock = \Mockery::mock(RequestExtensionInterface::class);
$this->sessionMiddleware = new SessionMiddleware($this->requestExtensionMock);
}
@@ -69,7 +71,7 @@ final class SessionMiddlewareTest extends TestCase
$requestMock = \Mockery::mock(LaravelRequest::class);
$responseMock = \Mockery::mock(\Symfony\Component\HttpFoundation\Response::class);
$this->requestExtensionMock->allows('flash')->never();
$this->requestExtensionMock->allows('flash')->once();
$handle = $this->sessionMiddleware->handle($requestMock, fn () => $responseMock);
+83 -21
View File
@@ -4,40 +4,102 @@ declare(strict_types=1);
namespace Flasher\Tests\Laravel;
use Flasher\Laravel\Middleware\FlasherMiddleware;
use Flasher\Laravel\Middleware\SessionMiddleware;
use Flasher\Prime\FlasherInterface;
use Illuminate\Foundation\Application;
use Orchestra\Testbench\Attributes\DefineEnvironment;
use PHPUnit\Framework\Attributes\DataProvider;
final class ServiceProviderTest extends TestCase
{
public function testContainerContainServices(): void
/**
* @param class-string<object> $class
*/
#[DataProvider('servicesDataProvider')]
public function testContainerContainServices(string $service, string $class): void
{
$this->assertTrue($this->app->bound('flasher'));
$this->assertTrue($this->app->bound('flasher.noty'));
$this->assertTrue($this->app->bound('flasher.notyf'));
$this->assertTrue($this->app->bound('flasher.sweetalert'));
$this->assertTrue($this->app->bound('flasher.toastr'));
$this->assertInstanceOf(\Flasher\Prime\Flasher::class, $this->app->make('flasher'));
$this->assertInstanceOf(\Flasher\Noty\Prime\Noty::class, $this->app->make('flasher.noty'));
$this->assertInstanceOf(\Flasher\Notyf\Prime\Notyf::class, $this->app->make('flasher.notyf'));
$this->assertInstanceOf(\Flasher\SweetAlert\Prime\SweetAlert::class, $this->app->make('flasher.sweetalert'));
$this->assertInstanceOf(\Flasher\Toastr\Prime\Toastr::class, $this->app->make('flasher.toastr'));
$this->assertTrue($this->app->bound($service));
$this->assertInstanceOf($class, $this->app->make($service));
}
public function testFlasherCanCreateServicesFromAlias(): void
/**
* @param class-string<object> $expectedClass
*/
#[DataProvider('flasherAdapterProvider')]
public function testFlasherCanCreateServicesFromAlias(string $alias, string $expectedClass): void
{
/** @var FlasherInterface $flasher */
$flasher = $this->app->make('flasher');
$adapter = $flasher->use('noty');
$this->assertInstanceOf(\Flasher\Noty\Prime\Noty::class, $adapter);
$adapter = $flasher->use($alias);
$this->assertInstanceOf($expectedClass, $adapter);
}
$adapter = $flasher->use('notyf');
$this->assertInstanceOf(\Flasher\Notyf\Prime\Notyf::class, $adapter);
public function testMiddlewareIsRegistered(): void
{
$this->assertTrue($this->hasMiddleware(FlasherMiddleware::class));
$this->assertTrue($this->hasMiddleware(SessionMiddleware::class));
}
$adapter = $flasher->use('sweetalert');
$this->assertInstanceOf(\Flasher\SweetAlert\Prime\SweetAlert::class, $adapter);
#[DefineEnvironment('disableInjectAssets')]
public function testFlasherMiddlewareDisabled(): void
{
$this->assertFalse($this->app->bound(FlasherMiddleware::class));
$this->assertFalse($this->hasMiddleware(FlasherMiddleware::class));
}
$adapter = $flasher->use('toastr');
$this->assertInstanceOf(\Flasher\Toastr\Prime\Toastr::class, $adapter);
#[DefineEnvironment('disableFlashBag')]
public function testSessionMiddlewareDisabled(): void
{
$this->assertFalse($this->app->bound(SessionMiddleware::class));
$this->assertFalse($this->hasMiddleware(SessionMiddleware::class));
}
private function hasMiddleware(string $middleware): bool
{
$kernel = $this->app->make(\Illuminate\Foundation\Http\Kernel::class);
$middlewares = $kernel->getMiddlewareGroups()['web'];
return \in_array($middleware, $middlewares);
}
/**
* @return array<array<string>>
*/
public static function servicesDataProvider(): array
{
return [
['flasher', \Flasher\Prime\Flasher::class],
['flasher.noty', \Flasher\Noty\Prime\Noty::class],
['flasher.notyf', \Flasher\Notyf\Prime\Notyf::class],
['flasher.sweetalert', \Flasher\SweetAlert\Prime\SweetAlert::class],
['flasher.toastr', \Flasher\Toastr\Prime\Toastr::class],
[FlasherMiddleware::class, FlasherMiddleware::class],
[SessionMiddleware::class, SessionMiddleware::class],
];
}
/**
* @return array<array<string>>
*/
public static function flasherAdapterProvider(): array
{
return [
['noty', \Flasher\Noty\Prime\Noty::class],
['notyf', \Flasher\Notyf\Prime\Notyf::class],
['sweetalert', \Flasher\SweetAlert\Prime\SweetAlert::class],
['toastr', \Flasher\Toastr\Prime\Toastr::class],
];
}
protected function disableInjectAssets(Application $app): void
{
$app['config']->set('flasher.inject_assets', false);
}
protected function disableFlashBag(Application $app): void
{
$app['config']->set('flasher.flash_bag', false);
}
}

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