diff --git a/README.md b/README.md index 2828684..12afdeb 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,138 @@ -# komments -A Kirby 3 comment plugin +# Komments + +![GitHub release](https://img.shields.io/github/release/mauricerenck/komments.svg?maxAge=1800) ![License](https://img.shields.io/github/license/mashape/apistatus.svg) ![Kirby Version](https://img.shields.io/badge/Kirby-3.3%2B-black.svg) + +A Kirby comment plugin + +**Please be aware, this is still a beta.** + +## Features + +- ✅ Receive comments from a form on your site + - The user will be informed that the komment is in moderation + - Spam detection + - Reject spam or just mark komments as spam +- ✅ Receive and send webmentions +- ✅ Send updates to Mastodon +- ✅ Ping archive.org +- ✅ Panel support + - Dashboard for komments in moderation/spam + - Moderate komments on your page + - Disable/enable komments per page + +![the dashboard](doc-assets/komments-dashboard.png) +(The komment dashboard) + +## Installation + +### Install the plugin + +- `composer require mauricerenck/komments` +- unzip [master.zip](https://github.com/mauricerenck/komments/releases/latest) as folder `site/plugins/komments` +- `git submodule add https://github.com/mauricerenck/komments.git site/plugins/komments` + +--- + +### Adding Komments to your site + +After Installing the Plugin add the snippet to your template. There are two snippets for you to use: + +To list all komments and webmentions: + +`` + +To show the komment form + +`` + +After adding the snippets, you may also want to add the stylesheet within the `
` of your site: + +`` + +--- + +### Adding Komments to your panel blueprint + +if you use the panel, you may want to add the komments section to your blueprints like so: + +``` +sections: + komments: + extends: sections/komments +``` + +Add this to every blueprint you wish to enable komments on. This will allow you to enable/disable komments for each individual page and to see and edit the list of komments for that page. + +![komment section](doc-assets/komment-section.png) + +--- + +## Options + +You can fine tune the komments to behave as you whish, use this options in `config.php` file. + +| Option | Default | Description | +| ----------------------------- | ----------------------------------------- | -------------------------------------------------------------------------------------------------------- | +| `debug` | `false` | Enables debug mode and logs all webmentions to a file | +| `enable-webmention-support` | `true` | Listen to Webmentions and save them as komment | +| `webmention-auto-publish` | `true` | When you receive a webmention set status to published | +| `komment-auto-publish` | `false` | When you receive a komment set status to published | +| `send-mention-on-update` | `true` | Detect urls in your pages and send webmentions | +| `send-limit-to-templates` | `[]` | An array of template names (strings). When set webmentions will be sent only when this pages are updated | +| `send-mention-url-fields` | `['text']` | An array of fieldnames in which the plugin will search for urls | +| `send-to-mastodon-on-publish` | `false` | Send a post to mastodon when publishing a page | +| `mastodon-bearer` | - | Your Mastodon bearer Token | +| `mastodon-instance-url` | `https://mastodon.social/api/v1/statuses` | Your Mastodon API Endpoint | +| `mastodon-text-field` | `mastodonTeaser` | The fieldname of the field you write your mastodon msg in, otherwise the title is used | +| `ping-archiveorg` | `false` | Enable if you want to inform archive.org when you update a page | +| `auto-delete-spam` | `true` | When comment spam is detected it will be rejected, set to false to just mark the comment as SPAM | +| `komment-icon-like` | ❤️ | The icon for likes in your komment list | +| `komment-icon-reply` | 💬 | The icon for replies/comments in your komment list | +| `komment-icon-repost` | ♻️ | The icon for reposts in your komment list | +| `komment-icon-mention` | ♻️ | The icon for mention in your komment list | + +**Please make sure to prefix all the options with `mauricerenck.komments.`**. For example the debug option should be set in your `config.php` like so: `'mauricerenck.komments.debug' => true` + +--- + +## Special features + +Next to komments directly on your page, there are some other features enabled by this plugin + +### Receiving webmentions + +To receive webmentions you have to install the [tratschtante plugin](https://github.com/mauricerenck/tratschtante) and configure it. Tratschtante will handle all the webmentions and normalize their data. Currently only webmention.io is supported. After installing tratschtante, komment will automaticly by informed about new webmentions. + +Webmention support is enabled by default but won't work until you install tratschtante. + +### Sending Webmentions + +You don't need tratschtante to send webmentions. By default the plugin will try to send webmentions to all urls it finds in your page. You might want to tell the plugin in which fields to look for urls, you can do that by providing a list of fieldnames in the `mauricerenck.komments.send-mention-url-fields` option. So if you have an intro and a text field in your blueprint, you might want to add those: + +``` +'mauricerenck.komments.send-mention-url-fields' => [ + 'intro', + 'text', + ] +``` + +If you just want to send webmention on specific pages, like only on blogposts, you can set a limit to those templates by using the `mauricerenck.komments.send-limit-to-templates` option. For example, using the starterkit, if you just want to send mentions on notes, do so: + +``` +'mauricerenck.komments.send-limit-to-templates' => [ + 'note', + ] +``` + +### Sending new pages to mastodon + +If you want to, you can inform your mastodon followers of new pages/posts on your site. Just set the `mauricerenck.komments.send-to-mastodon-on-publish` to `true`. Komments will then try to publish a mastodon post everytime you publish a page. This can also be limited by template (see sending webmentions above) + +In order to be able to publish to your mastodon account, you need to set a bearer token and your mastodon api endpoint. Please have a look at your mastodon instance on how to get that data. + +### Changing the komment list on your site + +By changing the the icon options you can add your own emoji or icons. You can set simple text or even full html-code. +If you want to change the styling, have a look at the classes, you can find the default styling in the `assets` folder of this plugin. + +You can also modify the javascript part, but be aware, that this might result in false spam detection. diff --git a/assets/komments.css b/assets/komments.css new file mode 100644 index 0000000..c594f2d --- /dev/null +++ b/assets/komments.css @@ -0,0 +1,133 @@ +#kommentform { + display: grid; + grid-template-columns: 100%; + + grid-template-areas: + "quote" + "komment" + "email" + "author" + "authorsite" + "privacy" + "button" + "tweet"; + + grid-column-gap: 10px; + grid-row-gap: 10px; +} + +#kommentform #url { + position: relative; + left: -200vw; + height: 0; +} + +#kommentform input[name="email"] { + grid-area: email; +} + +#kommentform input[name="author"] { + grid-area: author; +} + +#kommentform input[type="url"] { + grid-area: authorsite; +} + +#kommentform input[type="submit"] { + grid-area: button; +} + +#kommentform .share { + grid-area: tweet; + align-self: start; +} + +#kommentform textarea { + grid-area: komment; + width: 100%; +} + +#kommentform .visible-quote { + grid-area: quote; +} + +#kommentform .komment-privacy { + grid-area: privacy; + font-size: smaller; +} + +#kommentform.spam-indicator { + grid-area: spamindicator; + width: 100%; +} + +#kommentform .progress { + transition: width 1s, background 2s, height 0.2s; + transition-timing-function: linear; + display: inline-block; + width: 0%; + height: 5px; + background: red; +} + +#kommentform .progress.orange { + background: orange; +} +#kommentform .progress.yellow { + background: yellowgreen; +} +#kommentform .progress.green { + background: green; +} + +#kommentform .progress.done { + background: green; + height: 0; +} + +#kommentsWebmentions .single-komment { + display: grid; + grid-template-columns: 20px 40px 1fr; + + grid-template-areas: + "icon avatar action" + "icon avatar content"; + + grid-column-gap: 10px; + grid-row-gap: 10px; + + line-height: 1.2; + + border-bottom: 1px solid grey; + padding-bottom: 20px; + margin-bottom: 20px; +} + +#kommentsWebmentions .type-of { + grid-area: icon; + line-height: 40px; +} + +#kommentsWebmentions .author-avatar { + grid-area: avatar; + position: relative; +} +#kommentsWebmentions .author-avatar img { + max-width: 40px; + border-radius: 3px; +} + +#kommentsWebmentions .author-action { + grid-area: action; + color: grey; + line-height: 40px; +} +#kommentsWebmentions .mention-content { + grid-area: content; + padding-bottom: 20px; +} +#kommentsWebmentions .komment-text { + padding: 20; + line-height: 1.5; +} diff --git a/assets/komments.js b/assets/komments.js index fdbe355..e1a9108 100644 --- a/assets/komments.js +++ b/assets/komments.js @@ -1,5 +1,4 @@ window.onload = function () { - const komment = document.querySelector('#kommentform #komment') const kommentEmail = document.querySelector('#kommentform #email') const kommentAuthor = document.querySelector('#kommentform #author') @@ -9,47 +8,45 @@ window.onload = function () { const spamIndicatorProgress = document.querySelector('#kommentform .spam-indicator .progress') let duration = { - start: 0, - end: 0, indicator: 0, - timer: null + timer: null, + current: 0 } const setIndicator = () => { - if (duration.indicator > 0) { + if (duration.current > 0) { return } + timeField.value = 0; submitField.disabled = true; duration.timer = window.setInterval(() => { duration.indicator += 10; spamIndicatorProgress.style.width = `${duration.indicator}%` - // TODO if (duration.indicator > 25) { - spamIndicatorProgress.style.background = 'orange' + spamIndicatorProgress.classList.add('orange') } if (duration.indicator > 50) { - spamIndicatorProgress.style.background = 'yellowgreen' + spamIndicatorProgress.classList.add('yellow') } if (duration.indicator > 75) { - spamIndicatorProgress.style.background = 'green' + spamIndicatorProgress.classList.add('green') } if (duration.indicator >= 100) { - spamIndicatorProgress.style.background = 'green' - spamIndicatorProgress.style.height = '0'; + spamIndicatorProgress.classList.add('done') submitField.disabled = false; - duration.end = Math.round(Date.now() / 1000); - timeField.value = duration.end - duration.start - window.clearInterval(duration.timer) } + + duration.current++; + timeField.value = duration.current }, 1000) } @@ -58,7 +55,6 @@ window.onload = function () { kommentUrl.style.display = 'none'; komment.addEventListener('focus', () => { - duration.start = Math.round(Date.now() / 1000); setIndicator(); kommentEmail.style.display = 'block'; kommentAuthor.style.display = 'block'; diff --git a/blueprints/sections/komments.yml b/blueprints/sections/komments.yml new file mode 100644 index 0000000..bf56b32 --- /dev/null +++ b/blueprints/sections/komments.yml @@ -0,0 +1,74 @@ +label: Komments +type: fields +fields: + kommentsEnabledOnpage: + type: toggle + label: Komments enabled + default: true + kommentsEnabledOnpage: + type: toggle + label: Komments enabled + default: true + kommentsInbox: + type: structure + label: Inbox + fields: + avatar: + type: gravatar + label: Avatar + width: 1/6 + author: + type: text + label: Author + width: 2/6 + authorUrl: + type: url + label: Author Url + width: 3/6 + source: + type: hidden + label: Source + target: + type: hidden + label: Target + mentionOf: + type: hidden + label: Mentioned + property: + type: hidden + label: Type + komment: + type: textarea + label: Komment + width: 1/2 + quote: + type: textarea + label: Quote + width: 1/2 + kommentType: + type: select + label: Type + width: 1/3 + options: + LIKE: Like + REPOST: Repost + REPLY: Reply + MENTION: Mention + KOMMENT: Komment + SPAM: Spam + published: + type: date + label: Published + time: true + width: 1/3 + status: + type: toggle + label: Status + width: 1/3 + columns: + author: + width: 1/4 + komment: + width: 2/4 + status: + width: 1/4 diff --git a/blueprints/tabs/komments.yml b/blueprints/tabs/komments.yml deleted file mode 100644 index 5e30d5c..0000000 --- a/blueprints/tabs/komments.yml +++ /dev/null @@ -1,57 +0,0 @@ -label: Komments -columns: - - width: 1/1 - sections: - kommentsWebmentions: - type: fields - fields: - kommentsInbox: - type: structure - label: Inbox - fields: - avatar: - type: url - label: Avatar - author: - type: text - label: Author - authorUrl: - type: url - label: Author Url - wmSource: - type: url - label: Source - wmTarget: - type: url - label: Target - mentionOf: - type: url - label: Mentioned - wmProperty: - type: text - label: Type - published: - type: date - label: Published - time: true - komment: - type: textarea - label: Komment - quote: - type: textarea - label: Quote - status: - type: toggle - label: Status - honey: - type: text - label: Honeypot - columns: - author: - width: 1/4 - wmSource: - width: 1/4 - komment: - width: 1/4 - status: - width: 1/4 diff --git a/changelog.md b/changelog.md new file mode 100644 index 0000000..b076b92 --- /dev/null +++ b/changelog.md @@ -0,0 +1 @@ +- 2020-05-11 - Initial beta release diff --git a/composer.json b/composer.json index 9ccc1c3..49ce4ad 100644 --- a/composer.json +++ b/composer.json @@ -1,27 +1,35 @@ { - "name": "mauricerenck/komments", - "version": "0.0.2", - "description": "A webmention and comments plugin for Kirby 3", - "type": "kirby-plugin", - "license": "MIT", - "authors": [ - { - "name": "Maurice Renck", - "email": "hello@maurice-renck.de" - } - ], - "autoload": { - "files": [ - "utils/sendMastodon.php", - "utils/sendWebmention.php", - "utils/receiveWebmention.php" - ] - }, - "require": { - "getkirby/composer-installer": "^1.1", - "indieweb/mention-client": "^1.2" - }, - "config": { - "optimize-autoloader": true + "name": "mauricerenck/komments", + "version": "0.9.0", + "description": "A comment and webmention plugin for Kirby 3", + "type": "kirby-plugin", + "license": "MIT", + "authors": [ + { + "name": "Maurice Renck", + "email": "hello@maurice-renck.de" } + ], + "autoload": { + "files": [ + "utils/sendMastodon.php", + "utils/sendWebmention.php", + "utils/receiveKomment.php", + "utils/moderation.php" + ] + }, + "require": { + "getkirby/composer-installer": "^1.1", + "indieweb/mention-client": "^1.2" + }, + "config": { + "optimize-autoloader": true + }, + "scripts": { + "testKirby": "phpunit --bootstrap ./tests/bootstrap.php --testdox ./tests/suites", + "test": "phpunit --testdox ./tests/suites" + }, + "require-dev": { + "phpunit/phpunit": "^9" + } } diff --git a/composer.lock b/composer.lock index e7ea662..aba0244 100644 --- a/composer.lock +++ b/composer.lock @@ -1,10 +1,10 @@ { "_readme": [ "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c5501f6ee71da00db2c7c86a230e6c91", + "content-hash": "64f116d52c0b433ab0a0427a613a8563", "packages": [ { "name": "getkirby/composer-installer", @@ -143,12 +143,1700 @@ "time": "2018-08-24T14:47:04+00:00" } ], - "packages-dev": [], + "packages-dev": [ + { + "name": "doctrine/instantiator", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "ae466f726242e637cebdd526a7d991b9433bacf1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/ae466f726242e637cebdd526a7d991b9433bacf1", + "reference": "ae466f726242e637cebdd526a7d991b9433bacf1", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "doctrine/coding-standard": "^6.0", + "ext-pdo": "*", + "ext-phar": "*", + "phpbench/phpbench": "^0.13", + "phpstan/phpstan-phpunit": "^0.11", + "phpstan/phpstan-shim": "^0.11", + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2019-10-21T16:45:58+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.9.5", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "b2c28789e80a97badd14145fda39b545d83ca3ef" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/b2c28789e80a97badd14145fda39b545d83ca3ef", + "reference": "b2c28789e80a97badd14145fda39b545d83ca3ef", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "replace": { + "myclabs/deep-copy": "self.version" + }, + "require-dev": { + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^7.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + }, + "files": [ + "src/DeepCopy/deep_copy.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "time": "2020-01-17T21:11:47+00:00" + }, + { + "name": "phar-io/manifest", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", + "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "phar-io/version": "^2.0", + "php": "^5.6 || ^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "time": "2018-07-08T19:23:20+00:00" + }, + { + "name": "phar-io/version", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6", + "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "time": "2018-07-08T19:19:57+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "2.1.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "6568f4687e5b41b054365f9ae03fcb1ed5f2069b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/6568f4687e5b41b054365f9ae03fcb1ed5f2069b", + "reference": "6568f4687e5b41b054365f9ae03fcb1ed5f2069b", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "time": "2020-04-27T09:25:28+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "5.1.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "cd72d394ca794d3466a3b2fc09d5a6c1dc86b47e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/cd72d394ca794d3466a3b2fc09d5a6c1dc86b47e", + "reference": "cd72d394ca794d3466a3b2fc09d5a6c1dc86b47e", + "shasum": "" + }, + "require": { + "ext-filter": "^7.1", + "php": "^7.2", + "phpdocumentor/reflection-common": "^2.0", + "phpdocumentor/type-resolver": "^1.0", + "webmozart/assert": "^1" + }, + "require-dev": { + "doctrine/instantiator": "^1", + "mockery/mockery": "^1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "account@ijaap.nl" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "time": "2020-02-22T12:28:44+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "7462d5f123dfc080dfdf26897032a6513644fc95" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/7462d5f123dfc080dfdf26897032a6513644fc95", + "reference": "7462d5f123dfc080dfdf26897032a6513644fc95", + "shasum": "" + }, + "require": { + "php": "^7.2", + "phpdocumentor/reflection-common": "^2.0" + }, + "require-dev": { + "ext-tokenizer": "^7.2", + "mockery/mockery": "~1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "time": "2020-02-18T18:59:58+00:00" + }, + { + "name": "phpspec/prophecy", + "version": "v1.10.3", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "451c3cd1418cf640de218914901e51b064abb093" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/451c3cd1418cf640de218914901e51b064abb093", + "reference": "451c3cd1418cf640de218914901e51b064abb093", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.3|^7.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0", + "sebastian/comparator": "^1.2.3|^2.0|^3.0|^4.0", + "sebastian/recursion-context": "^1.0|^2.0|^3.0|^4.0" + }, + "require-dev": { + "phpspec/phpspec": "^2.5 || ^3.2", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10.x-dev" + } + }, + "autoload": { + "psr-4": { + "Prophecy\\": "src/Prophecy" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "time": "2020-03-05T15:02:03+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "8.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "31e94ccc084025d6abee0585df533eb3a792b96a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/31e94ccc084025d6abee0585df533eb3a792b96a", + "reference": "31e94ccc084025d6abee0585df533eb3a792b96a", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-xmlwriter": "*", + "php": "^7.3", + "phpunit/php-file-iterator": "^3.0", + "phpunit/php-text-template": "^2.0", + "phpunit/php-token-stream": "^4.0", + "sebastian/code-unit-reverse-lookup": "^2.0", + "sebastian/environment": "^5.0", + "sebastian/version": "^3.0", + "theseer/tokenizer": "^1.1.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "suggest": { + "ext-pcov": "*", + "ext-xdebug": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "8.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2020-02-19T13:41:19+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "4ac5b3e13df14829daa60a2eb4fdd2f2b7d33cf4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/4ac5b3e13df14829daa60a2eb4fdd2f2b7d33cf4", + "reference": "4ac5b3e13df14829daa60a2eb4fdd2f2b7d33cf4", + "shasum": "" + }, + "require": { + "php": "^7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-04-18T05:02:12+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "7579d5a1ba7f3ac11c80004d205877911315ae7a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/7579d5a1ba7f3ac11c80004d205877911315ae7a", + "reference": "7579d5a1ba7f3ac11c80004d205877911315ae7a", + "shasum": "" + }, + "require": { + "php": "^7.3" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^9.0" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "time": "2020-02-07T06:06:11+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "526dc996cc0ebdfa428cd2dfccd79b7b53fee346" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/526dc996cc0ebdfa428cd2dfccd79b7b53fee346", + "reference": "526dc996cc0ebdfa428cd2dfccd79b7b53fee346", + "shasum": "" + }, + "require": { + "php": "^7.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2020-02-01T07:43:44+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "3.1.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "dc9368fae6ef2ffa57eba80a7410bcef81df6258" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/dc9368fae6ef2ffa57eba80a7410bcef81df6258", + "reference": "dc9368fae6ef2ffa57eba80a7410bcef81df6258", + "shasum": "" + }, + "require": { + "php": "^7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-04-20T06:00:37+00:00" + }, + { + "name": "phpunit/php-token-stream", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "cdc0db5aed8fbfaf475fbd95bfd7bab83c7a779c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/cdc0db5aed8fbfaf475fbd95bfd7bab83c7a779c", + "reference": "cdc0db5aed8fbfaf475fbd95bfd7bab83c7a779c", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-05-06T09:56:31+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "9.1.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "2d7080c622cf7884992e7c3cf87853877bae8ff4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/2d7080c622cf7884992e7c3cf87853877bae8ff4", + "reference": "2d7080c622cf7884992e7c3cf87853877bae8ff4", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.2.0", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.9.1", + "phar-io/manifest": "^1.0.3", + "phar-io/version": "^2.0.1", + "php": "^7.3", + "phpspec/prophecy": "^1.8.1", + "phpunit/php-code-coverage": "^8.0.1", + "phpunit/php-file-iterator": "^3.0", + "phpunit/php-invoker": "^3.0", + "phpunit/php-text-template": "^2.0", + "phpunit/php-timer": "^3.1.4", + "sebastian/code-unit": "^1.0.2", + "sebastian/comparator": "^4.0", + "sebastian/diff": "^4.0", + "sebastian/environment": "^5.0.1", + "sebastian/exporter": "^4.0", + "sebastian/global-state": "^4.0", + "sebastian/object-enumerator": "^4.0", + "sebastian/resource-operations": "^3.0", + "sebastian/type": "^2.0", + "sebastian/version": "^3.0" + }, + "require-dev": { + "ext-pdo": "*", + "phpspec/prophecy-phpunit": "^2.0" + }, + "suggest": { + "ext-soap": "*", + "ext-xdebug": "*" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ], + "files": [ + "src/Framework/Assert/Functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "funding": [ + { + "url": "https://phpunit.de/donate.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-04-30T06:32:53+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "ac958085bc19fcd1d36425c781ef4cbb5b06e2a5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/ac958085bc19fcd1d36425c781ef4cbb5b06e2a5", + "reference": "ac958085bc19fcd1d36425c781ef4cbb5b06e2a5", + "shasum": "" + }, + "require": { + "php": "^7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-04-30T05:58:10+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "5b5dbe0044085ac41df47e79d34911a15b96d82e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5b5dbe0044085ac41df47e79d34911a15b96d82e", + "reference": "5b5dbe0044085ac41df47e79d34911a15b96d82e", + "shasum": "" + }, + "require": { + "php": "^7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "time": "2020-02-07T06:20:13+00:00" + }, + { + "name": "sebastian/comparator", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "85b3435da967696ed618ff745f32be3ff4a2b8e8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/85b3435da967696ed618ff745f32be3ff4a2b8e8", + "reference": "85b3435da967696ed618ff745f32be3ff4a2b8e8", + "shasum": "" + }, + "require": { + "php": "^7.3", + "sebastian/diff": "^4.0", + "sebastian/exporter": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2020-02-07T06:08:51+00:00" + }, + { + "name": "sebastian/diff", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "3e523c576f29dacecff309f35e4cc5a5c168e78a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3e523c576f29dacecff309f35e4cc5a5c168e78a", + "reference": "3e523c576f29dacecff309f35e4cc5a5c168e78a", + "shasum": "" + }, + "require": { + "php": "^7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.0", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-05-08T05:01:12+00:00" + }, + { + "name": "sebastian/environment", + "version": "5.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "c753f04d68cd489b6973cf9b4e505e191af3b05c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/c753f04d68cd489b6973cf9b4e505e191af3b05c", + "reference": "c753f04d68cd489b6973cf9b4e505e191af3b05c", + "shasum": "" + }, + "require": { + "php": "^7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-04-14T13:36:52+00:00" + }, + { + "name": "sebastian/exporter", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "80c26562e964016538f832f305b2286e1ec29566" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/80c26562e964016538f832f305b2286e1ec29566", + "reference": "80c26562e964016538f832f305b2286e1ec29566", + "shasum": "" + }, + "require": { + "php": "^7.3", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "time": "2020-02-07T06:10:52+00:00" + }, + { + "name": "sebastian/global-state", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "bdb1e7c79e592b8c82cb1699be3c8743119b8a72" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bdb1e7c79e592b8c82cb1699be3c8743119b8a72", + "reference": "bdb1e7c79e592b8c82cb1699be3c8743119b8a72", + "shasum": "" + }, + "require": { + "php": "^7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^9.0" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "time": "2020-02-07T06:11:37+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "e67516b175550abad905dc952f43285957ef4363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/e67516b175550abad905dc952f43285957ef4363", + "reference": "e67516b175550abad905dc952f43285957ef4363", + "shasum": "" + }, + "require": { + "php": "^7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "time": "2020-02-07T06:12:23+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "f4fd0835cabb0d4a6546d9fe291e5740037aa1e7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/f4fd0835cabb0d4a6546d9fe291e5740037aa1e7", + "reference": "f4fd0835cabb0d4a6546d9fe291e5740037aa1e7", + "shasum": "" + }, + "require": { + "php": "^7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "time": "2020-02-07T06:19:40+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "cdd86616411fc3062368b720b0425de10bd3d579" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cdd86616411fc3062368b720b0425de10bd3d579", + "reference": "cdd86616411fc3062368b720b0425de10bd3d579", + "shasum": "" + }, + "require": { + "php": "^7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "time": "2020-02-07T06:18:20+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "8c98bf0dfa1f9256d0468b9803a1e1df31b6fa98" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/8c98bf0dfa1f9256d0468b9803a1e1df31b6fa98", + "reference": "8c98bf0dfa1f9256d0468b9803a1e1df31b6fa98", + "shasum": "" + }, + "require": { + "php": "^7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "time": "2020-02-07T06:13:02+00:00" + }, + { + "name": "sebastian/type", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "9e8f42f740afdea51f5f4e8cec2035580e797ee1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/9e8f42f740afdea51f5f4e8cec2035580e797ee1", + "reference": "9e8f42f740afdea51f5f4e8cec2035580e797ee1", + "shasum": "" + }, + "require": { + "php": "^7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "time": "2020-02-07T06:13:43+00:00" + }, + { + "name": "sebastian/version", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "0411bde656dce64202b39c2f4473993a9081d39e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/0411bde656dce64202b39c2f4473993a9081d39e", + "reference": "0411bde656dce64202b39c2f4473993a9081d39e", + "shasum": "" + }, + "require": { + "php": "^7.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2020-01-21T06:36:37+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.16.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "1aab00e39cebaef4d8652497f46c15c1b7e45294" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/1aab00e39cebaef4d8652497f46c15c1b7e45294", + "reference": "1aab00e39cebaef4d8652497f46c15c1b7e45294", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.16-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-08T16:50:20+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.1.3", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/11336f6f84e16a720dae9d8e6ed5019efa85a0f9", + "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "time": "2019-06-13T22:48:21+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.8.0", + "source": { + "type": "git", + "url": "https://github.com/webmozart/assert.git", + "reference": "ab2cb0b3b559010b75981b1bdce728da3ee90ad6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/assert/zipball/ab2cb0b3b559010b75981b1bdce728da3ee90ad6", + "reference": "ab2cb0b3b559010b75981b1bdce728da3ee90ad6", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "vimeo/psalm": "<3.9.1" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.36 || ^7.5.13" + }, + "type": "library", + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "time": "2020-04-18T12:12:48+00:00" + } + ], "aliases": [], "minimum-stability": "stable", "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": [], - "platform-dev": [] + "platform-dev": [], + "plugin-api-version": "1.1.0" } diff --git a/config/api.php b/config/api.php new file mode 100644 index 0000000..04af4ed --- /dev/null +++ b/config/api.php @@ -0,0 +1,71 @@ + [ + [ + 'pattern' => 'komments/queued', + 'action' => function () { + $pendingKomments = []; + $collection = site()->index(); + $komments = new Structure(); + $key = 0; + + foreach ($collection as $item) { + if ($item->kommentsInbox()->isNotEmpty()) { + foreach ($item->kommentsInbox()->yaml() as $komment) { + $komment['spamlevel'] = (isset($komment['spamlevel'])) ? $komment['spamlevel'] : 0; // backward compatiblity + if ($komment['status'] == 'false' && (integer)$komment['spamlevel'] == 0) { + $pendingKomments[] = [ + 'author' => $komment['author'], + 'komment' => $komment['komment'], + 'kommentType' => $komment['kommenttype'], + 'image' => $komment['avatar'], + 'title' => (string) $item->title(), + 'url' => $item->panelUrl(), + ]; + } + } + } + } + + return json_encode($pendingKomments); + } + ], + [ + 'pattern' => 'komments/spam', + 'action' => function () { + $spamKomments = []; + $collection = site()->index(); + $komments = new Structure(); + $key = 0; + + foreach ($collection as $item) { + if ($item->kommentsInbox()->isNotEmpty()) { + foreach ($item->kommentsInbox()->yaml() as $komment) { + $komment['spamlevel'] = (isset($komment['spamlevel'])) ? $komment['spamlevel'] : 0; // backward compatiblity + + if ((integer)$komment['spamlevel'] > 0) { + $spamKomments[] = [ + 'author' => $komment['author'], + 'komment' => $komment['komment'], + 'kommentType' => $komment['kommenttype'], + 'image' => $komment['avatar'], + 'title' => (string) $item->title(), + 'url' => $item->panelUrl(), + ]; + } + } + } + } + + return json_encode($spamKomments); + } + ], + ] +]; diff --git a/config/hooks.php b/config/hooks.php new file mode 100644 index 0000000..991b38b --- /dev/null +++ b/config/hooks.php @@ -0,0 +1,39 @@ + function ($newPage, $oldPage) { + $webmentionSender = new WebmentionSender($newPage); + + if (option('mauricerenck.komments.send-mention-on-update', true) && !$newPage->isDraft() && $webmentionSender->templateIsWhitelisted($newPage->template())) { + $sendWebmention = new WebmentionSender($newPage); + $sendWebmention->send(); + } + }, + 'page.changeStatus:after' => function ($newPage, $oldPage) { + if (option('mauricerenck.komments.send-to-mastodon-on-publish', false)) { + if ($newPage->isListed() && !$oldPage->isListed() && $webmentionSender->templateIsWhitelisted($newPage->template())) { + $mastodon = new MastodonSender(); + $mastodon->sendToot($newPage); + } + } + }, + 'tratschtante.webhook.received' => function ($webmention, $targetPage) { + if (!option('mauricerenck.komments.enable-webmention-support')) { + return; + } + + if (!option('mauricerenck.komments.debug')) { + $time = time(); + file_put_contents('webmentionhook.' . $time . '.json', json_encode($response)); + } + + $kommentReceiver = new KommentReceiver(); + $newEntry = $kommentReceiver->createKomment($webmention); + $kommentReceiver->storeData($newEntry, $targetPage); + } +]; diff --git a/config/options.php b/config/options.php index a089041..7286116 100644 --- a/config/options.php +++ b/config/options.php @@ -1,5 +1,23 @@ null, + 'debug' => false, + 'enable-webmention-support' => true, + 'webmention-auto-publish' => true, + 'komment-auto-publish' => false, + 'send-mention-on-update' => true, + 'send-limit-to-templates' => [], + 'send-mention-url-fields' => [ + 'text' + ], + 'send-to-mastodon-on-publish' => false, + 'mastodon-bearer' => '', + 'mastodon-instance-url' => 'https://mastodon.social/api/v1/statuses', + 'mastodon-text-field' => 'mastodonTeaser', + 'ping-archiveorg' => false, + 'auto-delete-spam' => true, + 'komment-icon-like' => '❤️', + 'komment-icon-reply' => '💬', + 'komment-icon-repost' => '♻️', + 'komment-icon-mention' => '♻️', ]; diff --git a/config/translations.php b/config/translations.php new file mode 100644 index 0000000..712b886 --- /dev/null +++ b/config/translations.php @@ -0,0 +1,26 @@ + [ + 'mauricerenck.komments.liked' => 'spent a like', + 'mauricerenck.komments.replied' => 'replied', + 'mauricerenck.komments.mentioned' => 'mentioned this page', + 'mauricerenck.komments.moderation' => 'Your comment is awaiting moderation.', + 'mauricerenck.komments.disabled' => 'Comments were disabled on this page.', + 'mauricerenck.komments.externalReply' => 'Answer elsewhere', + 'mauricerenck.komments.form.submit' => 'send', + 'mauricerenck.komments.form.privacy' => 'Your E-Mail address will be encrypted before saving the comment. It will only be used to display a gravatar. By submitting your data, you agree that all entered data may be saved and displayed as a comment.', + ], + 'de' => [ + 'mauricerenck.komments.liked' => 'hat ein like spendiert', + 'mauricerenck.komments.liked' => 'schreibt', + 'mauricerenck.komments.mentioned' => 'erwähnte diesen Beitrag', + 'mauricerenck.komments.moderation' => 'Dein Kommentar wartet auf Freischaltung.', + 'mauricerenck.komments.disabled' => 'Die Kommentarfunktion wurde auf dieser Seite deaktiviert.', + 'mauricerenck.komments.externalReply' => 'Woanders antworten', + 'mauricerenck.komments.form.submit' => 'Abschicken', + 'mauricerenck.komments.form.privacy' => 'Die eigegebene E-Mail-Adresse wird vorm Speichern unwiderruflich verschlüsselt und dient nur zur Darstellung des Avatars. Mit dem Absenden stimmst du zu, dass die eingegebenen Daten gespeichert und in Form eines Kommentars dargestellt werden dürfen.', + ] +]; diff --git a/doc-assets/komment-section.png b/doc-assets/komment-section.png new file mode 100644 index 0000000..60c5744 Binary files /dev/null and b/doc-assets/komment-section.png differ diff --git a/doc-assets/komments-dashboard.png b/doc-assets/komments-dashboard.png new file mode 100644 index 0000000..9d85b73 Binary files /dev/null and b/doc-assets/komments-dashboard.png differ diff --git a/index.css b/index.css new file mode 100644 index 0000000..3737a7e --- /dev/null +++ b/index.css @@ -0,0 +1 @@ +img{width:100%} \ No newline at end of file diff --git a/index.js b/index.js index 1248c24..fb84799 100644 --- a/index.js +++ b/index.js @@ -1 +1 @@ -(function () {var a={data:function(){return{komments:[]}},created:function(){this.load()},methods:{load:function(){var t=this;this.$api.get("komments/queued").then(function(e){t.komments=e})}}};if(typeof a==="function"){a=a.options}Object.assign(a,function(){var render=function(){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c("div",{staticClass:"k-komments"},[_c("k-list",{attrs:{"data-size":"medium"}},_vm._l(_vm.komments,function(komment){return _c("k-list-item",{key:komment.title,attrs:{"link":komment.url+"#komments","info":komment.type+" by "+komment.author,"text":komment.title+" - "+komment.komment,"image":{ratio:"1/1",cover:true,back:"pattern",url:komment.image},"target":"_self"}})}),1)],1)};var staticRenderFns=[];return{render:render,staticRenderFns:staticRenderFns,_compiled:true,_scopeId:null,functional:undefined}}());var b={components:{QueuedKomments:a}};if(typeof b==="function"){b=b.options}Object.assign(b,function(){var render=function(){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c("k-view",{staticClass:"k-kommentviews-view"},[_c("k-header",[_vm._v("Komments")]),_vm._v(" "),_c("k-column",{attrs:{"width":"1/2"}},[_c("QueuedKomments")],1)],1)};var staticRenderFns=[];return{render:render,staticRenderFns:staticRenderFns,_compiled:true,_scopeId:null,functional:undefined}}());panel.plugin("mauricerenck/komments",{views:{queuedKommments:{component:b,icon:"chat",label:"Komments"}}});})(); \ No newline at end of file +(function () {var a={data:function(){return{komments:[]}},created:function(){this.load()},methods:{load:function(){var t=this;this.$api.get("komments/queued").then(function(e){t.komments=e})}}};if(typeof a==="function"){a=a.options}Object.assign(a,function(){var render=function(){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c("div",{staticClass:"k-komments"},[_c("k-list",{attrs:{"data-size":"medium"}},_vm._l(_vm.komments,function(komment){return _c("k-list-item",{key:komment.title,attrs:{"link":komment.url+"#komments","info":""+komment.author,"text":komment.title+" - "+komment.komment,"image":{ratio:"1/1",cover:true,back:"pattern",url:komment.image},"target":"_self"}})}),1)],1)};var staticRenderFns=[];return{render:render,staticRenderFns:staticRenderFns,_compiled:true,_scopeId:null,functional:undefined}}());var b={data:function(){return{komments:[]}},created:function(){this.load()},methods:{load:function(){var t=this;this.$api.get("komments/spam").then(function(e){t.komments=e})}}};if(typeof b==="function"){b=b.options}Object.assign(b,function(){var render=function(){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c("div",{staticClass:"k-spam-komments"},[_c("k-list",{attrs:{"data-size":"medium"}},_vm._l(_vm.komments,function(komment){return _c("k-list-item",{key:komment.title,attrs:{"link":komment.url+"#komments","info":""+komment.author,"text":komment.title+" - "+komment.komment,"image":{ratio:"1/1",cover:true,back:"pattern",url:komment.image},"target":"_self"}})}),1)],1)};var staticRenderFns=[];return{render:render,staticRenderFns:staticRenderFns,_compiled:true,_scopeId:null,functional:undefined}}());var c={components:{QueuedKomments:a,SpamKomments:b}};if(typeof c==="function"){c=c.options}Object.assign(c,function(){var render=function(){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c("k-view",{staticClass:"k-kommentviews-view"},[_c("k-header",[_vm._v("Komments")]),_vm._v(" "),_c("k-grid",{attrs:{"gutter":"large"}},[_c("k-column",{attrs:{"width":"3/6"}},[_c("k-headline-field",{attrs:{"label":"In moderation"}}),_vm._v(" "),_c("QueuedKomments")],1),_vm._v(" "),_c("k-column",{attrs:{"width":"2/6"}},[_c("k-headline-field",{attrs:{"label":"Marked as spam"}}),_vm._v(" "),_c("SpamKomments")],1),_vm._v(" "),_c("k-column",{attrs:{"width":"1/6"}},[_c("k-headline-field",{attrs:{"label":"Support"}})],1)],1)],1)};var staticRenderFns=[];return{render:render,staticRenderFns:staticRenderFns,_compiled:true,_scopeId:null,functional:undefined}}());var d={props:{label:String,value:String}};if(typeof d==="function"){d=d.options}Object.assign(d,function(){var render=function(){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c("img",{attrs:{"src":_vm.value}})};var staticRenderFns=[];return{render:render,staticRenderFns:staticRenderFns,_compiled:true,_scopeId:null,functional:undefined}}());panel.plugin("mauricerenck/komments",{views:{queuedKommments:{component:c,icon:"chat",label:"Komments"}},fields:{gravatar:d}});})(); \ No newline at end of file diff --git a/index.php b/index.php index b6fba63..55477cb 100644 --- a/index.php +++ b/index.php @@ -1,50 +1,111 @@ 'utils/readKomments.php', - 'Plugin\Komments\WriteKomments' => 'utils/writeKomments.php', + 'Plugin\Komments\MastodonSender' => 'utils/sendMastodon.php', + 'Plugin\Komments\WebmentionSender' => 'utils/sendWebmention.php', + 'Plugin\Komments\KommentReceiver' => 'utils/receiveKomment.php', + 'Plugin\Komments\KommentModeration' => 'utils/moderation.php', ], __DIR__); Kirby::plugin('mauricerenck/komments', [ - 'options' => [ - 'kommentUserId' => 'CHANGEME', + 'options' => require_once(__DIR__ . '/config/options.php'), + 'snippets' => [ + 'komments/webmention' => __DIR__ . '/snippets/webmentions.php', + 'komments/kommentform' => __DIR__ . '/snippets/kommentform.php', + 'komments/type/like' => __DIR__ . '/snippets/mention-type-like.php', + 'komments/type/reply' => __DIR__ . '/snippets/mention-type-reply.php', + 'komments/type/repost' => __DIR__ . '/snippets/mention-type-repost.php', + 'komments/type/mention' => __DIR__ . '/snippets/mention-type-mention.php', ], - 'templates' => [], 'blueprints' => [ - 'users/komments' => __DIR__ . '/blueprints/users/komments.yml', - 'tabs/komments' => __DIR__ . '/blueprints/tabs/komments.yml', - 'pages/komments' => __DIR__ . '/blueprints/pages/komments.yml', - 'pages/komment' => __DIR__ . '/blueprints/pages/komment.yml' + 'sections/komments' => __DIR__ . '/blueprints/sections/komments.yml' ], - 'snippets' => [ - 'komment/list' => __DIR__ . '/snippets/list-komments.php', - 'komment/single' => __DIR__ . '/snippets/single-komment.php', - 'komments/form' => __DIR__ . '/snippets/komment-form.php', + 'pageMethods' => [ + 'kommentCount' => function () { + $count = $this->kommentsInbox()->toStructure()->count(); + return $count; + }, + 'hasQueuedKomments' => function ($kommentId, $kommenStatus) { + $kommentModeration = new KommentModeration(); + return $kommentModeration->pageHasQueuedKomments($kommentId, $kommenStatus); + }, + ], + 'fields' => [ + 'kommentType' => [ + 'props' => [ + ] + ], + 'gravatar' => [ + 'props' => [ + ] + ] ], + 'translations' => require_once(__DIR__ . '/config/translations.php'), + 'api' => require_once(__DIR__ . '/config/api.php'), + 'hooks' => require_once(__DIR__ . '/config/hooks.php'), 'routes' => [ [ - 'pattern' => '(:all)/komment/save', + 'pattern' => 'komments/send', + 'method' => 'POST', 'action' => function () { - $kommentData = new stdClass(); - $kommentData->title = substr($_POST['text'], 0, 30); - $kommentData->author = $_POST['author']; - $kommentData->email = $_POST['email']; - $kommentData->text = $_POST['text']; - $kommentData->replyTo = $_POST['replyTo']; - - $slug = $_POST['page_slug']; - $kommentUtils = new WriteKomments(); - $kommentUtils->createKomment($slug, $kommentData); - - go($slug); - }, - 'method' => 'POST' - ] - ], - 'hooks' => [] -]); \ No newline at end of file + $kommentReceiver = new KommentReceiver(); + $kommentModeration = new KommentModeration(); + $targetPage = $kommentReceiver->getPageFromUrl($_POST['wmTarget']); + $spamlevel = 0; + + if (is_null($targetPage)) { + go('error'); + } + + if ($kommentReceiver->isSpam($_POST)) { + if (option('auto-delete-spam') === true) { + go('error'); + } else { + $spamlevel = 100; + } + } + + $webmention = [ + 'type' => 'KOMMENT', + 'target' => $targetPage->url(), + 'source' => $targetPage->url(), + 'published' => $kommentReceiver->setPublishDate(), + 'content' => $_POST['komment'], + 'quote' => $_POST['quote'], + 'author' => [ + 'type' => 'card', + 'name' => $kommentReceiver->setAuthorName($_POST['author']), + 'avatar' => $kommentReceiver->setAvatarFromEmail($_POST['email']), + 'url' => $kommentReceiver->setUrl($_POST['author_url']), + ] + ]; + + if (!$kommentReceiver->requiredFieldsAreValid($webmention)) { + go('error'); + } + + $newEntry = $kommentReceiver->createKomment($webmention, $spamlevel); + $kommentReceiver->storeData($newEntry, $targetPage); + $kommentModeration->addCookieToModerationList($newEntry['id']); + + go($targetPage . '#inModeration'); + } + ], + ] +]); diff --git a/package.json b/package.json index 21137cd..2f29e4a 100644 --- a/package.json +++ b/package.json @@ -1,17 +1,24 @@ { - "name": "komments", - "version": "1.2.4", - "description": "A Kirby Comment and Webmention Plugin", - "main": "index.js", - "author": "Maurice Renck", - "scripts": { - "dev": "parcel watch src/index.js --no-source-maps -d ./", - "build": "parcel build src/index.js --no-source-maps --experimental-scope-hoisting -d ./" - }, - "posthtml": { - "recognizeSelfClosing": true - }, - "dependencies": { - "vue": "^2.6.11" - } + "name": "komments", + "version": "0.9.0", + "description": "A comment and webmention plugin for Kirby 3", + "main": "index.js", + "author": "Maurice Renck", + "scripts": { + "dev": "parcel watch src/index.js --no-source-maps -d ./", + "build": "parcel build src/index.js --no-source-maps --experimental-scope-hoisting -d ./" + }, + "posthtml": { + "recognizeSelfClosing": true + }, + "dependencies": { + "vue": "^2.6.11", + "vue-hot-reload-api": "^2.3.4" + }, + "devDependencies": { + "@vue/component-compiler-utils": "^3.1.2", + "cssnano": "^4.1.10", + "stylus": "^0.54.7", + "vue-template-compiler": "^2.6.11" + } } diff --git a/snippets/kommentform.php b/snippets/kommentform.php index 0fba05a..2e984dd 100644 --- a/snippets/kommentform.php +++ b/snippets/kommentform.php @@ -1,15 +1,21 @@ +kommentsEnabledOnpage()->isNotEmpty() && $page->kommentsEnabledOnpage()->isFalse()): ?> + + + -quote()->html(); ?>
quote()->html(); ?>