(Grav GitSync) Automatic Commit from RealStickman

This commit is contained in:
RealStickman 2022-10-23 13:44:02 +02:00 committed by GitSync
parent 0643fa0f2d
commit 6d1184df78
38 changed files with 634 additions and 219 deletions

View File

@ -1,3 +1,16 @@
# v1.10.37.1
## 10/08/2022
1. [](#bugfix)
* Removed new GumRoad cart icon + new button styling [getgrav/grav#3631](https://github.com/getgrav/grav/issues/3631)
# v1.10.37
## 10/05/2022
1. [](#improved)
* Updated vendor libraries to latest versions
* Removed a reference to `SwiftMailer` library to support new **Email** plugin v4.0
# v1.10.36 # v1.10.36
## 09/08/2022 ## 09/08/2022

View File

@ -1,7 +1,7 @@
name: Admin Panel name: Admin Panel
slug: admin slug: admin
type: plugin type: plugin
version: 1.10.36 version: 1.10.37.1
description: Adds an advanced administration panel to manage your site description: Adds an advanced administration panel to manage your site
icon: empire icon: empire
author: author:

View File

@ -487,11 +487,8 @@ class LoginController extends AdminController
throw new \RuntimeException('Sending email failed'); throw new \RuntimeException('Sending email failed');
} }
// For testing only!
//Admin::DEBUG && Admin::addDebugMessage(sprintf('Email sent to %s', $to), $body);
$this->setMessage($this->translate('PLUGIN_ADMIN.FORGOT_INSTRUCTIONS_SENT_VIA_EMAIL')); $this->setMessage($this->translate('PLUGIN_ADMIN.FORGOT_INSTRUCTIONS_SENT_VIA_EMAIL'));
} catch (\RuntimeException|\Swift_SwiftException $e) { } catch (\Exception $e) {
$rateLimiter->resetRateLimit($username); $rateLimiter->resetRateLimit($username);
/** @var Debugger $debugger */ /** @var Debugger $debugger */

View File

@ -190,16 +190,16 @@
}, },
{ {
"name": "scssphp/scssphp", "name": "scssphp/scssphp",
"version": "v1.10.4", "version": "v1.11.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/scssphp/scssphp.git", "url": "https://github.com/scssphp/scssphp.git",
"reference": "8ed20753db2d3d82629e6f5d35535bbbd3893b0c" "reference": "33749d12c2569bb24071f94e9af828662dabb068"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/scssphp/scssphp/zipball/8ed20753db2d3d82629e6f5d35535bbbd3893b0c", "url": "https://api.github.com/repos/scssphp/scssphp/zipball/33749d12c2569bb24071f94e9af828662dabb068",
"reference": "8ed20753db2d3d82629e6f5d35535bbbd3893b0c", "reference": "33749d12c2569bb24071f94e9af828662dabb068",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -264,9 +264,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/scssphp/scssphp/issues", "issues": "https://github.com/scssphp/scssphp/issues",
"source": "https://github.com/scssphp/scssphp/tree/v1.10.4" "source": "https://github.com/scssphp/scssphp/tree/v1.11.0"
}, },
"time": "2022-07-26T16:28:33+00:00" "time": "2022-09-02T21:24:55+00:00"
} }
], ],
"packages-dev": [ "packages-dev": [
@ -818,16 +818,16 @@
}, },
{ {
"name": "guzzlehttp/promises", "name": "guzzlehttp/promises",
"version": "1.5.1", "version": "1.5.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/guzzle/promises.git", "url": "https://github.com/guzzle/promises.git",
"reference": "fe752aedc9fd8fcca3fe7ad05d419d32998a06da" "reference": "b94b2807d85443f9719887892882d0329d1e2598"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/guzzle/promises/zipball/fe752aedc9fd8fcca3fe7ad05d419d32998a06da", "url": "https://api.github.com/repos/guzzle/promises/zipball/b94b2807d85443f9719887892882d0329d1e2598",
"reference": "fe752aedc9fd8fcca3fe7ad05d419d32998a06da", "reference": "b94b2807d85443f9719887892882d0329d1e2598",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -882,7 +882,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/guzzle/promises/issues", "issues": "https://github.com/guzzle/promises/issues",
"source": "https://github.com/guzzle/promises/tree/1.5.1" "source": "https://github.com/guzzle/promises/tree/1.5.2"
}, },
"funding": [ "funding": [
{ {
@ -898,7 +898,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2021-10-22T20:56:57+00:00" "time": "2022-08-28T14:55:35+00:00"
}, },
{ {
"name": "guzzlehttp/psr7", "name": "guzzlehttp/psr7",
@ -1987,16 +1987,16 @@
}, },
{ {
"name": "sebastian/comparator", "name": "sebastian/comparator",
"version": "3.0.3", "version": "3.0.5",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/comparator.git", "url": "https://github.com/sebastianbergmann/comparator.git",
"reference": "1071dfcef776a57013124ff35e1fc41ccd294758" "reference": "1dc7ceb4a24aede938c7af2a9ed1de09609ca770"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1071dfcef776a57013124ff35e1fc41ccd294758", "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1dc7ceb4a24aede938c7af2a9ed1de09609ca770",
"reference": "1071dfcef776a57013124ff35e1fc41ccd294758", "reference": "1dc7ceb4a24aede938c7af2a9ed1de09609ca770",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -2049,7 +2049,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/sebastianbergmann/comparator/issues", "issues": "https://github.com/sebastianbergmann/comparator/issues",
"source": "https://github.com/sebastianbergmann/comparator/tree/3.0.3" "source": "https://github.com/sebastianbergmann/comparator/tree/3.0.5"
}, },
"funding": [ "funding": [
{ {
@ -2057,7 +2057,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2020-11-30T08:04:30+00:00" "time": "2022-09-14T12:31:48+00:00"
}, },
{ {
"name": "sebastian/diff", "name": "sebastian/diff",
@ -2190,16 +2190,16 @@
}, },
{ {
"name": "sebastian/exporter", "name": "sebastian/exporter",
"version": "3.1.4", "version": "3.1.5",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/exporter.git", "url": "https://github.com/sebastianbergmann/exporter.git",
"reference": "0c32ea2e40dbf59de29f3b49bf375176ce7dd8db" "reference": "73a9676f2833b9a7c36968f9d882589cd75511e6"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/0c32ea2e40dbf59de29f3b49bf375176ce7dd8db", "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/73a9676f2833b9a7c36968f9d882589cd75511e6",
"reference": "0c32ea2e40dbf59de29f3b49bf375176ce7dd8db", "reference": "73a9676f2833b9a7c36968f9d882589cd75511e6",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -2255,7 +2255,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/sebastianbergmann/exporter/issues", "issues": "https://github.com/sebastianbergmann/exporter/issues",
"source": "https://github.com/sebastianbergmann/exporter/tree/3.1.4" "source": "https://github.com/sebastianbergmann/exporter/tree/3.1.5"
}, },
"funding": [ "funding": [
{ {
@ -2263,7 +2263,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2021-11-11T13:51:24+00:00" "time": "2022-09-14T06:00:17+00:00"
}, },
{ {
"name": "sebastian/global-state", "name": "sebastian/global-state",
@ -2596,16 +2596,16 @@
}, },
{ {
"name": "symfony/browser-kit", "name": "symfony/browser-kit",
"version": "v4.4.37", "version": "v4.4.44",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/browser-kit.git", "url": "https://github.com/symfony/browser-kit.git",
"reference": "6e81008cac62369871cb6b8de64576ed138e3998" "reference": "2a1ff40723ef6b29c8229a860a9c8f815ad7dbbb"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/browser-kit/zipball/6e81008cac62369871cb6b8de64576ed138e3998", "url": "https://api.github.com/repos/symfony/browser-kit/zipball/2a1ff40723ef6b29c8229a860a9c8f815ad7dbbb",
"reference": "6e81008cac62369871cb6b8de64576ed138e3998", "reference": "2a1ff40723ef6b29c8229a860a9c8f815ad7dbbb",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -2648,7 +2648,7 @@
"description": "Simulates the behavior of a web browser, allowing you to make requests, click on links and submit forms programmatically", "description": "Simulates the behavior of a web browser, allowing you to make requests, click on links and submit forms programmatically",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/browser-kit/tree/v4.4.37" "source": "https://github.com/symfony/browser-kit/tree/v4.4.44"
}, },
"funding": [ "funding": [
{ {
@ -2664,20 +2664,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-01-02T09:41:36+00:00" "time": "2022-07-25T12:56:14+00:00"
}, },
{ {
"name": "symfony/console", "name": "symfony/console",
"version": "v4.4.43", "version": "v4.4.45",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/console.git", "url": "https://github.com/symfony/console.git",
"reference": "8a2628d2d5639f35113dc1b833ecd91e1ed1cf46" "reference": "28b77970939500fb04180166a1f716e75a871ef8"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/8a2628d2d5639f35113dc1b833ecd91e1ed1cf46", "url": "https://api.github.com/repos/symfony/console/zipball/28b77970939500fb04180166a1f716e75a871ef8",
"reference": "8a2628d2d5639f35113dc1b833ecd91e1ed1cf46", "reference": "28b77970939500fb04180166a1f716e75a871ef8",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -2738,7 +2738,7 @@
"description": "Eases the creation of beautiful and testable command line interfaces", "description": "Eases the creation of beautiful and testable command line interfaces",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/console/tree/v4.4.43" "source": "https://github.com/symfony/console/tree/v4.4.45"
}, },
"funding": [ "funding": [
{ {
@ -2754,20 +2754,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-06-23T12:22:25+00:00" "time": "2022-08-17T14:50:19+00:00"
}, },
{ {
"name": "symfony/css-selector", "name": "symfony/css-selector",
"version": "v4.4.37", "version": "v4.4.44",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/css-selector.git", "url": "https://github.com/symfony/css-selector.git",
"reference": "0628e6c6d7c92f1a7bae543959bdc17347be2436" "reference": "bd0a6737e48de45b4b0b7b6fc98c78404ddceaed"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/css-selector/zipball/0628e6c6d7c92f1a7bae543959bdc17347be2436", "url": "https://api.github.com/repos/symfony/css-selector/zipball/bd0a6737e48de45b4b0b7b6fc98c78404ddceaed",
"reference": "0628e6c6d7c92f1a7bae543959bdc17347be2436", "reference": "bd0a6737e48de45b4b0b7b6fc98c78404ddceaed",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -2804,7 +2804,7 @@
"description": "Converts CSS selectors to XPath expressions", "description": "Converts CSS selectors to XPath expressions",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/css-selector/tree/v4.4.37" "source": "https://github.com/symfony/css-selector/tree/v4.4.44"
}, },
"funding": [ "funding": [
{ {
@ -2820,7 +2820,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-01-02T09:41:36+00:00" "time": "2022-06-27T13:16:42+00:00"
}, },
{ {
"name": "symfony/deprecation-contracts", "name": "symfony/deprecation-contracts",
@ -2891,16 +2891,16 @@
}, },
{ {
"name": "symfony/dom-crawler", "name": "symfony/dom-crawler",
"version": "v4.4.42", "version": "v4.4.45",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/dom-crawler.git", "url": "https://github.com/symfony/dom-crawler.git",
"reference": "be5a04618e5d44e71d013f177df80d3ec4b192a0" "reference": "4b8daf6c56801e6d664224261cb100b73edc78a5"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/dom-crawler/zipball/be5a04618e5d44e71d013f177df80d3ec4b192a0", "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/4b8daf6c56801e6d664224261cb100b73edc78a5",
"reference": "be5a04618e5d44e71d013f177df80d3ec4b192a0", "reference": "4b8daf6c56801e6d664224261cb100b73edc78a5",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -2945,7 +2945,7 @@
"description": "Eases DOM navigation for HTML and XML documents", "description": "Eases DOM navigation for HTML and XML documents",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/dom-crawler/tree/v4.4.42" "source": "https://github.com/symfony/dom-crawler/tree/v4.4.45"
}, },
"funding": [ "funding": [
{ {
@ -2961,20 +2961,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-04-30T18:34:00+00:00" "time": "2022-08-03T12:57:57+00:00"
}, },
{ {
"name": "symfony/event-dispatcher", "name": "symfony/event-dispatcher",
"version": "v4.4.42", "version": "v4.4.44",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/event-dispatcher.git", "url": "https://github.com/symfony/event-dispatcher.git",
"reference": "708e761740c16b02c86e3f0c932018a06b895d40" "reference": "1e866e9e5c1b22168e0ce5f0b467f19bba61266a"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/708e761740c16b02c86e3f0c932018a06b895d40", "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/1e866e9e5c1b22168e0ce5f0b467f19bba61266a",
"reference": "708e761740c16b02c86e3f0c932018a06b895d40", "reference": "1e866e9e5c1b22168e0ce5f0b467f19bba61266a",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3029,7 +3029,7 @@
"description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/event-dispatcher/tree/v4.4.42" "source": "https://github.com/symfony/event-dispatcher/tree/v4.4.44"
}, },
"funding": [ "funding": [
{ {
@ -3045,7 +3045,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-05-05T15:33:49+00:00" "time": "2022-07-20T09:59:04+00:00"
}, },
{ {
"name": "symfony/event-dispatcher-contracts", "name": "symfony/event-dispatcher-contracts",
@ -3128,16 +3128,16 @@
}, },
{ {
"name": "symfony/finder", "name": "symfony/finder",
"version": "v4.4.41", "version": "v4.4.44",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/finder.git", "url": "https://github.com/symfony/finder.git",
"reference": "40790bdf293b462798882ef6da72bb49a4a6633a" "reference": "66bd787edb5e42ff59d3523f623895af05043e4f"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/40790bdf293b462798882ef6da72bb49a4a6633a", "url": "https://api.github.com/repos/symfony/finder/zipball/66bd787edb5e42ff59d3523f623895af05043e4f",
"reference": "40790bdf293b462798882ef6da72bb49a4a6633a", "reference": "66bd787edb5e42ff59d3523f623895af05043e4f",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3170,7 +3170,7 @@
"description": "Finds files and directories via an intuitive fluent interface", "description": "Finds files and directories via an intuitive fluent interface",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/finder/tree/v4.4.41" "source": "https://github.com/symfony/finder/tree/v4.4.44"
}, },
"funding": [ "funding": [
{ {
@ -3186,7 +3186,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-04-14T15:36:10+00:00" "time": "2022-07-29T07:35:46+00:00"
}, },
{ {
"name": "symfony/polyfill-ctype", "name": "symfony/polyfill-ctype",
@ -3609,16 +3609,16 @@
}, },
{ {
"name": "symfony/process", "name": "symfony/process",
"version": "v4.4.41", "version": "v4.4.44",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/process.git", "url": "https://github.com/symfony/process.git",
"reference": "9eedd60225506d56e42210a70c21bb80ca8456ce" "reference": "5cee9cdc4f7805e2699d9fd66991a0e6df8252a2"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/process/zipball/9eedd60225506d56e42210a70c21bb80ca8456ce", "url": "https://api.github.com/repos/symfony/process/zipball/5cee9cdc4f7805e2699d9fd66991a0e6df8252a2",
"reference": "9eedd60225506d56e42210a70c21bb80ca8456ce", "reference": "5cee9cdc4f7805e2699d9fd66991a0e6df8252a2",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3651,7 +3651,7 @@
"description": "Executes commands in sub-processes", "description": "Executes commands in sub-processes",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/process/tree/v4.4.41" "source": "https://github.com/symfony/process/tree/v4.4.44"
}, },
"funding": [ "funding": [
{ {
@ -3667,7 +3667,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-04-04T10:19:07+00:00" "time": "2022-06-27T13:16:42+00:00"
}, },
{ {
"name": "symfony/service-contracts", "name": "symfony/service-contracts",
@ -3754,16 +3754,16 @@
}, },
{ {
"name": "symfony/yaml", "name": "symfony/yaml",
"version": "v4.4.43", "version": "v4.4.45",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/yaml.git", "url": "https://github.com/symfony/yaml.git",
"reference": "07e392f0ef78376d080d5353c081a5e5704835bd" "reference": "aeccc4dc52a9e634f1d1eebeb21eacfdcff1053d"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/yaml/zipball/07e392f0ef78376d080d5353c081a5e5704835bd", "url": "https://api.github.com/repos/symfony/yaml/zipball/aeccc4dc52a9e634f1d1eebeb21eacfdcff1053d",
"reference": "07e392f0ef78376d080d5353c081a5e5704835bd", "reference": "aeccc4dc52a9e634f1d1eebeb21eacfdcff1053d",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3805,7 +3805,7 @@
"description": "Loads and dumps YAML files", "description": "Loads and dumps YAML files",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/yaml/tree/v4.4.43" "source": "https://github.com/symfony/yaml/tree/v4.4.45"
}, },
"funding": [ "funding": [
{ {
@ -3821,7 +3821,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-06-20T08:31:17+00:00" "time": "2022-08-02T15:47:23+00:00"
}, },
{ {
"name": "theseer/tokenizer", "name": "theseer/tokenizer",

View File

@ -1857,10 +1857,15 @@ table.noflex {
line-height: inherit !important; line-height: inherit !important;
font-family: inherit !important; font-family: inherit !important;
border-radius: 4px !important; border-radius: 4px !important;
box-shadow: inherit !important; } box-shadow: inherit !important;
border-color: transparent !important; }
#admin-main .admin-block a.gumroad-button:hover {
transform: inherit; }
#admin-main .admin-block a.gumroad-button .gumroad-button-logo { #admin-main .admin-block a.gumroad-button .gumroad-button-logo {
display: none !important; display: none !important;
background-image: none !important; } background-image: none !important; }
#admin-main .admin-block a.gumroad-button .logo-full {
display: none; }
#error { #error {
text-align: center; text-align: center;
@ -2815,6 +2820,9 @@ table.noflex {
right: 0; right: 0;
left: 0; } left: 0; }
.gumroad .cart-button {
display: none !important; }
@media only all and (max-width: 47.938em) { @media only all and (max-width: 47.938em) {
#admin-main .config-wrapper-system .form-tabs.side-tabs > .tabs-nav { #admin-main .config-wrapper-system .form-tabs.side-tabs > .tabs-nav {
display: none; display: none;

File diff suppressed because one or more lines are too long

View File

@ -1220,6 +1220,13 @@ body.sidebar-quickopen #admin-main {
} }
} }
// Gumroad
.gumroad {
.cart-button {
display: none !important;
}
}
// Config Side Tabs // Config Side Tabs
@include breakpoint(mobile-only) { @include breakpoint(mobile-only) {
#admin-main .config-wrapper-system .form-tabs.side-tabs { #admin-main .config-wrapper-system .form-tabs.side-tabs {

View File

@ -124,8 +124,17 @@
font-family: inherit !important; font-family: inherit !important;
border-radius: 4px !important; border-radius: 4px !important;
box-shadow: inherit !important; box-shadow: inherit !important;
border-color: transparent !important;
&:hover {
transform: inherit;
}
.gumroad-button-logo { .gumroad-button-logo {
display: none !important; display: none !important;
background-image: none !important; background-image: none !important;
} }
.logo-full {
display: none;
}
} }

View File

@ -9,4 +9,4 @@ if (PHP_VERSION_ID < 50600) {
require_once __DIR__ . '/composer/autoload_real.php'; require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInit38a448a612c5797456d245c809d4a914::getLoader(); return ComposerAutoloaderInit98c98c1c3d67f21a128f935fe4a74897::getLoader();

View File

@ -66,6 +66,16 @@ if (PHP_VERSION_ID < 80000) {
return $operation ? flock($this->handle, $operation) : true; return $operation ? flock($this->handle, $operation) : true;
} }
public function stream_seek($offset, $whence)
{
if (0 === fseek($this->handle, $offset, $whence)) {
$this->position = ftell($this->handle);
return true;
}
return false;
}
public function stream_tell() public function stream_tell()
{ {
return $this->position; return $this->position;
@ -98,7 +108,10 @@ if (PHP_VERSION_ID < 80000) {
} }
} }
if (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) { if (
(function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true))
|| (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper'))
) {
include("phpvfscomposer://" . __DIR__ . '/..'.'/p3k/picofeed/picofeed'); include("phpvfscomposer://" . __DIR__ . '/..'.'/p3k/picofeed/picofeed');
exit(0); exit(0);
} }

View File

@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer // autoload_real.php @generated by Composer
class ComposerAutoloaderInit38a448a612c5797456d245c809d4a914 class ComposerAutoloaderInit98c98c1c3d67f21a128f935fe4a74897
{ {
private static $loader; private static $loader;
@ -24,18 +24,18 @@ class ComposerAutoloaderInit38a448a612c5797456d245c809d4a914
require __DIR__ . '/platform_check.php'; require __DIR__ . '/platform_check.php';
spl_autoload_register(array('ComposerAutoloaderInit38a448a612c5797456d245c809d4a914', 'loadClassLoader'), true, true); spl_autoload_register(array('ComposerAutoloaderInit98c98c1c3d67f21a128f935fe4a74897', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__)); self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInit38a448a612c5797456d245c809d4a914', 'loadClassLoader')); spl_autoload_unregister(array('ComposerAutoloaderInit98c98c1c3d67f21a128f935fe4a74897', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php'; require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit38a448a612c5797456d245c809d4a914::getInitializer($loader)); call_user_func(\Composer\Autoload\ComposerStaticInit98c98c1c3d67f21a128f935fe4a74897::getInitializer($loader));
$loader->register(true); $loader->register(true);
$includeFiles = \Composer\Autoload\ComposerStaticInit38a448a612c5797456d245c809d4a914::$files; $includeFiles = \Composer\Autoload\ComposerStaticInit98c98c1c3d67f21a128f935fe4a74897::$files;
foreach ($includeFiles as $fileIdentifier => $file) { foreach ($includeFiles as $fileIdentifier => $file) {
composerRequire38a448a612c5797456d245c809d4a914($fileIdentifier, $file); composerRequire98c98c1c3d67f21a128f935fe4a74897($fileIdentifier, $file);
} }
return $loader; return $loader;
@ -47,7 +47,7 @@ class ComposerAutoloaderInit38a448a612c5797456d245c809d4a914
* @param string $file * @param string $file
* @return void * @return void
*/ */
function composerRequire38a448a612c5797456d245c809d4a914($fileIdentifier, $file) function composerRequire98c98c1c3d67f21a128f935fe4a74897($fileIdentifier, $file)
{ {
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;

View File

@ -4,7 +4,7 @@
namespace Composer\Autoload; namespace Composer\Autoload;
class ComposerStaticInit38a448a612c5797456d245c809d4a914 class ComposerStaticInit98c98c1c3d67f21a128f935fe4a74897
{ {
public static $files = array ( public static $files = array (
'7e9bd612cc444b3eed788ebbe46263a0' => __DIR__ . '/..' . '/laminas/laminas-zendframework-bridge/src/autoload.php', '7e9bd612cc444b3eed788ebbe46263a0' => __DIR__ . '/..' . '/laminas/laminas-zendframework-bridge/src/autoload.php',
@ -63,10 +63,10 @@ class ComposerStaticInit38a448a612c5797456d245c809d4a914
public static function getInitializer(ClassLoader $loader) public static function getInitializer(ClassLoader $loader)
{ {
return \Closure::bind(function () use ($loader) { return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInit38a448a612c5797456d245c809d4a914::$prefixLengthsPsr4; $loader->prefixLengthsPsr4 = ComposerStaticInit98c98c1c3d67f21a128f935fe4a74897::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit38a448a612c5797456d245c809d4a914::$prefixDirsPsr4; $loader->prefixDirsPsr4 = ComposerStaticInit98c98c1c3d67f21a128f935fe4a74897::$prefixDirsPsr4;
$loader->prefixesPsr0 = ComposerStaticInit38a448a612c5797456d245c809d4a914::$prefixesPsr0; $loader->prefixesPsr0 = ComposerStaticInit98c98c1c3d67f21a128f935fe4a74897::$prefixesPsr0;
$loader->classMap = ComposerStaticInit38a448a612c5797456d245c809d4a914::$classMap; $loader->classMap = ComposerStaticInit98c98c1c3d67f21a128f935fe4a74897::$classMap;
}, null, ClassLoader::class); }, null, ClassLoader::class);
} }

View File

@ -193,17 +193,17 @@
}, },
{ {
"name": "scssphp/scssphp", "name": "scssphp/scssphp",
"version": "v1.10.4", "version": "v1.11.0",
"version_normalized": "1.10.4.0", "version_normalized": "1.11.0.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/scssphp/scssphp.git", "url": "https://github.com/scssphp/scssphp.git",
"reference": "8ed20753db2d3d82629e6f5d35535bbbd3893b0c" "reference": "33749d12c2569bb24071f94e9af828662dabb068"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/scssphp/scssphp/zipball/8ed20753db2d3d82629e6f5d35535bbbd3893b0c", "url": "https://api.github.com/repos/scssphp/scssphp/zipball/33749d12c2569bb24071f94e9af828662dabb068",
"reference": "8ed20753db2d3d82629e6f5d35535bbbd3893b0c", "reference": "33749d12c2569bb24071f94e9af828662dabb068",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -226,7 +226,7 @@
"ext-iconv": "Can be used as fallback when ext-mbstring is not available", "ext-iconv": "Can be used as fallback when ext-mbstring is not available",
"ext-mbstring": "For best performance, mbstring should be installed as it is faster than ext-iconv" "ext-mbstring": "For best performance, mbstring should be installed as it is faster than ext-iconv"
}, },
"time": "2022-07-26T16:28:33+00:00", "time": "2022-09-02T21:24:55+00:00",
"bin": [ "bin": [
"bin/pscss" "bin/pscss"
], ],
@ -270,7 +270,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/scssphp/scssphp/issues", "issues": "https://github.com/scssphp/scssphp/issues",
"source": "https://github.com/scssphp/scssphp/tree/v1.10.4" "source": "https://github.com/scssphp/scssphp/tree/v1.11.0"
}, },
"install-path": "../scssphp/scssphp" "install-path": "../scssphp/scssphp"
} }

View File

@ -3,7 +3,7 @@
'name' => 'getgrav/grav-plugin-admin', 'name' => 'getgrav/grav-plugin-admin',
'pretty_version' => 'dev-develop', 'pretty_version' => 'dev-develop',
'version' => 'dev-develop', 'version' => 'dev-develop',
'reference' => '713002e2b83b9660bfcefe5bb0d76954eedf2b90', 'reference' => '97ab52df8179fad32d1190b530c32053b84d5979',
'type' => 'grav-plugin', 'type' => 'grav-plugin',
'install_path' => __DIR__ . '/../../', 'install_path' => __DIR__ . '/../../',
'aliases' => array(), 'aliases' => array(),
@ -13,7 +13,7 @@
'getgrav/grav-plugin-admin' => array( 'getgrav/grav-plugin-admin' => array(
'pretty_version' => 'dev-develop', 'pretty_version' => 'dev-develop',
'version' => 'dev-develop', 'version' => 'dev-develop',
'reference' => '713002e2b83b9660bfcefe5bb0d76954eedf2b90', 'reference' => '97ab52df8179fad32d1190b530c32053b84d5979',
'type' => 'grav-plugin', 'type' => 'grav-plugin',
'install_path' => __DIR__ . '/../../', 'install_path' => __DIR__ . '/../../',
'aliases' => array(), 'aliases' => array(),
@ -53,9 +53,9 @@
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'scssphp/scssphp' => array( 'scssphp/scssphp' => array(
'pretty_version' => 'v1.10.4', 'pretty_version' => 'v1.11.0',
'version' => '1.10.4.0', 'version' => '1.11.0.0',
'reference' => '8ed20753db2d3d82629e6f5d35535bbbd3893b0c', 'reference' => '33749d12c2569bb24071f94e9af828662dabb068',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../scssphp/scssphp', 'install_path' => __DIR__ . '/../scssphp/scssphp',
'aliases' => array(), 'aliases' => array(),

View File

@ -50,16 +50,16 @@
"type": "package", "type": "package",
"package": { "package": {
"name": "sass/sass-spec", "name": "sass/sass-spec",
"version": "2022.02.24", "version": "2022.08.19",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sass/sass-spec.git", "url": "https://github.com/sass/sass-spec.git",
"reference": "f41b9bfb9a3013392f2136c79f7f3356f15fb8ba" "reference": "2bdc199723a3445d5badac3ac774105698f08861"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sass/sass-spec/zipball/f41b9bfb9a3013392f2136c79f7f3356f15fb8ba", "url": "https://api.github.com/repos/sass/sass-spec/zipball/2bdc199723a3445d5badac3ac774105698f08861",
"reference": "f41b9bfb9a3013392f2136c79f7f3356f15fb8ba", "reference": "2bdc199723a3445d5badac3ac774105698f08861",
"shasum": "" "shasum": ""
} }
} }

View File

@ -1,12 +0,0 @@
<?xml version="1.0"?>
<ruleset name="PSR12 (adapted for PHP 5.6+)">
<rule ref="PSR12">
<!-- Ignore this PHP 7.1+ sniff as long as we support PHP 5.6+ -->
<exclude name="PSR12.Properties.ConstantVisibility.NotFound"/>
<!-- This sniff doesn't ignore comment blocks -->
<!--
<exclude name="Generic.Files.LineLength"/>
-->
</rule>
</ruleset>

View File

@ -7947,7 +7947,11 @@ EOL;
$max = 100; $max = 100;
} }
return $number->valueInRange($change ? 0 : -$max, $max, $name); if ($scale || $assertPercent) {
return $number->valueInRange($change ? 0 : -$max, $max, $name);
}
return $number->valueInRangeWithUnit($change ? 0 : -$max, $max, $name, $checkPercent ? '%' : '');
}; };
$alpha = $getParam('alpha', 1); $alpha = $getParam('alpha', 1);
@ -8582,7 +8586,7 @@ EOL;
$color = $this->assertColor($args[0], 'color'); $color = $this->assertColor($args[0], 'color');
$amount = $this->assertNumber($args[1], 'amount'); $amount = $this->assertNumber($args[1], 'amount');
$color[4] = (isset($color[4]) ? $color[4] : 1) + $amount->valueInRange(0, 1, 'amount'); $color[4] = (isset($color[4]) ? $color[4] : 1) + $amount->valueInRangeWithUnit(0, 1, 'amount', '');
$color[4] = min(1, max(0, $color[4])); $color[4] = min(1, max(0, $color[4]));
return $color; return $color;
@ -8601,7 +8605,7 @@ EOL;
$color = $this->assertColor($args[0], 'color'); $color = $this->assertColor($args[0], 'color');
$amount = $this->assertNumber($args[1], 'amount'); $amount = $this->assertNumber($args[1], 'amount');
$color[4] = (isset($color[4]) ? $color[4] : 1) - $amount->valueInRange(0, 1, 'amount'); $color[4] = (isset($color[4]) ? $color[4] : 1) - $amount->valueInRangeWithUnit(0, 1, 'amount', '');
$color[4] = min(1, max(0, $color[4])); $color[4] = min(1, max(0, $color[4]));
return $color; return $color;
@ -8769,7 +8773,7 @@ will be an error in future versions of Sass.\n on line $line of $fname";
protected function libNth($args) protected function libNth($args)
{ {
$list = $this->coerceList($args[0], ',', false); $list = $this->coerceList($args[0], ',', false);
$n = $this->assertNumber($args[1])->getDimension(); $n = $this->assertInteger($args[1]);
if ($n > 0) { if ($n > 0) {
$n--; $n--;
@ -8784,7 +8788,7 @@ will be an error in future versions of Sass.\n on line $line of $fname";
protected function libSetNth($args) protected function libSetNth($args)
{ {
$list = $this->coerceList($args[0]); $list = $this->coerceList($args[0]);
$n = $this->assertNumber($args[1])->getDimension(); $n = $this->assertInteger($args[1]);
if ($n > 0) { if ($n > 0) {
$n--; $n--;
@ -9589,7 +9593,25 @@ will be an error in future versions of Sass.\n on line $line of $fname";
protected function libRandom($args) protected function libRandom($args)
{ {
if (isset($args[0]) && $args[0] !== static::$null) { if (isset($args[0]) && $args[0] !== static::$null) {
$n = $this->assertInteger($args[0], 'limit'); $limit = $this->assertNumber($args[0], 'limit');
if ($limit->hasUnits()) {
$unitString = $limit->unitStr();
$message = <<<TXT
random() will no longer ignore \$limit units ($limit) in a future release.
Recommendation: random(\$limit / 1$unitString) * 1$unitString
To preserve current behavior: random(\$limit / 1$unitString)
More info: https://sass-lang.com/d/random-with-units
TXT;
Warn::deprecation($this->addLocationToMessage($message));
}
$n = $this->assertInteger($limit, 'limit');
if ($n < 1) { if ($n < 1) {
throw new SassScriptException("\$limit: Must be greater than 0, was $n."); throw new SassScriptException("\$limit: Must be greater than 0, was $n.");

View File

@ -227,6 +227,16 @@ class Number extends Node implements \ArrayAccess
return \count($this->numeratorUnits) === 0 && \count($this->denominatorUnits) === 0; return \count($this->numeratorUnits) === 0 && \count($this->denominatorUnits) === 0;
} }
/**
* Returns true if the number has any units
*
* @return bool
*/
public function hasUnits()
{
return !$this->unitless();
}
/** /**
* Checks whether the number has exactly this unit * Checks whether the number has exactly this unit
* *
@ -266,7 +276,27 @@ class Number extends Node implements \ArrayAccess
try { try {
return Util::checkRange('', new Range($min, $max), $this); return Util::checkRange('', new Range($min, $max), $this);
} catch (RangeException $e) { } catch (RangeException $e) {
throw SassScriptException::forArgument(sprintf('Expected %s to be within %s%s and %s%3$s', $this, $min, $this->unitStr(), $max), $name); throw SassScriptException::forArgument(sprintf('Expected %s to be within %s%s and %s%3$s.', $this, $min, $this->unitStr(), $max), $name);
}
}
/**
* @param float|int $min
* @param float|int $max
* @param string $name
* @param string $unit
*
* @return float|int
* @throws SassScriptException
*
* @internal
*/
public function valueInRangeWithUnit($min, $max, $name, $unit)
{
try {
return Util::checkRange('', new Range($min, $max), $this);
} catch (RangeException $e) {
throw SassScriptException::forArgument(sprintf('Expected %s to be within %s%s and %s%3$s.', $this, $min, $unit, $max), $name);
} }
} }

View File

@ -2461,7 +2461,7 @@ class Parser
$whiteBefore = isset($this->buffer[$this->count - 1]) && $whiteBefore = isset($this->buffer[$this->count - 1]) &&
ctype_space($this->buffer[$this->count - 1]); ctype_space($this->buffer[$this->count - 1]);
while ($this->match($operators, $m, false) && static::$precedence[$m[1]] >= $minP) { while ($this->match($operators, $m, false) && static::$precedence[strtolower($m[1])] >= $minP) {
$whiteAfter = isset($this->buffer[$this->count]) && $whiteAfter = isset($this->buffer[$this->count]) &&
ctype_space($this->buffer[$this->count]); ctype_space($this->buffer[$this->count]);
$varAfter = isset($this->buffer[$this->count]) && $varAfter = isset($this->buffer[$this->count]) &&
@ -2485,7 +2485,7 @@ class Parser
} }
// consume higher-precedence operators on the right-hand side // consume higher-precedence operators on the right-hand side
$rhs = $this->expHelper($rhs, static::$precedence[$op] + 1); $rhs = $this->expHelper($rhs, static::$precedence[strtolower($op)] + 1);
$lhs = [Type::T_EXPRESSION, $op, $lhs, $rhs, $this->inParens, $whiteBefore, $whiteAfter]; $lhs = [Type::T_EXPRESSION, $op, $lhs, $rhs, $this->inParens, $whiteBefore, $whiteAfter];
@ -2804,6 +2804,10 @@ class Parser
$this->argValues($args) && $this->argValues($args) &&
$this->matchChar(')') $this->matchChar(')')
) { ) {
if (strtolower($name) === 'var' && \count($args) === 2 && $args[1][0] === Type::T_NULL) {
$args[1] = [null, [Type::T_STRING, '', [' ']], false];
}
$func = [Type::T_FUNCTION_CALL, $name, $args]; $func = [Type::T_FUNCTION_CALL, $name, $args];
return true; return true;

View File

@ -19,5 +19,5 @@ namespace ScssPhp\ScssPhp;
*/ */
class Version class Version
{ {
const VERSION = '1.10.4'; const VERSION = '1.11.0';
} }

View File

@ -1,3 +1,9 @@
# v1.9.0
## 10/05/2022
1. [](#new)
* Utilize the new `onPageHeaders()` event in Grav `1.7.37` to force UTF-8 encoding
# v1.8.5 # v1.8.5
## 06/09/2021 ## 06/09/2021

View File

@ -1,7 +1,7 @@
name: Feed name: Feed
type: plugin type: plugin
slug: feed slug: feed
version: 1.8.5 version: 1.9.0
description: The **Feed** plugin is a simple yet powerful add-on that lets you view a Grav Collection as **JSON**, **RSS** or **Atom** news feed. description: The **Feed** plugin is a simple yet powerful add-on that lets you view a Grav Collection as **JSON**, **RSS** or **Atom** news feed.
icon: rss icon: rss
author: author:

View File

@ -41,7 +41,8 @@ class FeedPlugin extends Plugin
['autoload', 100000], ['autoload', 100000],
['onPluginsInitialized', 0], ['onPluginsInitialized', 0],
], ],
'onBlueprintCreated' => ['onBlueprintCreated', 0] 'onBlueprintCreated' => ['onBlueprintCreated', 0],
'onPageHeaders' => ['onPageHeaders', 0]
]; ];
} }
@ -159,4 +160,19 @@ class FeedPlugin extends Plugin
$inEvent = false; $inEvent = false;
} }
} }
/**
* Force UTF-8 char-set encoding via `Content-Type` header
*
* @param Event $e
* @return void
*/
public function onPageHeaders(Event $e)
{
$headers = $e['headers'];
$content_type = $headers->{'Content-Type'} ?? null;
if ($content_type) {
$headers->{'Content-Type'} = "$content_type; charset=utf-8";
}
}
} }

View File

@ -1,3 +1,21 @@
# v7.0.2
## 10/05/2022
1. [](#bugfix)
* Fix for modular form definitions at root-level (useful for storing shared forms)
# v7.0.1
## 09/20/2022
1. [](#improved)
* Provided some basic CSS styling for new captcha field
# v7.0.0
## 09/20/2022
1. [](#new)
* Added a new custom `basic-captcha` option with **character** and **math** puzzles. No 3rd-part service required.
# v6.0.4 # v6.0.4
## 08/08/2022 ## 08/08/2022

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"version":3,"sourceRoot":"","sources":["../scss/form-styles.scss"],"names":[],"mappings":"CAGA,uBACI,6BACA,kCACA,kBACA,cACA,cAGJ,aACI,cAGJ,gBACI,kBACA,6BACA,WACA,UACA,gBACA,8BAGJ,eACI,SAKA,uBACI,aAGJ,wCACI,kBACA,kBACA,OACA,QACA,QACA,2BACA,SAGJ,0BACI,kBACA,gBACA,kBACA,qBACA,uBACA,WACA,cAEA,sCACI,aAEA,4CACI,UAGJ,wDACI,gBACA,WAGJ,gHAEI,kBACA,UAWZ,qBACI,aACA,gBAEA,mBAEA,uBACI,OACA,8CACA,eACA,kBACA,aACA,aACA,mBACA,uBACA,6BACA,0BAEA,8BACI,sBACA,sCACA,cAEA,mCACI,MAtGA,KA2GZ,0BACI,qBACA,gBAKR,4BACI,0BAKA,uCACI,aACA,iBAEA,8CACI,cAOhB,YACI,qBAEA,kBACI,eACA,eACA,kBACA,mBACA,kBAGJ,yBACI,WACA,qBACA,WACA,YACA,OACA,aACA,kBACA,kBACA,kBAEA,yBAGJ,iCACI,aAEJ,sDACI,YACA,eACA,cACA,kBAGJ,6BACI,eAMJ,8CACI,iBACA,sBAEJ,yCACI,qBAKR,eACI,oBACA,gBACA,kBACA,iBACA,sBAEA,iCACI,kBACA,kBACA,aAGJ,qBACI,qBACA,eACA,eACA,SACA,mBACA,cACA,qCAGJ,6CACI,gBACA,WAGJ,mCACI,WACA,gBAOR,eACI,kBACA,oBACA,oBACA,aACA,4BACA,6BACA,0BACA,sBACA,eACA,WACA,YACA,gBACA,iBACA,yBACA,sBACA,aAGJ,qBACI,kBACA,mBACA,WACA,OACA,yBACA,iBAGJ,4BACI,kBACA,OACA,MACA,WACA,YACA,kBACA,yCAGJ,uBACI,cACA,kBACA,gBAGJ,wBACI,oBACA,oBACA,aACA,yBACA,sBACA,8BACA,eAGJ,kCACI,aACA,mBACA,oBAGJ,mFAGI,eACA,qBAIA,6CACI,sBACA,kBACA,aACA,gBAEJ,6CACI,aACA,WACA,sBACA,cACA,iDACI,SAEJ,wDACI,aACA,WACA,YAGR,0CACI","file":"form-styles.css"}

View File

@ -1,7 +1,7 @@
name: Form name: Form
slug: form slug: form
type: plugin type: plugin
version: 6.0.4 version: 7.0.2
description: Enables forms handling and processing description: Enables forms handling and processing
icon: check-square icon: check-square
author: author:
@ -196,3 +196,127 @@ form:
label: PLUGIN_FORM.RECAPTCHA_SECRET_KEY label: PLUGIN_FORM.RECAPTCHA_SECRET_KEY
help: PLUGIN_FORM.RECAPTCHA_SECRET_KEY_HELP help: PLUGIN_FORM.RECAPTCHA_SECRET_KEY_HELP
default: '' default: ''
basic_captcha:
type: section
title: PLUGIN_FORM.BASIC_CAPTCHA
fields:
basic_captcha.type:
type: elements
label: PLUGIN_FORM.BASIC_CAPTCHA_TYPE
default: 'characters'
size: medium
options:
characters: Random Characters
math: Math Puzzle
fields:
characters:
type: element
fields:
basic_captcha.chars.length:
type: range
label: PLUGIN_FORM.BASIC_CAPTCHA_LENGTH
default: 6
validate:
min: 4
max: 12
append: characters
basic_captcha.chars.font:
type: select
label: PLUGIN_FORM.BASIC_CAPTCHA_FONT
default: zxx-noise.ttf
options:
'zxx-noise.ttf': zxx-Noise
'zxx-xed.ttf': zxx-Xed
'zxx-camo.ttf': zxx-Camo
'zxx-sans.ttf': zxx-Sans
basic_captcha.chars.size:
type: range
label: PLUGIN_FORM.BASIC_CAPTCHA_SIZE
default: 24
append: px
validate:
min: 12
max: 32
step: 2
basic_captcha.chars.bg:
type: colorpicker
size: small
label: PLUGIN_FORM.BASIC_CAPTCHA_BG_COLOR
default: '#ffffff'
basic_captcha.chars.text:
type: colorpicker
size: small
label: PLUGIN_FORM.BASIC_CAPTCHA_TEXT_COLOR
default: '#000000'
basic_captcha.chars.start_x:
type: number
label: PLUGIN_FORM.BASIC_CAPTCHA_START_X
default: 5
append: px
size: small
validate:
min: 0
type: number
basic_captcha.chars.start_y:
type: number
label: PLUGIN_FORM.BASIC_CAPTCHA_START_Y
default: 30
append: px
size: small
validate:
min: 0
type: number
basic_captcha.chars.box_width:
type: number
label: PLUGIN_FORM.BASIC_CAPTCHA_BOX_WIDTH
default: 135
append: px
size: small
validate:
min: 0
type: number
basic_captcha.chars.box_height:
type: number
label: PLUGIN_FORM.BASIC_CAPTCHA_BOX_HEIGHT
default: 40
append: px
size: small
validate:
min: 0
type: number
math:
type: element
fields:
basic_captcha.math.min:
type: number
label: PLUGIN_FORM.BASIC_CAPTCHA_MATH_MIN
default: 1
size: small
validate:
min: 0
type: number
basic_captcha.math.max:
type: number
label: PLUGIN_FORM.BASIC_CAPTCHA_MATH_MAX
default: 10
size: small
validate:
min: 1
type: number
basic_captcha.math.operators:
type: selectize
selectize:
options:
- value: '+'
text: '+ Addition'
- value: '-'
text: '- Subtraction'
- value: '*'
text: 'x Multiplication'
- value: '/'
text: '/ Division'
label: PLUGIN_FORM.BASIC_CAPTCHA_MATH_OPERATORS
validate:
type: commalist

View File

@ -0,0 +1,122 @@
<?php
namespace Grav\Plugin\Form;
use GdImage;
use Grav\Common\Grav;
class BasicCaptcha
{
protected $session = null;
protected $key = 'basic_captcha_code';
public function __construct()
{
$this->session = Grav::instance()['session'];
}
public function getCaptchaCode($length = null): string
{
$config = Grav::instance()['config']->get('plugins.form.basic_captcha');
$type = $config['type'] ?? 'characters';
if ($type == 'math') {
$min = $config['math']['min'] ?? 1;
$max = $config['math']['max'] ?? 12;
$operators = $config['math']['operators'] ?? ['+','-','*'];
$first_num = random_int($min, $max);
$second_num = random_int($min, $max);
$operator = $operators[array_rand($operators)];
// calculator
if ($operator === '-') {
if ($first_num < $second_num) {
$result = "$second_num-$first_num";
$captcha_code = $second_num-$first_num;
} else {
$result = "$first_num-$second_num";
$captcha_code = $first_num - $second_num;
}
} elseif ($operator === '*') {
$result = "{$first_num}x{$second_num}";
$captcha_code = $first_num - $second_num;
} elseif ($operator === '/') {
$result = "$first_num/ second_num";
$captcha_code = $first_num / $second_num;
} elseif ($operator === '+') {
$result = "$first_num+$second_num";
$captcha_code = $first_num + $second_num;
}
} else {
if ($length === null) {
$length = $config['chars']['length'] ?? 6;
}
$random_alpha = md5(random_bytes(64));
$captcha_code = substr($random_alpha, 0, $length);
$result = $captcha_code;
}
$this->setSession($this->key, $captcha_code);
return $result;
}
public function setSession($key, $value): void
{
$this->session->$key = $value;
}
public function getSession($key = null): ?string
{
if ($key === null) {
$key = $this->key;
}
return $this->session->$key ?? null;
}
public function createCaptchaImage($captcha_code)
{
$config = Grav::instance()['config']->get('plugins.form.basic_captcha');
$font = $config['chars']['font'] ?? 'zxx-xed.ttf';
$target_layer = imagecreatetruecolor($config['chars']['box_width'], $config['chars']['box_height']);
$bg = $this->hexToRgb($config['chars']['bg'] ?? '#ffffff');
$text = $this->hexToRgb($config['chars']['text'] ?? '#000000');
$captcha_background = imagecolorallocate($target_layer, $bg[0], $bg[1], $bg[2]);
$captcha_text_color = imagecolorallocate($target_layer, $text[0], $text[1], $text[2]);
$font_path = __DIR__ . '/../fonts/' . $font;
imagefill($target_layer, 0, 0, $captcha_background);
imagefttext($target_layer, $config['chars']['size'], 0, $config['chars']['start_x'], $config['chars']['start_y'], $captcha_text_color, $font_path, $captcha_code);
return $target_layer;
}
public function renderCaptchaImage($imageData): void
{
header("Content-type: image/jpeg");
imagejpeg($imageData);
}
public function validateCaptcha($formData): bool
{
$isValid = false;
$capchaSessionData = $this->getSession();
if ($capchaSessionData == $formData) {
$isValid = true;
}
return $isValid;
}
private function hexToRgb($hex): array
{
return sscanf($hex, "#%02x%02x%02x");
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -21,6 +21,7 @@ use Grav\Common\Yaml;
use Grav\Framework\Form\Interfaces\FormInterface; use Grav\Framework\Form\Interfaces\FormInterface;
use Grav\Framework\Psr7\Response; use Grav\Framework\Psr7\Response;
use Grav\Framework\Route\Route; use Grav\Framework\Route\Route;
use Grav\Plugin\Form\BasicCaptcha;
use Grav\Plugin\Form\Form; use Grav\Plugin\Form\Form;
use Grav\Plugin\Form\Forms; use Grav\Plugin\Form\Forms;
use Grav\Plugin\Form\TwigExtension; use Grav\Plugin\Form\TwigExtension;
@ -135,6 +136,8 @@ class FormPlugin extends Plugin
$this->grav->close($response); $this->grav->close($response);
} }
$this->processBasicCaptchaImage($uri);
$this->enable([ $this->enable([
'onPageProcessed' => ['onPageProcessed', 0], 'onPageProcessed' => ['onPageProcessed', 0],
'onPagesInitialized' => ['onPagesInitialized', 0], 'onPagesInitialized' => ['onPagesInitialized', 0],
@ -509,6 +512,21 @@ class FormPlugin extends Plugin
return; return;
} }
break; break;
case 'basic-captcha':
$captcha = new BasicCaptcha();
$captcha_value = trim($form->value('basic-captcha'));
if (!$captcha->validateCaptcha($captcha_value)) {
$message = $params['message'] ?? $this->grav['language']->translate('PLUGIN_FORM.ERROR_BASIC_CAPTCHA');
$this->grav->fireEvent('onFormValidationError', new Event([
'form' => $form,
'message' => $message
]));
$event->stopPropagation();
return;
}
break;
case 'timestamp': case 'timestamp':
$label = $params['label'] ?? 'Timestamp'; $label = $params['label'] ?? 'Timestamp';
$format = $params['format'] ?? 'Y-m-d H:i:s'; $format = $params['format'] ?? 'Y-m-d H:i:s';
@ -553,8 +571,7 @@ class FormPlugin extends Plugin
$this->grav['messages']->add($form->message, 'success'); $this->grav['messages']->add($form->message, 'success');
} }
$event['redirect'] = $url; $this->grav->redirect($url);
$event->stopPropagation();
break; break;
case 'reset': case 'reset':
if (Utils::isPositive($params)) { if (Utils::isPositive($params)) {
@ -780,7 +797,7 @@ class FormPlugin extends Plugin
*/ */
public function addFormDefinition(PageInterface $page, string $name, array $form): void public function addFormDefinition(PageInterface $page, string $name, array $form): void
{ {
$route = $page->home() ? '/' : $page->route(); $route = ($page->home() ? '/' : $page->route()) ?? '/';
if (!isset($this->forms[$route][$name])) { if (!isset($this->forms[$route][$name])) {
$form['_page_routable'] = !$page->isModule(); $form['_page_routable'] = !$page->isModule();
@ -1258,4 +1275,15 @@ class FormPlugin extends Plugin
return date(preg_replace('`(?<!\\\\)u`', sprintf('%06d', $milliseconds), $format), $timestamp); return date(preg_replace('`(?<!\\\\)u`', sprintf('%06d', $milliseconds), $format), $timestamp);
} }
protected function processBasicCaptchaImage(Uri $uri)
{
if ($uri->path() === '/forms-basic-captcha-image.jpg') {
$captcha = new BasicCaptcha();
$code = $captcha->getCaptchaCode();
$image = $captcha->createCaptchaImage($code);
$captcha->renderCaptchaImage($image);
exit;
}
}
} }

View File

@ -18,3 +18,19 @@ recaptcha:
theme: light theme: light
site_key: site_key:
secret_key: secret_key:
basic_captcha:
type: characters # options: [characters | math]
chars:
length: 6 # number of chars to output
font: zxx-noise.ttf # options: [zxx-noise.ttf | zxx-camo.ttf | zxx-xed.ttf | zxx-sans.ttf]
bg: '#cccccc' # 6-char hex color
text: '#333333' # 6-char hex color
size: 24 # font size in px
start_x: 5 # start position in x direction in px
start_y: 30 # start position in y direction in px
box_width: 135 # box width in px
box_height: 40 # box height in px
math:
min: 1 # smallest digit
max: 12 # largest digit
operators: ['+','-','*'] # operators that can be used in math

View File

@ -10,6 +10,7 @@ en:
DESTINATION_HELP: "The location where the files should be uploaded to" DESTINATION_HELP: "The location where the files should be uploaded to"
ACCEPT: "Allowed MIME Types" ACCEPT: "Allowed MIME Types"
ACCEPT_HELP: "A list of MIME Types that are allowed for upload" ACCEPT_HELP: "A list of MIME Types that are allowed for upload"
ERROR_BASIC_CAPTCHA: "Captcha failed for this form, please try again"
ERROR_VALIDATING_CAPTCHA: "reCAPTCHA bot protection has identified this form submission is problematic" ERROR_VALIDATING_CAPTCHA: "reCAPTCHA bot protection has identified this form submission is problematic"
DATA_SUMMARY: "Here is the summary of what you wrote to us:" DATA_SUMMARY: "Here is the summary of what you wrote to us:"
NO_FORM_DATA: "No form data available" NO_FORM_DATA: "No form data available"
@ -72,6 +73,21 @@ en:
DESTINATION_NOT_SPECIFIED: "Destination not specified" DESTINATION_NOT_SPECIFIED: "Destination not specified"
INVALID_MIME_TYPE: "The MIME type %s for the file %s is not accepted." INVALID_MIME_TYPE: "The MIME type %s for the file %s is not accepted."
INVALID_FILE_EXTENSION: "The File Extension for the file %s is not accepted." INVALID_FILE_EXTENSION: "The File Extension for the file %s is not accepted."
BASIC_CAPTCHA: "Basic Captcha"
BASIC_CAPTCHA_TYPE: "Captcha challenge type"
BASIC_CAPTCHA_LENGTH: "Number of characters"
BASIC_CAPTCHA_FONT: "TTF Font"
BASIC_CAPTCHA_SIZE: "Font size"
BASIC_CAPTCHA_BG_COLOR: "Background color"
BASIC_CAPTCHA_TEXT_COLOR: "Text color"
BASIC_CAPTCHA_START_X: "Text start x-position"
BASIC_CAPTCHA_START_Y: "Text start y-position"
BASIC_CAPTCHA_BOX_WIDTH: "Image width"
BASIC_CAPTCHA_BOX_HEIGHT: "Image height"
BASIC_CAPTCHA_MATH_MIN: "Minimum number"
BASIC_CAPTCHA_MATH_MAX: "Maximum number"
BASIC_CAPTCHA_MATH_OPERATORS: "Mathematical operators (randomized)"
eu: eu:
PLUGIN_FORM: PLUGIN_FORM:
NOT_VALIDATED: "Formularioa ez da baliozkotu. Beharrezkoa den eremu bat edo gehiago falta dira." NOT_VALIDATED: "Formularioa ez da baliozkotu. Beharrezkoa den eremu bat edo gehiago falta dira."

2
plugins/form/scss.sh Normal file
View File

@ -0,0 +1,2 @@
#!/bin/sh
sass --watch -s compressed scss:assets

View File

@ -1,4 +1,4 @@
$form-border-color: #eee; $form-border-color: #ccc;
$form-active-color: #000; $form-active-color: #000;
.form-group.has-errors { .form-group.has-errors {
@ -287,3 +287,29 @@ $form-active-color: #000;
display: inline-block; display: inline-block;
} }
.form-data.basic-captcha {
.form-input-wrapper {
border: 1px solid $form-border-color;
border-radius: 5px;
display: flex;
overflow: hidden;
}
.form-input-prepend {
display: flex;
color: #333;
background-color: #ccc;
flex-shrink: 0;
img {
margin: 0;
}
button > svg {
margin: 0 8px;
width: 18px;
height: 18px;
}
}
input.form-input {
border: 0;
}
}

View File

@ -0,0 +1,28 @@
{% set form_field_outer_data_classes = 'form-data basic-captcha' %}
{% extends "forms/field.html.twig" %}
{% block prepend %}
<div class="form-input-addon form-input-prepend">
<img id="basic-captcha-reload" src="{{ url('/forms-basic-captcha-image.jpg') }}" alt="human test" />
<button id="reload-captcha"><svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><g fill="#292D32"><path d="M14.74 22.39c4.68-1.24 8-5.49 8-10.4 0-5.95-4.79-10.75-10.75-10.75 -3.11 0-5.78 1.11-7.99 2.95 -.77.64-1.43 1.32-1.98 2.01 -.34.41-.57.75-.69.95 -.22.35-.1.81.25 1.02 .35.21.81.09 1.02-.26 .08-.15.27-.43.56-.79 .49-.62 1.08-1.23 1.76-1.81C6.87 3.67 9.21 2.7 11.94 2.7c5.13 0 9.25 4.12 9.25 9.25 0 4.22-2.86 7.88-6.9 8.94 -.41.1-.64.51-.54.91 .1.4.51.63.91.53Zm-12-14.84V2.99c-.001-.42-.34-.75-.75-.75 -.42 0-.75.33-.75.75v4.56c0 .41.33.75.75.75 .41 0 .75-.34.75-.75Zm-.75.75H4h2.43c.41 0 .75-.34.75-.75 0-.42-.34-.75-.75-.75H4 1.99c-.42 0-.75.33-.75.75 0 .41.33.75.75.75Z"/><path d="M1.25 12c0 1.09.16 2.16.48 3.18 .12.39.54.61.93.49 .39-.13.61-.55.49-.94 -.28-.89-.42-1.81-.42-2.75 0-.42-.34-.75-.75-.75 -.42 0-.75.33-.75.75Zm1.93 6.15c.61.88 1.36 1.67 2.22 2.33 .32.25.79.19 1.05-.14 .25-.33.19-.8-.14-1.06 -.74-.58-1.38-1.25-1.92-2.02 -.24-.34-.71-.43-1.05-.19 -.34.23-.43.7-.19 1.04Zm5.02 3.91c1 .37 2.06.6 3.15.66 .41.02.76-.3.79-.71 .02-.42-.3-.77-.71-.8 -.94-.06-1.85-.25-2.72-.58 -.39-.15-.83.04-.97.43 -.15.38.04.82.43.96Z"/></g></svg></button>
<script>
function stripQueryString(url) {
return url.split("?")[0].split("#")[0];
}
document.getElementById("reload-captcha").onclick = function(event) {
event.preventDefault();
const src = stripQueryString(document.getElementById("basic-captcha-reload").src);
document.getElementById("basic-captcha-reload").src = src + `?v=${new Date().getTime()}`;
}
</script>
</div>
{% endblock %}
{% block input_attributes %}
type="text"
{% if field.size %}size="{{ field.size }}"{% endif %}
{% if field.minlength is defined or field.validate.min is defined %}minlength="{{ field.minlength | default(field.validate.min) }}"{% endif %}
{% if field.maxlength is defined or field.validate.max is defined %}maxlength="{{ field.maxlength | default(field.validate.max) }}"{% endif %}
{{ parent() }}
{% endblock %}