diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
new file mode 100644
index 00000000..eaac2e1e
--- /dev/null
+++ b/.devcontainer/devcontainer.json
@@ -0,0 +1,101 @@
+// https://aka.ms/devcontainer.json
+{
+ "name": "Existing Docker Compose (Extend)",
+ "dockerComposeFile": [
+ "../docker-compose.yml"
+ ],
+ "features": {
+ "ghcr.io/devcontainers/features/sshd:1": {
+ "version": "latest"
+ }
+ },
+ "service": "laravel.test",
+ "workspaceFolder": "/var/www/html",
+ "customizations": {
+ "vscode": {
+ "settings": {},
+ "extensions": [
+ "aaron-bond.better-comments",
+ "adrianwilczynski.alpine-js-intellisense",
+ "amiralizadeh9480.laravel-extra-intellisense",
+ "austenc.laravel-blade-spacer",
+ "beyondcode.tinkerwell",
+ "bmewburn.vscode-intelephense-client",
+ "bradlc.vscode-tailwindcss",
+ "christian-kohler.npm-intellisense",
+ "christian-kohler.path-intellisense",
+ "cierra.livewire-vscode",
+ "codingyu.laravel-goto-view",
+ "davidanson.vscode-markdownlint",
+ "davidbwaters.macos-modern-theme",
+ "eamodio.gitlens",
+ "editorconfig.editorconfig",
+ "ericcheng.codesongclear",
+ "faelv.composer-companion",
+ "file-icons.file-icons",
+ "foxundermoon.shell-format",
+ "georgykurian.laravel-ide-helper",
+ "github.codespaces",
+ "GitHub.copilot-chat",
+ "GitHub.copilot-nightly",
+ "github.vscode-github-actions",
+ "github.vscode-pull-request-github",
+ "Gruntfuggly.activitusbar",
+ "heissenbergerlab.php-array-from-json",
+ "heybourn.headwind",
+ "huibizhang.codesnap-plus",
+ "irongeek.vscode-env",
+ "kencocaceo.customvscodeuicss",
+ "m4ns0ur.base64",
+ "maciejdems.add-to-gitignore",
+ "mahmoudshahin.laravel-routes",
+ "markis.code-coverage",
+ "martybegood.single-editor-tabs",
+ "mechatroner.rainbow-csv",
+ "mehedidracula.php-namespace-resolver",
+ "mhutchie.git-graph",
+ "mikestead.dotenv",
+ "mohamedbenhida.laravel-intellisense",
+ "mrmlnc.vscode-duplicate",
+ "naoray.laravel-goto-components",
+ "oderwat.indent-rainbow",
+ "pcbowers.alpine-intellisense",
+ "recca0120.vscode-phpunit",
+ "redhat.vscode-yaml",
+ "rifi2k.format-html-in-php",
+ "shevaua.phpcs",
+ "shufo.vscode-blade-formatter",
+ "sperovita.alpinejs-syntax-highlight",
+ "streetsidesoftware.code-spell-checker",
+ "syler.ignore",
+ "teabyii.ayu",
+ "usernamehw.errorlens",
+ "vincaslt.highlight-matching-tag",
+ "WakaTime.vscode-wakatime",
+ "withfig.fig",
+ "wongjn.php-sniffer",
+ "xdebug.php-debug",
+ "codecov.codecov"
+ ]
+ }
+ },
+ "remoteUser": "sail",
+ "postCreateCommand": "sudo chown -R 1000:1000 /var/www/html",
+ "forwardPorts": [
+ 5432,
+ 6379
+ ],
+ "portsAttributes": {
+ "5432": {
+ "label": "Postgres"
+ },
+ "6379": {
+ "label": "Redis"
+ }
+ },
+ "mounts": [
+ "source=${localEnv:HOME}/.wakatime.cfg,target=/home/sail/.wakatime.cfg,type=bind,consistency=delegated"
+ ]
+ // "runServices": [],
+ // "shutdownAction": "none",
+}
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 00000000..bc1105dc
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,19 @@
+root = true
+
+[*]
+charset = utf-8
+end_of_line = lf
+insert_final_newline = true
+indent_style = space
+indent_size = 4
+trim_trailing_whitespace = true
+
+[*.md]
+trim_trailing_whitespace = false
+indent_size = 2
+
+[*.{yml,yaml}]
+indent_size = 2
+
+[.blackfire.yaml]
+indent_size = 4
diff --git a/.github/workflows/laravel.yml b/.github/workflows/laravel.yml
index a169f2bb..f5bcd953 100644
--- a/.github/workflows/laravel.yml
+++ b/.github/workflows/laravel.yml
@@ -14,7 +14,7 @@ jobs:
strategy:
fail-fast: true
matrix:
- php: [8.2, 8.1]
+ php: [8.4, 8.3, 8.2]
name: PHP ${{ matrix.php }}
@@ -42,9 +42,9 @@ jobs:
- uses: harmon758/postgresql-action@v1
with:
- postgresql version: '11'
+ postgresql version: '15'
postgresql db: 'testing'
- postgresql user: 'homestead'
+ postgresql user: 'forge'
postgresql password: 'secret'
- name: Remove Nova on a pull request
@@ -56,7 +56,7 @@ jobs:
- name: Install Dependencies
run: |
- composer config "http-basic.nova.laravel.com" "${{ secrets.NOVA_USERNAME }}" "${{ secrets.NOVA_PASSWORD }}"
+ composer config "http-basic.nova.laravel.com" "${{ secrets.NOVA_USERNAME }}" "${{ secrets.NOVA_LICENSE_KEY }}"
composer install -q --no-ansi --no-interaction --no-scripts --no-suggest --no-progress --prefer-dist
- name: Execute Integration and Feature tests via PHPUnit
diff --git a/.gitignore b/.gitignore
index c2d4570f..8fbb4834 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,6 @@
+.idea
+.phpunit.result.cache
+/.phpunit*
/build
/vendor
composer.lock
-.phpunit.result.cache
-phpunit.xml
-.idea
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
new file mode 100644
index 00000000..757b5a7d
--- /dev/null
+++ b/.vscode/extensions.json
@@ -0,0 +1,69 @@
+{
+ "recommendations": [
+ "aaron-bond.better-comments",
+ "adrianwilczynski.alpine-js-intellisense",
+ "amiralizadeh9480.laravel-extra-intellisense",
+ "austenc.laravel-blade-spacer",
+ "beyondcode.tinkerwell",
+ "bmewburn.vscode-intelephense-client",
+ "bradlc.vscode-tailwindcss",
+ "christian-kohler.npm-intellisense",
+ "christian-kohler.path-intellisense",
+ "cierra.livewire-vscode",
+ "codingyu.laravel-goto-view",
+ "davidanson.vscode-markdownlint",
+ "davidbwaters.macos-modern-theme",
+ "eamodio.gitlens",
+ "editorconfig.editorconfig",
+ "ericcheng.codesongclear",
+ "faelv.composer-companion",
+ "file-icons.file-icons",
+ "foxundermoon.shell-format",
+ "georgykurian.laravel-ide-helper",
+ "github.codespaces",
+ "GitHub.copilot-chat",
+ "GitHub.copilot-nightly",
+ "github.vscode-github-actions",
+ "github.vscode-pull-request-github",
+ "Gruntfuggly.activitusbar",
+ "heissenbergerlab.php-array-from-json",
+ "heybourn.headwind",
+ "huibizhang.codesnap-plus",
+ "irongeek.vscode-env",
+ "kencocaceo.customvscodeuicss",
+ "m4ns0ur.base64",
+ "maciejdems.add-to-gitignore",
+ "mahmoudshahin.laravel-routes",
+ "markis.code-coverage",
+ "martybegood.single-editor-tabs",
+ "mechatroner.rainbow-csv",
+ "mehedidracula.php-namespace-resolver",
+ "mhutchie.git-graph",
+ "mikestead.dotenv",
+ "mohamedbenhida.laravel-intellisense",
+ "mrmlnc.vscode-duplicate",
+ "naoray.laravel-goto-components",
+ "oderwat.indent-rainbow",
+ "pcbowers.alpine-intellisense",
+ "recca0120.vscode-phpunit",
+ "redhat.vscode-yaml",
+ "rifi2k.format-html-in-php",
+ "shevaua.phpcs",
+ "shufo.vscode-blade-formatter",
+ "sperovita.alpinejs-syntax-highlight",
+ "streetsidesoftware.code-spell-checker",
+ "syler.ignore",
+ "teabyii.ayu",
+ "usernamehw.errorlens",
+ "vincaslt.highlight-matching-tag",
+ "WakaTime.vscode-wakatime",
+ "withfig.fig",
+ "wongjn.php-sniffer",
+ "xdebug.php-debug",
+ "codecov.codecov"
+ ],
+ "unwantedRecommendations": [
+ "ikappas.phpcs",
+ "linyang95.phpmd"
+ ]
+}
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 00000000..e614d03c
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,318 @@
+{
+ "activitusbar.combineWorkspaceSettings": true,
+ "activitusbar.searchViewInPanel": false,
+ "activitusbar.showSourceControlCounter": true,
+ "activitusbar.views": [
+ {
+ "name": "command.workbench.panel.chatSidebar.copilot",
+ "codicon": "octoface"
+ },
+ {
+ "name": "explorer",
+ "codicon": "explorer-view-icon"
+ },
+ {
+ "name": "search",
+ "codicon": "search-view-icon"
+ },
+ {
+ "name": "pr:github",
+ "codicon": "github"
+ },
+ {
+ "name": "scm",
+ "codicon": "source-control-view-icon"
+ },
+ {
+ "name": "command.workbench.panel.chatSidebar.copilot",
+ "codicon": "octoface"
+ },
+ {
+ "name": "debug",
+ "codicon": "run-view-icon"
+ },
+ {
+ "name": "github.codespaces.explorer",
+ "codicon": "remote-explorer"
+ },
+ {
+ "name": "extensions",
+ "codicon": "extensions-view-icon"
+ },
+ {
+ "codicon": "kebab-vertical"
+ }
+ ],
+ "alpine-intellisense.settings.languageScopes": "html,blade,php",
+ "better-comments.tags": [
+ {
+ "tag": "!",
+ "color": "#FF2D00",
+ "strikethrough": false,
+ "underline": false,
+ "backgroundColor": "transparent",
+ "bold": false,
+ "italic": false
+ },
+ {
+ "tag": "?",
+ "color": "#3498DB",
+ "strikethrough": false,
+ "underline": false,
+ "backgroundColor": "transparent",
+ "bold": false,
+ "italic": false
+ },
+ {
+ "tag": "//",
+ "color": "#474747",
+ "strikethrough": true,
+ "underline": false,
+ "backgroundColor": "transparent",
+ "bold": false,
+ "italic": false
+ },
+ {
+ "tag": "todo",
+ "color": "#FF8C00",
+ "strikethrough": false,
+ "underline": false,
+ "backgroundColor": "transparent",
+ "bold": false,
+ "italic": false
+ },
+ {
+ "tag": "*",
+ "color": "#98C379",
+ "strikethrough": false,
+ "underline": false,
+ "backgroundColor": "transparent",
+ "bold": false,
+ "italic": false
+ }
+ ],
+ "blade.format.enable": true,
+ "blade.newLine": true,
+ "bladeFormatter.format.enabled": true,
+ "bladeFormatter.format.noMultipleEmptyLines": true,
+ "bladeFormatter.format.sortHtmlAttributes": "alphabetical",
+ "bladeFormatter.format.sortTailwindcssClasses": true,
+ "bladeFormatter.format.wrapAttributes": "force-expand-multiline",
+ "bladeFormatter.format.wrapLineLength": 100,
+ "breadcrumbs.enabled": true,
+ "composerCompanion.executablePath": "composer",
+ "cSpell.spellCheckOnlyWorkspaceFiles": true,
+ "cSpell.autoFormatConfigFile": true,
+ "css.validate": false,
+ "debug.allowBreakpointsEverywhere": true,
+ "debug.showBreakpointsInOverviewRuler": true,
+ "diffEditor.ignoreTrimWhitespace": false,
+ "diffEditor.wordWrap": "off",
+ "editor.acceptSuggestionOnEnter": "off",
+ "editor.accessibilitySupport": "off",
+ "editor.autoClosingBrackets": "always",
+ "editor.codeLensFontFamily": "JetBrains Mono",
+ "editor.cursorBlinking": "expand",
+ "editor.cursorSmoothCaretAnimation": "on",
+ "editor.detectIndentation": true,
+ "editor.emptySelectionClipboard": false,
+ "editor.fontFamily": "JetBrains Mono",
+ "editor.fontLigatures": true,
+ "editor.formatOnPaste": false,
+ "editor.formatOnType": true,
+ "editor.gotoLocation.multipleDeclarations": "goto",
+ "editor.gotoLocation.multipleDefinitions": "goto",
+ "editor.gotoLocation.multipleImplementations": "goto",
+ "editor.gotoLocation.multipleReferences": "goto",
+ "editor.gotoLocation.multipleTypeDefinitions": "goto",
+ "editor.inlayHints.fontFamily": "JetBrains Mono",
+ "editor.inlineSuggest.enabled": true,
+ "editor.insertSpaces": true,
+ "editor.lightbulb.enabled": "off",
+ "editor.linkedEditing": true,
+ "editor.minimap.maxColumn": 100,
+ "editor.parameterHints.enabled": false,
+ "editor.quickSuggestions": {
+ "strings": true
+ },
+ "editor.renderFinalNewline": "on",
+ "editor.renderWhitespace": "none",
+ "editor.roundedSelection": true,
+ "editor.rulers": [
+ 100,
+ ],
+ "editor.stickyScroll.enabled": true,
+ "editor.suggest.localityBonus": true,
+ "editor.suggest.showValues": false,
+ "editor.trimAutoWhitespace": true,
+ "editor.wordBasedSuggestions": "off",
+ "editor.wordSeparators": "`~!@#%^&*()-=+[{]}\\|;:'\",.<>/?",
+ "editor.wordWrapColumn": 100,
+ "editor.wrappingIndent": "none",
+ "errorLens.enableOnDiffView": true,
+ "errorLens.fontFamily": "JetBrains Mono",
+ "errorLens.messageTemplate": "$message $source $code",
+ "explorer.confirmDelete": false,
+ "explorer.confirmDragAndDrop": false,
+ "extensions.ignoreRecommendations": false,
+ "files.autoGuessEncoding": true,
+ "files.insertFinalNewline": true,
+ "files.trimFinalNewlines": true,
+ "files.trimTrailingWhitespace": true,
+ "git.allowForcePush": true,
+ "git.autofetch": true,
+ "git.confirmSync": false,
+ "git.enableCommitSigning": false,
+ "git.enableSmartCommit": true,
+ "git.fetchOnPull": true,
+ "git.ignoreRebaseWarning": true,
+ "git.mergeEditor": false,
+ "git.showPushSuccessNotification": true,
+ "github.copilot.enable": {
+ "*": true,
+ "yaml": false,
+ "plaintext": false,
+ "markdown": false
+ },
+ "github.copilot.inlineSuggest.enable": true,
+ "githubIssues.issueBranchTitle": "${user}/${sanitizedIssueTitle}",
+ "githubIssues.queries": [
+ {
+ "label": "My Issues",
+ "query": "default"
+ },
+ {
+ "label": "Created Issues",
+ "query": "author:${user} state:open repo:${owner}\/${repository} sort:created-desc"
+ },
+ {
+ "label": "Recent Issues",
+ "query": "state:open repo:${owner}\/${repository} sort:updated-desc"
+ }
+ ],
+ "githubIssues.workingIssueFormatScm": "",
+ "githubPullRequests.assignCreated": "${user}",
+ "githubPullRequests.createDraft": true,
+ "githubPullRequests.defaultMergeMethod": "squash",
+ "githubPullRequests.fileListLayout": "tree",
+ "githubPullRequests.ignoredPullRequestBranches": [
+ "develop",
+ "master"
+ ],
+ "githubPullRequests.pullBranch": "never",
+ "githubPullRequests.showPullRequestNumberInTree": true,
+ "githubPullRequests.terminalLinksHandler": "vscode",
+ "gitlens.showWelcomeOnInstall": false,
+ "gitlens.showWhatsNewAfterUpgrades": false,
+ "gitlens.outputLevel": "silent",
+ "gitlens.plusFeatures.enabled": false,
+ "gitlens.virtualRepositories.enabled": false,
+ "gitlens.codeLens.enabled": false,
+ "gitlens.codeLens.recentChange.enabled": false,
+ "gitlens.codeLens.authors.enabled": false,
+ "gitlens.statusBar.enabled": false,
+ "gitlens.statusBar.pullRequests.enabled": false,
+ "gitlens.hovers.enabled": false,
+ "gitlens.hovers.avatars": false,
+ "gitlens.hovers.pullRequests.enabled": false,
+ "gitlens.hovers.autolinks.enabled": false,
+ "gitlens.hovers.currentLine.enabled": false,
+ "gitlens.hovers.autolinks.enhanced": false,
+ "gitlens.hovers.currentLine.details": false,
+ "gitlens.hovers.currentLine.changes": false,
+ "gitlens.hovers.annotations.enabled": false,
+ "gitlens.hovers.annotations.changes": false,
+ "gitlens.hovers.annotations.details": false,
+ "headwind.runOnSave": true,
+ "html.format.indentHandlebars": true,
+ "html.format.indentInnerHtml": true,
+ "html.format.preserveNewLines": true,
+ "html.format.wrapAttributes": "force",
+ "html.format.wrapLineLength": 100,
+ "indentRainbow.colorOnWhiteSpaceOnly": true,
+ "intelephense.environment.documentRoot": "public/index.php",
+ "intelephense.files.exclude": [
+ "**/.git/**",
+ "**/.svn/**",
+ "**/.hg/**",
+ "**/CVS/**",
+ "**/.DS_Store/**",
+ "**/node_modules/**",
+ "**/bower_components/**",
+ "**/vendor/**/{Tests,tests}/**",
+ "**/.history/**"
+ ],
+ "intelephense.phpdoc.returnVoid": false,
+ "javascript.format.placeOpenBraceOnNewLineForControlBlocks": true,
+ "LaravelExtraIntellisense.modelAccessorCase": "camel",
+ "LaravelExtraIntellisense.modelAttributeCase": "camel",
+ "LaravelExtraIntellisense.modelsPaths": [
+ "app",
+ "app/Models"
+ ],
+ "LaravelExtraIntellisense.modelVariables": {
+ "user": "App\\Models\\User"
+ },
+ "LaravelIntellisense.model": "App\\Models",
+ "markdown.preview.fontFamily": "JetBrains Mono",
+ "markdownlint.config": {
+ "default": true,
+ "MD024": false,
+ "MD022": false,
+ "MD032": false,
+ },
+ "namespaceResolver.leadingSeparator": false,
+ "namespaceResolver.showMessageOnStatusBar": true,
+ "namespaceResolver.sortAlphabetically": true,
+ "namespaceResolver.sortOnSave": true,
+ "php.suggest.basic": false,
+ "php.validate.enable": false,
+ "php.validate.run": "onType",
+ "phpcs.executablePath": "vendor/bin/phpcs",
+ "phpcs.showSources": true,
+ "phpunit.args": [
+ "--coverage-clover=coverage.xml",
+ ],
+ "redhat.telemetry.enabled": false,
+ "search.exclude": {
+ // Hide everything in /vendor, except "laravel" and "livewire" folders.
+ "**/vendor/{[^l],?[^ai]}*": true,
+ // Hide everything in /public, except "index.php"
+ "**/public/{[^i],?[^n]}*": true,
+ "**/node_modules": true,
+ "**/dist": true,
+ "**/_ide_helper.php": true,
+ "**/composer.lock": true,
+ "**/package-lock.json": true,
+ "storage": true,
+ ".phpunit.result.cache": true
+ },
+ "tailwindCSS.validate": true,
+ "terminal.explorerKind": "external",
+ "terminal.integrated.drawBoldTextInBrightColors": false,
+ "terminal.integrated.enableMultiLinePasteWarning": false,
+ "terminal.integrated.fontFamily": "MesloLGS NF",
+ "terminal.integrated.gpuAcceleration": "off",
+ "terminal.integrated.scrollback": 5000,
+ "typescript.suggest.enabled": false,
+ "window.commandCenter": true,
+ "workbench.editor.enablePreview": false,
+ "workbench.editor.showIcons": false,
+ "workbench.editor.showTabs": "single",
+ "workbench.editor.tabCloseButton": "left",
+ "workbench.fontAliasing": "auto",
+ "workbench.iconTheme": "file-icons",
+ "workbench.productIconTheme": "macos-modern",
+ "workbench.startupEditor": "none",
+ "zenMode.fullScreen": false,
+ "zenMode.hideLineNumbers": false,
+ // formaters
+ "[blade]": {
+ "editor.defaultFormatter": "shufo.vscode-blade-formatter"
+ },
+ "[php]": {
+ "editor.defaultFormatter": "bmewburn.vscode-intelephense-client"
+ },
+ "window.title": "laravel-model-caching",
+ "workbench.editor.tabActionLocation": "left"
+}
diff --git a/README.md b/README.md
index 86d86357..f8c04ce7 100644
--- a/README.md
+++ b/README.md
@@ -67,6 +67,7 @@ The following are packages we have identified as conflicting:
- [spatie/laravel-query-builder](https://github.com/spatie/laravel-query-builder)
- [dwightwatson/rememberable](https://github.com/dwightwatson/rememberable)
- [kalnoy/nestedset](https://github.com/lazychaser/laravel-nestedset)
+- [laravel-adjacency-list](https://github.com/staudenmeir/laravel-adjacency-list)
### Things That Don't Work Currently
The following items currently do no work with this package:
@@ -81,7 +82,7 @@ The following items currently do no work with this package:
## Installation
Be sure to not require a specific version of this package when requiring it:
```
-composer require genealabs/laravel-model-caching
+composer require mikebronner/laravel-model-caching
```
### Gotchas If Using With Lumen
diff --git a/composer.json b/composer.json
index 0460718b..de5669c6 100644
--- a/composer.json
+++ b/composer.json
@@ -1,5 +1,5 @@
{
- "name": "genealabs/laravel-model-caching",
+ "name": "mikebronner/laravel-model-caching",
"description": "Automatic caching for Eloquent models.",
"license": "MIT",
"authors": [
@@ -15,26 +15,25 @@
}
],
"require": {
- "php": "^8.1",
- "genealabs/laravel-pivot-events": "^10.0",
- "illuminate/cache": "^10.0",
- "illuminate/config": "^10.0",
- "illuminate/console": "^10.0",
- "illuminate/container": "^10.0",
- "illuminate/database": "^10.0",
- "illuminate/http": "^10.0",
- "illuminate/support": "^10.0"
+ "php": ">=8.1",
+ "mikebronner/laravel-pivot-events": "^10.0|^11.0|^12.0",
+ "illuminate/cache": "^10.0|^11.0|^12.0",
+ "illuminate/config": "^10.0|^11.0|^12.0",
+ "illuminate/console": "^10.0|^11.0|^12.0",
+ "illuminate/container": "^10.0|^11.0|^12.0",
+ "illuminate/database": "^10.0|^11.0|^12.0",
+ "illuminate/http": "^10.0|^11.0|^12.0",
+ "illuminate/support": "^10.0|^11.0|^12.0"
},
"require-dev": {
- "doctrine/dbal": "^3.3",
+ "doctrine/dbal": "^3.3|^4.2",
"fakerphp/faker": "^1.11",
- "laravel/nova": "^3.9",
- "orchestra/testbench-browser-kit": "^8.0",
- "orchestra/testbench": "^8.0",
- "php-coveralls/php-coveralls" : "^2.2",
- "phpmd/phpmd": "^2.11",
- "phpunit/phpunit": "^9.5",
- "slevomat/coding-standard": "^7.0",
+ "laravel/nova": "^5.0",
+ "orchestra/testbench-browser-kit": "^9.0|^10.0",
+ "orchestra/testbench": "^9.0|^10.0",
+ "php-coveralls/php-coveralls": "^2.2",
+ "phpunit/phpunit": "^10.5|^11.5.3",
+ "slevomat/coding-standard": "^7.0|^8.14",
"squizlabs/php_codesniffer": "^3.6",
"symfony/thanks": "^1.2",
"laravel/legacy-factories": "^1.3"
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 00000000..91897e8c
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,59 @@
+# For more information: https://laravel.com/docs/sail
+version: '3'
+services:
+ laravel.test:
+ image: ghcr.io/mikebronner/sail/php-8.2:latest
+ extra_hosts:
+ - 'host.docker.internal:host-gateway'
+ ports:
+ - '${APP_PORT:-80}:80'
+ - '${VITE_PORT:-5173}:${VITE_PORT:-5173}'
+ environment:
+ WWWUSER: '${WWWUSER}'
+ LARAVEL_SAIL: 1
+ XDEBUG_MODE: '${SAIL_XDEBUG_MODE:-off}'
+ XDEBUG_CONFIG: '${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}'
+ volumes:
+ - '.:/var/www/html'
+ networks:
+ - sail
+ depends_on:
+ - redis
+ pgsql:
+ image: 'postgres:15'
+ ports:
+ - '${FORWARD_DB_PORT:-5432}:5432'
+ environment:
+ PGPASSWORD: '${DB_PASSWORD:-secret}'
+ POSTGRES_DB: '${DB_DATABASE:-testing}'
+ POSTGRES_USER: '${DB_USERNAME:-forge}'
+ POSTGRES_PASSWORD: '${DB_PASSWORD:-secret}'
+ volumes:
+ - 'sail-pgsql:/var/lib/postgresql/data'
+ - './vendor/laravel/sail/database/pgsql/create-testing-database.sql:/docker-entrypoint-initdb.d/10-create-testing-database.sql'
+ networks:
+ - sail
+ healthcheck:
+ test: ["CMD", "pg_isready", "-q", "-d", "${DB_DATABASE}", "-U", "${DB_USERNAME}"]
+ retries: 3
+ timeout: 5s
+ redis:
+ image: 'redis:alpine'
+ ports:
+ - '${FORWARD_REDIS_PORT:-6379}:6379'
+ volumes:
+ - 'sail-redis:/data'
+ networks:
+ - sail
+ healthcheck:
+ test: ["CMD", "redis-cli", "ping"]
+ retries: 3
+ timeout: 5s
+networks:
+ sail:
+ driver: bridge
+volumes:
+ sail-pgsql:
+ driver: local
+ sail-redis:
+ driver: local
diff --git a/phpmd.xml b/phpmd.xml
deleted file mode 100644
index 45449165..00000000
--- a/phpmd.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-
-
-
- Custom ruleset for Laravel.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 36
-
-
-
-
-
-
- 2
-
-
-
-
-
-
- 2
-
-
-
-
-
-
diff --git a/phpunit.xml b/phpunit.xml
index 638c1866..c26ddd53 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -1,34 +1,45 @@
-
-
-
- ./src
-
-
-
-
- ./tests/Feature
-
-
- ./tests/Integration
-
-
- ./tests/Nova
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ ./tests/Feature
+
+
+ ./tests/Integration
+
+
+ ./tests/Nova
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ./src
+
+
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 3c8ff2dd..45a3ad26 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -1,14 +1,14 @@
@@ -21,21 +21,21 @@
./tests/Nova
-
-
- ./src
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+ ./src
+
+
diff --git a/src/CacheKey.php b/src/CacheKey.php
index 3258e288..84c1fc97 100644
--- a/src/CacheKey.php
+++ b/src/CacheKey.php
@@ -1,5 +1,8 @@
-query->havings)->reduce(function ($carry, $having) {
- $value = $carry;
- $value .= $this->getHavingClause($having);
-
- return $value;
- });
- }
-
- protected function getHavingClause(array $having): string
- {
- $return = '-having';
-
- foreach ($having as $key => $value) {
- $return .= '_' . $key . '_' . str_replace(' ', '_', $value);
- }
-
- return $return;
- }
-
protected function getBindingsSlug() : string
{
if (! method_exists($this->model, 'query')) {
@@ -102,7 +85,7 @@ protected function getColumnClauses(array $where) : string
if ($where["type"] !== "Column") {
return "";
}
-
+
if ($where["first"] instanceof Expression) {
$where["first"] = $this->expressionToString($where["first"]);
}
@@ -119,6 +102,27 @@ protected function getCurrentBinding(string $type, $bindingFallback = null)
return data_get($this->query->bindings, "{$type}.{$this->currentBinding}", $bindingFallback);
}
+ protected function getHavingClauses()
+ {
+ return Collection::make($this->query->havings)->reduce(function ($carry, $having) {
+ $value = $carry;
+ $value .= $this->getHavingClause($having);
+
+ return $value;
+ });
+ }
+
+ protected function getHavingClause(array $having): string
+ {
+ $return = '-having';
+
+ foreach ($having as $key => $value) {
+ $return .= '_' . $key . '_' . str_replace(' ', '_', $value);
+ }
+
+ return $return;
+ }
+
protected function getIdColumn(string $idColumn) : string
{
return $idColumn ? "_{$idColumn}" : "";
@@ -214,7 +218,7 @@ protected function getOrderByClauses() : string
}
$orders = collect($this->query->orders);
-
+
return $orders
->reduce(function ($carry, $order) {
if (($order["type"] ?? "") === "Raw") {
@@ -241,7 +245,12 @@ protected function getOtherClauses(array $where) : string
$value .= $this->getValuesClause($where);
$column = "";
- $column .= isset($where["column"]) ? $this->expressionToString($where["column"]) : "";
+
+ if (data_get($where, "column") instanceof Expression) {
+ $where["column"] = $this->expressionToString(data_get($where, "column"));
+ }
+
+ $column .= isset($where["column"]) ? $where["column"] : "";
$column .= isset($where["columns"]) ? implode("-", $where["columns"]) : "";
return "-{$column}_{$value}";
@@ -260,16 +269,18 @@ protected function getQueryColumns(array $columns) : string
if (property_exists($this->query, "columns")
&& $this->query->columns
) {
- $columns = array_map(function ($column) {
+ $columns = array_map(function ($column) {
return $this->expressionToString($column);
}, $this->query->columns);
return "_" . implode("_", $columns);
}
- return "_" . implode("_", array_map(function ($column) {
+ $columns = array_map(function ($column) {
return $this->expressionToString($column);
- }, $columns));
+ }, $columns);
+
+ return "_" . implode("_", $columns);
}
protected function getRawClauses(array $where) : string
@@ -304,7 +315,7 @@ protected function getTableSlug() : string
protected function getTypeClause($where) : string
{
- $type = in_array($where["type"], ["InRaw", "In", "NotIn", "Null", "NotNull", "between", "NotInSub", "InSub", "JsonContains", "Fulltext"])
+ $type = in_array($where["type"], ["InRaw", "In", "NotIn", "Null", "NotNull", "between", "NotInSub", "InSub", "JsonContains", "Fulltext", "JsonContainsKey"])
? strtolower($where["type"])
: strtolower($where["operator"]);
@@ -448,11 +459,11 @@ protected function recursiveImplode(array $items, string $glue = ",") : string
return $result;
}
- private function processEnum(\BackedEnum|\UnitEnum|Expression|string|null $value): string
+ private function processEnum(BackedEnum|UnitEnum|Expression|string|null $value): ?string
{
- if ($value instanceof \BackedEnum) {
+ if ($value instanceof BackedEnum) {
return $value->value;
- } elseif ($value instanceof \UnitEnum) {
+ } elseif ($value instanceof UnitEnum) {
return $value->name;
} elseif ($value instanceof Expression) {
return $this->expressionToString($value);
diff --git a/src/Traits/Buildable.php b/src/Traits/Buildable.php
index 0fcf5bde..34af7002 100644
--- a/src/Traits/Buildable.php
+++ b/src/Traits/Buildable.php
@@ -176,7 +176,7 @@ public function paginate(
if (is_array($page)) {
$page = $this->recursiveImplodeWithKey($page);
}
-
+
$columns = collect($columns)->toArray();
$keyDifferentiator = "-paginate_by_{$perPage}_{$pageName}_{$page}";
@@ -325,12 +325,12 @@ function () use ($arguments, $cacheKey, $method) {
* The risk of this change is if any application code is dependent on the `pivotParent` property
* of a cached Pivot record, then you're a bit out of luck and would need to have a fallback.
*/
- if (is_iterable($value) && !empty($value)) {
- foreach ($value as $index => $model) {
- if (!empty($model) && is_object($model) && $model?->pivot?->pivotParent) {
+ if (is_iterable($value) && ! empty($value)) {
+ foreach ($value as $model) {
+ if (! empty($model) && is_object($model) && $model?->pivot?->pivotParent) {
unset($model->pivot->pivotParent);
- }
- }
+ }
+ }
}
return [
"key" => $cacheKey,
diff --git a/src/Traits/BuilderCaching.php b/src/Traits/BuilderCaching.php
index e3cc90f0..f51d247d 100644
--- a/src/Traits/BuilderCaching.php
+++ b/src/Traits/BuilderCaching.php
@@ -31,7 +31,7 @@ public function withoutGlobalScope($scope)
return parent::withoutGlobalScope($scope);
}
- public function withoutGlobalScopes(array $scopes = null)
+ public function withoutGlobalScopes(?array $scopes = null)
{
if ($scopes !== null) {
$this->withoutGlobalScopes = $scopes;
diff --git a/src/Traits/Caching.php b/src/Traits/Caching.php
index 5d5fccb9..fcf85247 100644
--- a/src/Traits/Caching.php
+++ b/src/Traits/Caching.php
@@ -41,7 +41,7 @@ public function applyScopes()
if ($this->scopesAreApplied) {
return $this;
}
-
+
return parent::applyScopes();
}
@@ -170,7 +170,7 @@ protected function makeCacheKey(
?? Container::getInstance()
->make("db")
->query();
-
+
if (
$this->query
&& method_exists($this->query, "getQuery")
@@ -241,7 +241,7 @@ protected function checkCooldownAndRemoveIfExpired(Model $instance)
if (
! $cacheCooldown
- || (new Carbon)->now()->diffInSeconds($invalidatedAt) < $cacheCooldown
+ || (new Carbon)->now()->diffInSeconds($invalidatedAt, true) < $cacheCooldown
) {
return;
}
@@ -263,6 +263,15 @@ protected function checkCooldownAndRemoveIfExpired(Model $instance)
protected function checkCooldownAndFlushAfterPersisting(Model $instance, string $relationship = "")
{
+ /**
+ * Our usage of the library currently expects model caches to be flushed in the usual way, even
+ * whilst code is run in a `runDisabled` callback. Leaving this check in place introduced all
+ * sorts of issues where caches weren't being flushed where they needed to be.
+ */
+ // if (! $this->isCachable()) {
+ // return;
+ // }
+
[$cacheCooldown, $invalidatedAt] = $instance->getModelCacheCooldown($instance);
if (! $cacheCooldown) {
@@ -281,7 +290,7 @@ protected function checkCooldownAndFlushAfterPersisting(Model $instance, string
$this->setCacheCooldownSavedAtTimestamp($instance);
- if ((new Carbon)->now()->diffInSeconds($invalidatedAt) >= $cacheCooldown) {
+ if ((new Carbon)->now()->diffInSeconds($invalidatedAt, true) >= $cacheCooldown) {
$instance->flushCache();
if ($relationship) {
@@ -295,6 +304,11 @@ public function isCachable() : bool
$isCacheDisabled = ! Container::getInstance()
->make("config")
->get("laravel-model-caching.enabled");
+
+ if ($isCacheDisabled) {
+ return false;
+ }
+
$allRelationshipsAreCachable = true;
if (
@@ -311,7 +325,7 @@ public function isCachable() : bool
) {
return $carry;
}
-
+
$relatedModel = $this->model->$related()->getRelated();
if (
@@ -327,7 +341,6 @@ public function isCachable() : bool
}
return $this->isCachable
- && ! $isCacheDisabled
&& $allRelationshipsAreCachable;
}
diff --git a/src/Traits/ModelCaching.php b/src/Traits/ModelCaching.php
index 1f428c36..b18927d7 100644
--- a/src/Traits/ModelCaching.php
+++ b/src/Traits/ModelCaching.php
@@ -22,6 +22,11 @@ public function __get($key)
?? 0;
}
+ if ($key === "query") {
+ return $this->query
+ ?? $this->newModelQuery();
+ }
+
return parent::__get($key);
}
@@ -160,7 +165,7 @@ public function scopeDisableCache(EloquentBuilder $query) : EloquentBuilder
public function scopeWithCacheCooldownSeconds(
EloquentBuilder $query,
- int $seconds = null
+ ?int $seconds = null
) : EloquentBuilder {
if (! $seconds) {
$seconds = $this->cacheCooldownSeconds;
diff --git a/tests/CreatesApplication.php b/tests/CreatesApplication.php
index b402ab3a..7b70d647 100644
--- a/tests/CreatesApplication.php
+++ b/tests/CreatesApplication.php
@@ -139,18 +139,26 @@ protected function getEnvironmentSetUp($app)
]);
}
- public function appVersionEightAndUp(): bool
+ public function appVersionEightAndNine(): bool
{
- return version_compare(app()->version(), '8.0.0', '>=');
+ return version_compare(app()->version(), '8.0.0', '>=')
+ && version_compare(app()->version(), '10.0.0', '<');
}
public function appVersionFiveBetweenSeven(): bool
{
- return version_compare(app()->version(), '5.6.0', '>=') && version_compare(app()->version(), '8.0.0', '<');
+ return version_compare(app()->version(), '5.6.0', '>=')
+ && version_compare(app()->version(), '8.0.0', '<');
}
public function appVersionOld(): bool
{
- return version_compare(app()->version(), '5.4.0', '>=') && version_compare(app()->version(), '5.6.0', '<');
+ return version_compare(app()->version(), '5.4.0', '>=')
+ && version_compare(app()->version(), '5.6.0', '<');
+ }
+
+ public function appVersionTen(): bool
+ {
+ return version_compare(app()->version(), '10.0.0', '>=');
}
}
diff --git a/tests/Feature/PaginationTest.php b/tests/Feature/PaginationTest.php
index 465ec823..ab8e751c 100644
--- a/tests/Feature/PaginationTest.php
+++ b/tests/Feature/PaginationTest.php
@@ -7,8 +7,14 @@ class PaginationTest extends FeatureTestCase
{
public function testPaginationProvidesDifferentLinksOnDifferentPages()
{
+ // Checking the version start with 10.0.
+ if ($this->appVersionTen()) {
+ $page1ActiveLink = '1';
+ $page2ActiveLink = '2';
+ }
+
// Checking the version start with 8.0.
- if ($this->appVersionEightAndUp()) {
+ if ($this->appVersionEightAndNine()) {
$page1ActiveLink = '1';
$page2ActiveLink = '2';
}
@@ -39,8 +45,14 @@ public function testPaginationProvidesDifferentLinksOnDifferentPages()
public function testAdvancedPagination()
{
+ // Checking the version start with 10.0.
+ if ($this->appVersionTen()) {
+ $page1ActiveLink = '1';
+ $page2ActiveLink = '2';
+ }
+
// Checking the version start with 8.0.
- if ($this->appVersionEightAndUp()) {
+ if ($this->appVersionEightAndNine()) {
$page1ActiveLink = '1';
$page2ActiveLink = '2';
}
@@ -62,8 +74,14 @@ public function testAdvancedPagination()
public function testCustomPagination()
{
+ // Checking the version start with 10.0.
+ if ($this->appVersionTen()) {
+ $page1ActiveLink = '1';
+ $page2ActiveLink = '2';
+ }
+
// Checking the version start with 8.0.
- if ($this->appVersionEightAndUp()) {
+ if ($this->appVersionEightAndNine()) {
$page1ActiveLink = '1';
$page2ActiveLink = '2';
}
diff --git a/tests/Integration/CachedBuilder/PaginateTest.php b/tests/Integration/CachedBuilder/PaginateTest.php
index 0ac4ead0..5d95b3d3 100644
--- a/tests/Integration/CachedBuilder/PaginateTest.php
+++ b/tests/Integration/CachedBuilder/PaginateTest.php
@@ -36,7 +36,14 @@ public function testPaginationIsCached()
public function testPaginationReturnsCorrectLinks()
{
- if ($this->appVersionEightAndUp()) {
+ // Checking the version start with 10.0.
+ if ($this->appVersionTen()) {
+ $page1ActiveLink = '1';
+ $page2ActiveLink = '2';
+ $page24ActiveLink = '24';
+ }
+
+ if ($this->appVersionEightAndNine()) {
$page1ActiveLink = '1';
$page2ActiveLink = '2';
$page24ActiveLink = '24';
@@ -71,7 +78,14 @@ public function testPaginationReturnsCorrectLinks()
public function testPaginationWithOptionsReturnsCorrectLinks()
{
- if ($this->appVersionEightAndUp()) {
+ // Checking the version start with 10.0.
+ if ($this->appVersionTen()) {
+ $page1ActiveLink = '1';
+ $page2ActiveLink = '2';
+ $page24ActiveLink = '24';
+ }
+
+ if ($this->appVersionEightAndNine()) {
$page1ActiveLink = '1';
$page2ActiveLink = '2';
$page24ActiveLink = '24';
@@ -106,7 +120,14 @@ public function testPaginationWithOptionsReturnsCorrectLinks()
public function testPaginationWithCustomOptionsReturnsCorrectLinks()
{
- if ($this->appVersionEightAndUp()) {
+ // Checking the version start with 10.0.
+ if ($this->appVersionTen()) {
+ $page1ActiveLink = '1';
+ $page2ActiveLink = '2';
+ $page24ActiveLink = '24';
+ }
+
+ if ($this->appVersionEightAndNine()) {
$page1ActiveLink = '1';
$page2ActiveLink = '2';
$page24ActiveLink = '24';
diff --git a/tests/Integration/CachedBuilder/WhereJsonContainsTest.php b/tests/Integration/CachedBuilder/WhereJsonContainsTest.php
index 3dd62c8c..3811d6f6 100644
--- a/tests/Integration/CachedBuilder/WhereJsonContainsTest.php
+++ b/tests/Integration/CachedBuilder/WhereJsonContainsTest.php
@@ -17,9 +17,9 @@ protected function getEnvironmentSetUp($app)
parent::getEnvironmentSetUp($app);
$app['config']->set('database.default', 'pgsql');
- $app['config']->set('database.connections.pgsql.host', env("PGSQL_HOST", "127.0.0.1"));
+ $app['config']->set('database.connections.pgsql.host', env("PGSQL_HOST", "pgsql"));
$app['config']->set('database.connections.pgsql.database', env("PGSQL_DATABASE", "testing"));
- $app['config']->set('database.connections.pgsql.username', env("PGSQL_USERNAME", "homestead"));
+ $app['config']->set('database.connections.pgsql.username', env("PGSQL_USERNAME", "forge"));
$app['config']->set('database.connections.pgsql.password', env("PGSQL_PASSWORD", "secret"));
}
diff --git a/tests/Integration/CachedModelTest.php b/tests/Integration/CachedModelTest.php
index af6e2524..dc932645 100644
--- a/tests/Integration/CachedModelTest.php
+++ b/tests/Integration/CachedModelTest.php
@@ -1,11 +1,11 @@
withCacheCooldownSeconds(1)
->first();
-
+
[$usesCacheCooldown, $expiresAt, $savedAt] = $method->invokeArgs($author, [$author]);
$this->assertEquals($usesCacheCooldown, 1);
@@ -188,7 +188,7 @@ public function testModelCacheDoesntInvalidateDuringCooldownPeriod()
->get();
$uncachedAuthors = (new UncachedAuthor)
->get();
- sleep(2);
+ sleep(3);
$authorsAfterCooldown = (new AuthorWithCooldown)
->get();
diff --git a/tests/NovaTestCase.php b/tests/NovaTestCase.php
index 9a25ec4b..d1885ade 100644
--- a/tests/NovaTestCase.php
+++ b/tests/NovaTestCase.php
@@ -1,5 +1,7 @@
authenticate();
+ $this->withoutMiddleware();
+
+ Artisan::call("nova:publish");
}
protected function authenticate()
@@ -54,6 +61,7 @@ protected function getPackageProviders($app)
NovaCoreServiceProvider::class,
\Laravel\Nova\NovaServiceProvider::class,
NovaServiceProvider::class,
+ ServiceProvider::class,
]
);
}
diff --git a/tools/phpcs b/tools/phpcs
deleted file mode 120000
index 9a822ebb..00000000
--- a/tools/phpcs
+++ /dev/null
@@ -1 +0,0 @@
-/home/forge/.phive/phars/phpcs-3.5.6.phar
\ No newline at end of file
diff --git a/tools/phpmd b/tools/phpmd
deleted file mode 120000
index 7649801a..00000000
--- a/tools/phpmd
+++ /dev/null
@@ -1 +0,0 @@
-/home/forge/.phive/phars/phpmd-2.7.0.phar
\ No newline at end of file
diff --git a/tools/phpunit b/tools/phpunit
deleted file mode 120000
index c8a2e31f..00000000
--- a/tools/phpunit
+++ /dev/null
@@ -1 +0,0 @@
-/home/forge/.phive/phars/phpunit-9.3.10.phar
\ No newline at end of file