├── .devcontainer
└── devcontainer.json
├── .editorconfig
├── .github
├── FUNDING.yml
├── ISSUE_TEMPLATE
├── dependabot.yml
└── workflows
│ └── laravel.yml
├── .gitignore
├── .travis.yml
├── .vscode
└── settings.json
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── ISSUE_TEMPLATE.md
├── LICENSE
├── README.md
├── caffeine.jpg
├── composer.json
├── config
├── .gitkeep
└── genealabs-laravel-caffeine.php
├── docker-compose.yml
├── phpunit.xml
├── resources
└── views
│ └── script.blade.php
├── routes
└── web.php
├── src
├── Console
│ └── Commands
│ │ └── Publish.php
├── Dripper.php
├── Http
│ ├── Controllers
│ │ └── Drip.php
│ └── Middleware
│ │ └── LaravelCaffeineDripMiddleware.php
└── Providers
│ └── Service.php
└── tests
├── CreatesApplication.php
├── Feature
└── CaffeineTest.php
├── FeatureTestCase.php
├── Fixtures
├── expired_script.txt
├── partial_script.txt
└── unexpired_script.txt
├── Http
└── Controllers
│ └── Test.php
├── Unit
├── Console
│ └── Commands
│ │ └── PublishTest.php
└── DripperTest.php
├── UnitTestCase.php
├── resources
└── views
│ └── tests
│ ├── disabled.blade.php
│ ├── form.blade.php
│ └── layout.blade.php
└── routes
└── web.php
/.devcontainer/devcontainer.json:
--------------------------------------------------------------------------------
1 | // https://aka.ms/devcontainer.json
2 | {
3 | "name": "Existing Docker Compose (Extend)",
4 | "dockerComposeFile": [
5 | "../docker-compose.yml"
6 | ],
7 | "features": {
8 | "ghcr.io/devcontainers/features/sshd:1": {
9 | "version": "latest"
10 | }
11 | },
12 | "service": "laravel.test",
13 | "workspaceFolder": "/var/www/html",
14 | "customizations": {
15 | "vscode": {
16 | "settings": {},
17 | "extensions": [
18 | "aaron-bond.better-comments",
19 | "adrianwilczynski.alpine-js-intellisense",
20 | "AlexArthurs.todo-pusher",
21 | "amiralizadeh9480.laravel-extra-intellisense",
22 | "austenc.laravel-blade-spacer",
23 | "beyondcode.tinkerwell",
24 | "bmewburn.vscode-intelephense-client",
25 | "bradlc.vscode-tailwindcss",
26 | "christian-kohler.npm-intellisense",
27 | "christian-kohler.path-intellisense",
28 | "cierra.livewire-vscode",
29 | "codecov.codecov",
30 | "codingyu.laravel-goto-view",
31 | "davidanson.vscode-markdownlint",
32 | "davidbwaters.macos-modern-theme",
33 | "eamodio.gitlens",
34 | "editorconfig.editorconfig",
35 | "ericcheng.codesongclear",
36 | "faelv.composer-companion",
37 | "file-icons.file-icons",
38 | "foxundermoon.shell-format",
39 | "georgykurian.laravel-ide-helper",
40 | "github.codespaces",
41 | "GitHub.copilot-chat",
42 | "GitHub.copilot-nightly",
43 | "GitHub.copilot",
44 | "github.vscode-github-actions",
45 | "github.vscode-pull-request-github",
46 | "Gruntfuggly.todo-tree",
47 | "heissenbergerlab.php-array-from-json",
48 | "heybourn.headwind",
49 | "huibizhang.codesnap-plus",
50 | "irongeek.vscode-env",
51 | "kencocaceo.customvscodeuicss",
52 | "m4ns0ur.base64",
53 | "maciejdems.add-to-gitignore",
54 | "mahmoudshahin.laravel-routes",
55 | "markis.code-coverage",
56 | "martybegood.single-editor-tabs",
57 | "mechatroner.rainbow-csv",
58 | "mehedidracula.php-namespace-resolver",
59 | "mhutchie.git-graph",
60 | "mikestead.dotenv",
61 | "mohamedbenhida.laravel-intellisense",
62 | "mrmlnc.vscode-duplicate",
63 | "naoray.laravel-goto-components",
64 | "oderwat.indent-rainbow",
65 | "pcbowers.alpine-intellisense",
66 | "recca0120.vscode-phpunit",
67 | "redhat.vscode-yaml",
68 | "rifi2k.format-html-in-php",
69 | "shevaua.phpcs",
70 | "shufo.vscode-blade-formatter",
71 | "sperovita.alpinejs-syntax-highlight",
72 | "streetsidesoftware.code-spell-checker",
73 | "syler.ignore",
74 | "teabyii.ayu",
75 | "usernamehw.errorlens",
76 | "vincaslt.highlight-matching-tag",
77 | "WakaTime.vscode-wakatime",
78 | "withfig.fig",
79 | "xdebug.php-debug"
80 | ]
81 | }
82 | },
83 | "remoteUser": "sail",
84 | "postCreateCommand": "sudo chown -R 1000:1000 /var/www/html",
85 | "forwardPorts": [
86 | 80,
87 | 5432,
88 | 6001,
89 | 8025,
90 | 8900,
91 | 9000
92 | ],
93 | "portsAttributes": {
94 | "80": {
95 | "label": "HTTP"
96 | },
97 | "5432": {
98 | "label": "Postgres"
99 | },
100 | "6001": {
101 | "label": "Web Sockets"
102 | },
103 | "8025": {
104 | "label": "MailHog"
105 | },
106 | "8900": {
107 | "label": "Minio Console"
108 | },
109 | "9000": {
110 | "label": "Minio Host"
111 | }
112 | },
113 | "mounts": [
114 | "source=${localEnv:HOME}/.wakatime.cfg,target=/home/sail/.wakatime.cfg,type=bind,consistency=delegated"
115 | ]
116 | // "runServices": [],
117 | // "shutdownAction": "none",
118 | }
119 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | end_of_line = lf
6 | insert_final_newline = true
7 | indent_style = space
8 | indent_size = 4
9 | trim_trailing_whitespace = true
10 |
11 | [*.md]
12 | trim_trailing_whitespace = false
13 | indent_size = 2
14 |
15 | [*.{yml,yaml}]
16 | indent_size = 2
17 |
18 | [.blackfire.yaml]
19 | indent_size = 4
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: [mikebronner]
4 | patreon: # mikebronner
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
13 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE:
--------------------------------------------------------------------------------
1 | ## Expected Behavior
2 |
3 | ## Actual Behavior
4 |
5 | ## Environment
6 | - PHP Version:
7 | - Laravel Version:
8 | - LaravelCaffeine Version:
9 |
10 | ## Stack Trace
11 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | registries:
3 | git-nova-laravel-com:
4 | type: git
5 | url: https://nova.laravel.com
6 | username: mike@genealabs.com
7 | password: "${{secrets.GIT_NOVA_LARAVEL_COM_PASSWORD}}"
8 |
9 | updates:
10 | - package-ecosystem: composer
11 | directory: "/"
12 | schedule:
13 | interval: daily
14 | time: "13:00"
15 | open-pull-requests-limit: 10
16 | registries:
17 | - git-nova-laravel-com
18 |
--------------------------------------------------------------------------------
/.github/workflows/laravel.yml:
--------------------------------------------------------------------------------
1 | name: Laravel Package
2 |
3 | on:
4 | push:
5 | branches: [ master ]
6 | pull_request:
7 | branches: [ master ]
8 |
9 | jobs:
10 | laravel-tests:
11 |
12 | runs-on: ubuntu-latest
13 |
14 | strategy:
15 | fail-fast: true
16 | matrix:
17 | php: [8.3, 8.2]
18 |
19 | name: PHP ${{ matrix.php }}
20 |
21 | steps:
22 | - name: Checkout code
23 | uses: actions/checkout@v3
24 |
25 | - name: Cache dependencies
26 | uses: actions/cache@v4
27 | with:
28 | path: ~/.composer/cache/files
29 | key: dependencies-php-${{ matrix.php }}-composer-${{ hashFiles('composer.json') }}
30 |
31 | - name: Setup PHP ${{ matrix.php }}
32 | uses: shivammathur/setup-php@v2
33 | with:
34 | php-version: ${{ matrix.php }}
35 | extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, gd, pgsql, pdo_pgsql
36 | coverage: none
37 |
38 | - name: Install Dependencies
39 | run: |
40 | composer install -q --no-ansi --no-interaction --no-scripts --no-suggest --no-progress --prefer-dist
41 |
42 | - name: Execute Integration and Feature tests via PHPUnit
43 | run: vendor/bin/phpunit --configuration phpunit.xml --testsuite Integration,Feature
44 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .phpunit.result.cache
2 | .phpunit.cache
3 | /tests/Browser/console
4 | /tests/Browser/screenshots
5 | /vendor
6 | composer.lock
7 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | dist: trusty
2 | language: php
3 | sudo: required
4 |
5 | addons:
6 | chrome: stable
7 |
8 | php:
9 | - 7.2
10 | - 7.3
11 | - 8.1
12 | - 8.2
13 |
14 | before_script:
15 | - travis_retry composer self-update
16 | - travis_retry composer install --no-interaction --dev --prefer-dist --no-suggest
17 | - google-chrome-stable --headless --disable-gpu --remote-debugging-port=9222 http://localhost &
18 |
19 | script:
20 | - ./vendor/bin/phpunit --coverage-text --coverage-clover ./build/logs/clover.xml
21 |
22 | after_script:
23 | - php vendor/bin/coveralls
24 | - wget https://scrutinizer-ci.com/ocular.phar
25 | - php ocular.phar code-coverage:upload --format=php-clover ./build/logs/clover.xml
26 |
27 | notifications:
28 | webhooks:
29 | urls:
30 | - https://webhooks.gitter.im/e/30886f28c25b1e31088f
31 | on_success: change # options: [always|never|change] default: always
32 | on_failure: always # options: [always|never|change] default: always
33 | on_start: never # options: [always|never|change] default: always
34 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "cSpell.words": [
3 | "autoload",
4 | "autoloader",
5 | "Bronner",
6 | "classmap",
7 | "Genea",
8 | "genealabs",
9 | "jenssegers",
10 | "laravel",
11 | "Laravel",
12 | "phpmd",
13 | "phpunit",
14 | "testbench"
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 |
3 | ## [7.0.2] - 2020-03-11
4 | ### Fixed
5 | - problems with DOM parsing and reverted back to RegExp.
6 |
7 | ## [7.0.1] - 2020-03-06
8 | ### Updated
9 | - dependencies for Laravel 7 compatibility, removed temp dependencies.
10 |
11 | ## [7.0.0] - 2020-02-29
12 | ### Added
13 | - Laravel 7 compatibility.
14 |
15 | ### Fixed
16 | - asset insertion functionality.
17 |
18 | ## [1.0.5] - 2019-11-28
19 | ### Updated
20 | - readme with Voyager incompatibility warning and suggested work-around.
21 |
22 | ## [1.0.4] - 2019-10-08
23 | ### Fixed
24 | - commits not being applied to previous release.
25 |
26 | ## [1.0.3] - 2019-10-08
27 | ### Updated
28 | - dependency compatibilies.
29 |
30 | ## [1.0] - 2019-09-05
31 | ### Added
32 | - Laravel 6.0 compatibility.
33 |
34 | ### Removed
35 | - compatibility with older versions of Laravel.
36 |
37 | ## [0.8.3] - 2019-06-30
38 | ### Added
39 | - support for Spatie's `laravel-csp` package.
40 |
41 | ## [0.8.2] - 2019-06-30
42 | ### Changed
43 | - method of checking registered middleware groups to use `hasMiddlewareGroup()`.
44 |
45 | ## [0.6.12] - 5 Aug 2018
46 | ### Fixed
47 | - middleware response to be a view instead of string. Thanks @dallincoons, #96 #95.
48 |
49 | ## [0.6.11] - 13 May 2018
50 | ### Fixed
51 | - regexp to be simpler. Thanks @juandi, #92.
52 | - `app_env` (to `internaltesting`) to avoid testing conflicts. Thanks @agjino, #82.
53 |
54 | ## [0.6.10] - 13 May 2018
55 | ### Fixed
56 | - erroneous `const` in JavaScript, changed to `var`. Thanks @netpok, #86.
57 |
58 | ## [0.6.9] - 13 May 2018
59 | ### Fixed
60 | - erroneous `let` in JavaScript, changed to `var`. Thanks @spaceemotion, #94.
61 |
62 | ## [0.6.8] - 15 Feb 2018
63 | ### Fixed
64 | - dependency versions to allow installation on earlier versions of Laravel.
65 |
66 | ## [0.6.7] - 9 Feb 2018
67 | ### Added
68 | - Laravel 5.6 compatibility.
69 |
70 | ## [0.6.6] - 9 Jan 2018
71 | ### Changed
72 | - testing to use orchestral/testbench suite.
73 |
74 | ## [0.6.5] - 5 Jan 2018
75 | ### Added
76 | - Laravel 5.6 compatibility.
77 |
78 | ## [0.6.6] - 9 Feb 2018
79 | ### Changed
80 | - tests to use `orchestral/testbench` suite.
81 |
82 | ## [0.6.5] - 5 Jan 2018
83 | ### Added
84 | - `thanks` package.
85 |
86 | ### Updated
87 | - documentation and change-log.
88 |
89 | ## [0.6.4] - 5 Jan 2018
90 | ### Fixed
91 | - composer dependency version constraints (only Laravel 5.4 and 5.5 have been tested).
92 |
93 | ## [0.6.3] - 14 Dec 2017
94 | ### Fixed
95 | - middleware registration to detect apache server.
96 |
97 | ## [0.6.2] - 11 Dec 2017
98 | ### Added
99 | - route middleware functionality.
100 |
101 | ### Changed
102 | - config variable to `outdated-drip-check-interval`.
103 |
104 | ### Fixed
105 | - naming of config setting `drip-interval`.
106 | - formatting of script fixture.
107 |
108 | ## [0.6.1] - 10 Dec 2017
109 | ### Added
110 | - ability to exclude a page from caffinating the application via meta tag.
111 |
112 | ## [0.6.0] - 9 Dec 2017
113 | ### Added
114 | - drip timeout check and force page refresh if timeout occurred.
115 |
116 | ### Changed
117 | - config file setting names to be more explicit.
118 | - middleware is injected only when called from a web page or during testing.
119 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
6 |
7 | ## Our Standards
8 |
9 | Examples of behavior that contributes to creating a positive environment include:
10 |
11 | * Using welcoming and inclusive language
12 | * Being respectful of differing viewpoints and experiences
13 | * Gracefully accepting constructive criticism
14 | * Focusing on what is best for the community
15 | * Showing empathy towards other community members
16 |
17 | Examples of unacceptable behavior by participants include:
18 |
19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances
20 | * Trolling, insulting/derogatory comments, and personal or political attacks
21 | * Public or private harassment
22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission
23 | * Other conduct which could reasonably be considered inappropriate in a professional setting
24 |
25 | ## Our Responsibilities
26 |
27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
28 |
29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
30 |
31 | ## Scope
32 |
33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
34 |
35 | ## Enforcement
36 |
37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at hello@genealabs.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
38 |
39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
40 |
41 | ## Attribution
42 |
43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
44 |
45 | [homepage]: http://contributor-covenant.org
46 | [version]: http://contributor-covenant.org/version/1/4/
47 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # How to contribute
2 | We welcome everyone to submit pull requests with:
3 | - fixes for issues
4 | - change suggestions
5 | - updateing of documentation
6 |
7 | However, not every pull request will automatically be accepted. I will review each carefully to make sure it is in line with
8 | the direction I want the package to continue in. This might mean that some pull requests are not accepted, or might stay
9 | unmerged until a place for them can be determined.
10 |
11 | ## Testing
12 | - [ ] After making your changes, make sure the tests still pass.
13 | - [ ] When adding new functionality, also add new tests.
14 | - [ ] Make sure there are no build errors on our CI server (https://ci.genealabs.com/build-status/view/6)
15 | - [ ] All code must past PHPCS and PHPMD PSR2 validation.
16 |
17 | ## Submitting changes
18 | When submitting a pull request, it is important to make sure to complete the following:
19 | - [ ] Add a descriptive header that explains in a single scentence what problem the PR solves.
20 | - [ ] Add a detailed description with animated screengrab GIFs vidualizing how it works.
21 | - [ ] Explain why you think it should be implemented one way vs. another, highlight performance improvements, etc.
22 |
23 | ## Coding conventions
24 | Start reading our code and you'll get the hang of it. We optimize for readability:
25 | - indent using four spaces (soft tabs)
26 | - use Blade for all views
27 | - avoid logic in views, put it in controllers or service classes
28 | - ALWAYS put spaces after list items and method parameters (`[1, 2, 3]`, not `[1,2,3]`), around operators (`x += 1`, not `x+=1`), and around hash arrows.
29 | - this is open source software. Consider the people who will read your code, and make it look nice for them. It's sort of like driving a car: Perhaps you love doing donuts when you're alone, but with passengers the goal is to make the ride as smooth as possible.
30 | - emphasis readability of code over patterns to reduce mental debt
31 | - always add an empty line around structures (if statements, loops, etc.)
32 |
33 | Thanks!
34 | Mike Bronner, GeneaLabs
35 |
--------------------------------------------------------------------------------
/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | # Issue
2 | *summarize your issue here*
3 |
4 | ## Environment
5 | Laravel Version: *x.y.z*
6 | Laravel Caffeine Package Version: *x.y.z*
7 | PHP Version: *x.y.z*
8 | Homestead Version: *x.y*
9 |
10 | ## Stack Trace
11 | - [ ] I have cleared my Laravel log file.
12 | - [ ] I have then reproduced my issue.
13 | - [ ] I have copied the __first__ listed stack trace from the fresh log file.
14 |
15 | ```
16 | *paste the first stack trace here*
17 | ```
18 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 - 2017 GeneaLabs, LLC
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Caffeine for Laravel
2 | [](https://travis-ci.org/GeneaLabs/laravel-caffeine)
3 | [](https://scrutinizer-ci.com/g/GeneaLabs/laravel-caffeine)
4 | [](https://coveralls.io/github/GeneaLabs/laravel-caffeine)
5 | [](https://github.com/GeneaLabs/laravel-caffeine)
6 | [](https://packagist.org/packages/genealabs/laravel-caffeine)
7 |
8 | 
9 |
10 | ## Supporting This Package
11 | This is an MIT-licensed open source project with its ongoing development made possible by the support of the community. If you'd like to support this, and our other packages, please consider [becoming a sponsor](https://github.com/sponsors/mikebronner).
12 |
13 | We thank the following sponsors for their generosity. Please take a moment to check them out:
14 |
15 | - [LIX](https://lix-it.com)
16 |
17 | ## Goal
18 | Prevent forms from timing out when submitting them after leaving them on-screen
19 | for a considerable amount of time. (Laravel defaults to 120 minutes, but that
20 | is configurable and could be different site-by-site.)
21 |
22 | ## Implementation
23 | To achieve this, we are sending a caffeine-drip (a request at regular intervals)
24 | to keep the session from timing out.
25 | This is only implemented on pages with a `_token` field, so all other pages will
26 | time-out as normal.
27 |
28 | ## Reasoning
29 | I chose this approach to keep the integrity of site-security, by avoiding the
30 | following:
31 | - exposing the CSRF Token on an unsecured endpoint.
32 | - eliminating CSRF Token validation on specific routes, or even altogether.
33 | - removing session-timeout on all pages.
34 |
35 | ## Considerations
36 | ### Incompatible Packages
37 | - [Voyager](https://github.com/the-control-group/voyager) has been reported as
38 | being incompatible. To work around this, configure Caffeine to use
39 | route-based middleware on all non-Voyager routes. See details below for
40 | configuration and implementation of route-based middleware.
41 |
42 | ### Routes
43 | This package adds the routes under `genealabs/laravel-caffeine`.
44 |
45 | ### Dependencies
46 | Your project must fullfill the following:
47 | - Laravel 8.0 or higher
48 | - PHP 7.3 or higher.
49 |
50 | ## Installation
51 | ```sh
52 | composer require genealabs/laravel-caffeine
53 | ```
54 |
55 | ## Upgrade Notes
56 | If you have previously registered the middleware, please remove the following
57 | middleware from `app/Http/Kernel.php`:
58 | ```php
59 | // protected $middleware = [
60 | GeneaLabs\LaravelCaffeine\Http\Middleware\LaravelCaffeineDripMiddleware::class,
61 | // ];
62 | ```
63 |
64 | ### 0.6.0
65 | This update changes the config file setting names. Please delete the published
66 | config file `config/genealabs-laravel-caffeine.php` if it exists, and follow the
67 | configuration instructions below.
68 |
69 | ## Configuration
70 | ```php
71 | return [
72 | /*
73 | |--------------------------------------------------------------------------
74 | | Drip Interval
75 | |--------------------------------------------------------------------------
76 | |
77 | | Here you may configure the interval with which Caffeine for Laravel
78 | | keeps the session alive. By default this is 5 minutes (expressed
79 | | in milliseconds). This needs to be shorter than your session
80 | | lifetime value configured set in "config/session.php".
81 | |
82 | | Default: 300000 (int)
83 | |
84 | */
85 | 'drip-interval' => 300000,
86 |
87 | /*
88 | |--------------------------------------------------------------------------
89 | | Domain
90 | |--------------------------------------------------------------------------
91 | |
92 | | You may optionally configure a separate domain that you are running
93 | | Caffeine for Laravel on. This may be of interest if you have a
94 | | monitoring service that queries other apps. Setting this to
95 | | null will use the domain of the current application.
96 | |
97 | | Default: null (null|string)
98 | |
99 | */
100 | 'domain' => null,
101 |
102 | /*
103 | |--------------------------------------------------------------------------
104 | | Drip Endpoint URL
105 | |--------------------------------------------------------------------------
106 | |
107 | | Sometimes you may wish to white-label your app and not expose the AJAX
108 | | request URLs as belonging to this package. To achieve that you can
109 | | rename the URL used for dripping caffeine into your application.
110 | |
111 | | Default: 'genealabs/laravel-caffeine/drip' (string)
112 | |
113 | */
114 | 'route' => 'genealabs/laravel-caffeine/drip', // Customizable end-point URL
115 |
116 | /*
117 | |--------------------------------------------------------------------------
118 | | Checking for Lapsed Drips
119 | |--------------------------------------------------------------------------
120 | |
121 | | If the browser tab is suspended due to inactivity or the device is put to
122 | | sleep, it will still cause an error when trying to submit the form. To
123 | | avoid this, we force-reload the form 2 minutes prior to session
124 | | time-out or later. Setting this setting to 0 will disable this
125 | | check if you don't want to use it.
126 | |
127 | | Default: 2000 (int)
128 | |
129 | */
130 | 'outdated-drip-check-interval' => 2000,
131 |
132 | /*
133 | |--------------------------------------------------------------------------
134 | | Use Route Middleware
135 | |--------------------------------------------------------------------------
136 | |
137 | | Drips are enabled via route middleware instead of global middleware.
138 | |
139 | | Default: false (bool)
140 | |
141 | */
142 | 'use-route-middleware' => false,
143 |
144 | ];
145 | ```
146 |
147 | ___Only publish the config file if you need to customize it___:
148 | ```sh
149 | php artisan caffeine:publish --config
150 | ```
151 |
152 | ## Usage
153 | That was it! It will apply itself automatically where it finds a form with a
154 | `_token` field, or a meta tag named "csrf-token", while pages are open in
155 | browsers.
156 |
157 | ### Prevent Caffeination
158 | There are two methods to prevent Caffeine for Laravel from dripping to keep the
159 | session alive: disabling it in Blade using the meta tag method, or enabling
160 | route-middleware mode, and then only enabling it on routes or route groups.
161 |
162 | #### Meta Tag Method
163 | If you would like to prevent a certain page from caffeinating your application,
164 | then add the following meta tag:
165 | ```php
166 |
167 | ```
168 |
169 | #### Route Middleware Method
170 | To enable this mode, you need to publish the configuration file (see the
171 | configuration section above) and then set `use-route-middleware` to `true`. This
172 | will disable the default global middleware mode (which applies it to any page
173 | that has the CSRF token in it across your entire application). Now you need to
174 | selectively enable Caffeine on a given route or route group using route
175 | middleware:
176 |
177 | ```php
178 | Route::any('test', 'TestController@test')->middleware('caffeinated');
179 |
180 | Route::group(['middleware' => ['caffeinated']], function () {
181 | Route::any('test', 'TestController@test');
182 | })
183 | ```
184 |
185 | You can still use the route middleware method and apply it globally to all
186 | routes by editing `app/Http/Kernel.php` and adding it to the `web` middleware
187 | group. Although you should only use this option if you have a very specific use-
188 | case that prevents you from utilizing the default global middleware option.
189 |
190 | __This will only have effect if the page includes a form. If not, the page will
191 | not caffeinate your application anyway.__
192 |
193 | # The Fine Print
194 | ## Commitment to Quality
195 | During package development I try as best as possible to embrace good design and
196 | development practices to try to ensure that this package is as good as it can
197 | be. My checklist for package development includes:
198 |
199 | - ✅ Achieve as close to 100% code coverage as possible using unit tests.
200 | - ✅ Eliminate any issues identified by SensioLabs Insight and Scrutinizer.
201 | - ✅ Be fully PSR1, PSR2, and PSR4 compliant.
202 | - ✅ Include comprehensive documentation in README.md.
203 | - ✅ Provide an up-to-date CHANGELOG.md which adheres to the format outlined
204 | at .
205 | - ✅ Have no PHPMD or PHPCS warnings throughout all code.
206 |
207 | ## Contributing
208 | Please observe and respect all aspects of the included Code of Conduct
209 | .
210 |
211 | ### Reporting Issues
212 | When reporting issues, please fill out the included template as completely as
213 | possible. Incomplete issues may be ignored or closed if there is not enough
214 | information included to be actionable.
215 |
216 | ### Submitting Pull Requests
217 | Please review the Contribution Guidelines .
218 | Only PRs that meet all criterium will be accepted.
219 |
220 | ## ❤️ Open-Source Software - Give ⭐️
221 | We have included the awesome `symfony/thanks` composer package as a dev
222 | dependency. Let your OS package maintainers know you appreciate them by starring
223 | the packages you use. Simply run `composer thanks` after installing this
224 | package. (And not to worry, since it's a dev-dependency it won't be installed in
225 | your live environment.)
226 |
--------------------------------------------------------------------------------
/caffeine.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikebronner/laravel-caffeine/79a3cb163f1d3c79a004725cbd9ee17ed9e06415/caffeine.jpg
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "genealabs/laravel-caffeine",
3 | "description": "Keeping Your Laravel Forms Awake",
4 | "license": "MIT",
5 | "authors": [
6 | {
7 | "name": "Mike Bronner",
8 | "email": "hello@genealabs.com"
9 | }
10 | ],
11 | "require": {
12 | "illuminate/routing": "^10.0|^11.0|^12.0",
13 | "illuminate/support": "^10.0|^11.0|^12.0"
14 | },
15 | "require-dev": {
16 | "orchestra/testbench-browser-kit": "^10.0",
17 | "orchestra/testbench-dusk": "^10.0",
18 | "orchestra/testbench": "^10.0",
19 | "phpmd/phpmd": "^2.13",
20 | "phpunit/phpunit": "^11.5.3"
21 | },
22 | "autoload": {
23 | "psr-4": {
24 | "GeneaLabs\\LaravelCaffeine\\": "src/"
25 | }
26 | },
27 | "autoload-dev": {
28 | "psr-4": {
29 | "GeneaLabs\\LaravelCaffeine\\Tests\\": "tests/"
30 | }
31 | },
32 | "config": {
33 | "optimize-autoloader": true,
34 | "preferred-install": "dist",
35 | "sort-packages": true
36 | },
37 | "extra": {
38 | "laravel": {
39 | "providers": [
40 | "GeneaLabs\\LaravelCaffeine\\Providers\\Service"
41 | ]
42 | }
43 | },
44 | "minimum-stability": "dev",
45 | "prefer-stable": true
46 | }
47 |
--------------------------------------------------------------------------------
/config/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikebronner/laravel-caffeine/79a3cb163f1d3c79a004725cbd9ee17ed9e06415/config/.gitkeep
--------------------------------------------------------------------------------
/config/genealabs-laravel-caffeine.php:
--------------------------------------------------------------------------------
1 | 300000,
18 |
19 | /*
20 | |--------------------------------------------------------------------------
21 | | Domain
22 | |--------------------------------------------------------------------------
23 | |
24 | | You may optionally configure a separate domain that you are running
25 | | Caffeine for Laravel on. This may be of interest if you have a
26 | | monitoring service that queries other apps. Setting this to
27 | | null will use the domain of the current application.
28 | |
29 | | Default: null (null|string)
30 | |
31 | */
32 | 'domain' => null,
33 |
34 | /*
35 | |--------------------------------------------------------------------------
36 | | Drip Endpoint URL
37 | |--------------------------------------------------------------------------
38 | |
39 | | Sometimes you may wish to white-label your app and not expose the AJAX
40 | | request URLs as belonging to this package. To achieve that you can
41 | | rename the URL used for dripping caffeine into your application.
42 | |
43 | | Default: 'genealabs/laravel-caffeine/drip' (string)
44 | |
45 | */
46 | 'route' => 'genealabs/laravel-caffeine/drip', // Customizable end-point URL
47 |
48 | /*
49 | |--------------------------------------------------------------------------
50 | | Checking for Lapsed Drips
51 | |--------------------------------------------------------------------------
52 | |
53 | | If the browser is put to sleep on (for example on mobile devices or
54 | | laptops), it will still cause an error when trying to submit the
55 | | form. To avoid this, we force-reload the form 2 minutes prior
56 | | to session time-out or later. Setting this setting to 0
57 | | will disable this check if you don't want to use it.
58 | |
59 | | Default: 2000 (int)
60 | |
61 | */
62 | 'outdated-drip-check-interval' => 2000,
63 |
64 | /*
65 | |--------------------------------------------------------------------------
66 | | Use Route Middleware
67 | |--------------------------------------------------------------------------
68 | |
69 | | Drips are enabled via route middleware instead of global middleware.
70 | |
71 | | Default: false (bool)
72 | |
73 | */
74 | 'use-route-middleware' => false,
75 |
76 | ];
77 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | # For more information: https://laravel.com/docs/sail
2 | version: '3'
3 | services:
4 | laravel.test:
5 | image: ghcr.io/mikebronner/sail/php-8.2:latest
6 | extra_hosts:
7 | - 'host.docker.internal:host-gateway'
8 | ports:
9 | - '${APP_PORT:-80}:80'
10 | - '${VITE_PORT:-5173}:${VITE_PORT:-5173}'
11 | environment:
12 | WWWUSER: '${WWWUSER:-1000}'
13 | LARAVEL_SAIL: 1
14 | XDEBUG_MODE: '${SAIL_XDEBUG_MODE:-off}'
15 | XDEBUG_CONFIG: '${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}'
16 | volumes:
17 | - '.:/var/www/html'
18 | networks:
19 | - sail
20 |
21 | networks:
22 | sail:
23 | driver: bridge
24 |
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 | ./tests/Feature
12 |
13 |
14 | ./tests/Unit
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | ./src
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/resources/views/script.blade.php:
--------------------------------------------------------------------------------
1 | @if (function_exists('csp_nonce'))
2 |
49 |
--------------------------------------------------------------------------------
/routes/web.php:
--------------------------------------------------------------------------------
1 | middleware('web');
8 |
--------------------------------------------------------------------------------
/src/Console/Commands/Publish.php:
--------------------------------------------------------------------------------
1 | option('config')) {
15 | $this->call('vendor:publish', [
16 | '--provider' => Service::class,
17 | '--tag' => ['config'],
18 | '--force' => true,
19 | ]);
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/Dripper.php:
--------------------------------------------------------------------------------
1 | with([
13 | "ageCheckInterval" => $this->getAgeCheckInterval(),
14 | "ageThreshold" => $this->getAgeThreshold(),
15 | "interval" => $this->getInterval(),
16 | "url" => $this->getUrl(),
17 | ]);
18 | }
19 |
20 | protected function getAgeCheckInterval(): int
21 | {
22 | return config("genealabs-laravel-caffeine.outdated-drip-check-interval", 2000);
23 | }
24 |
25 | protected function getAgeThreshold(): int
26 | {
27 | return (config("session.lifetime", 32) - 2) * 60000;
28 | }
29 |
30 | protected function getInterval(): int
31 | {
32 | return config("genealabs-laravel-caffeine.drip-interval", 300000);
33 | }
34 |
35 | protected function getUrl(): string
36 | {
37 | return trim(config("genealabs-laravel-caffeine.domain") ?? url("/"), "/")
38 | . "/"
39 | . trim(
40 | config("genealabs-laravel-caffeine.route", "genealabs/laravel-caffeine/drip"),
41 | "/",
42 | );
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/Http/Controllers/Drip.php:
--------------------------------------------------------------------------------
1 | getContent();
14 |
15 | if (! is_string($content) || strlen(trim($content)) === 0) {
16 | return $response;
17 | }
18 |
19 | $shouldDripRegexp = $this->makeRegex([
20 | 'makeRegex([
32 | "makeRegex([
35 | ")\s*\z/', "{$dripper->getHtml()}