diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..1a20d2d --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Robin Scholz + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 19d1940..868dbe6 100755 --- a/README.md +++ b/README.md @@ -4,10 +4,55 @@ Small [Kirby](https://getkirby.com) plugin that exposes the internal REST API at `/rest` with the option to convert Kirbytags to HTML and add a `srcset` to images in the process. Intended to convert Kirby into a headless CMS. -## Caveats -### GET only -The plugin only allows `GET` requests. +## Usage + +You can access the Better-Rest API route at `/rest`. The plugin only allows `GET` requests. + +### Authentification +Requests need to be authenticated via _Basic Auth_. It’s recommended to create a seperate _API User_ with a special blueprint at `site/blueprints/users/api.yml` or use the one provided by this plugin called [Better-Rest](https://github.com/robinscholz/better-rest/blob/master/blueprints/users/betterrest.yml). Read more about [User Roles in the docs](https://getkirby.com/docs/guide/users/roles). + +### Kirby 3 API + +Examples: + +- `rest/pages/:id` : https://getkirby.com/docs/reference/api/pages +- `rest/users/:id` : https://getkirby.com/docs/reference/api/users + +> [official Kirby 3 API docs](https://getkirby.com/docs/reference/api/) + +### Better-Rest Settings from Query + +You can override the Settings defined in your Config file with each request in prefixing the param with `br-`. + +Examples: + +- `rest/pages/test?br-srcset=375,1200` : **br-srcset** +- `rest/pages/test?br-smartypants=1` : **br-smartypants** +- `rest/pages/test?br-language=fr` : **br-language** +- `rest/pages/test?br-kirbytags=0&br-srcset=0` : **br-kirbytag br-srcset** + +### Multilang +The plugin supports multiple language settings. To fetch content for a specific language include a _X-Language header_ containing the desired language code with your request or use the Query. + +## Settings + +### Config File + +- The plugin converts _kirbytags_ to HTML and adds a `srcset` to images by default. +- You can enable smartytags to be applied. +- You can enforce a specific language in setting its language code. + +All settings need to be prefixed with `robinscholz.better-rest.`! + +| Settings | Default | Options | +| ----------- | ------------------------ | ------------------ | +| kirbytags | `true` | `boolean` | +| smartypants | `false` | `boolean` | +| srcset | `[375, 667, 1024, 1680]` | `Array` or `false` | +| language | `null` | `null` or `string` | + +## Caveats ### HTTPS The Kirby installation needs to be served with a _TLS Certicificate_ via `https`. @@ -24,24 +69,6 @@ return [ ``` > **WARNING**: Do not use this setting for production environments! -### Settings - -The plugin converts _kirbytags_ to HTML and adds a `srcset` to images by default. You can also enforce a specific language in setting its language code. - -All settings need to be prefixed with `robinscholz.better-rest.`! - -| Settings | Default | Options | -| --------- | ------------------------ | ------------------ | -| kirbytags | `true` | `boolean` | -| srcset | `[375, 667, 1024, 1680]` | `Array` or `false` | -| language | `null` | `null` or `string` | - -### Authentification -Requests need to be authenticated via _Basic Auth_. It’s recommended to create a seperate _API User_ with a special blueprint at `site/blueprints/users/api.yml` or use the one provided by this plugin called [Better-Rest](https://github.com/robinscholz/better-rest/blob/master/blueprints/users/betterrest.yml). - -### Multilang -The plugin supports multiple language settings. To fetch content for a specific language include a _X-Language header_ containing the desired language code with your request. - ## Installation ### Download @@ -58,7 +85,7 @@ git submodule add https://github.com/robinscholz/better-rest.git site/plugins/be ``` ## Credits -A big thanks to [@bnomei](https://github.com/bnomei) who refactored the initial source code into something extendable and future proof. If you are using this plugin please consider buying a Kirby license through his [affiliate link](https://a.paddle.com/v2/click/1129/35731?link=1170)! +A big thanks to [@bnomei](https://github.com/bnomei) who refactored the initial source code into something extendable and future proof. If you are using this plugin please consider to [buy him ☕](https://buymeacoff.ee/bnomei)! ## License MIT diff --git a/classes/Betterrest.php b/classes/Betterrest.php index 8086a30..66cfd20 100644 --- a/classes/Betterrest.php +++ b/classes/Betterrest.php @@ -44,19 +44,13 @@ public function __construct(array $options = []) $defaults = [ 'srcset' => \option('robinscholz.better-rest.srcset'), 'kirbytags' => \option('robinscholz.better-rest.kirbytags'), + 'smartypants' => \option('robinscholz.better-rest.smartypants'), 'language' => \option('robinscholz.better-rest.language'), + 'query' => null, ]; $this->options = array_merge($defaults, $options); } - /** - * @return array - */ - public function getOptions(): array - { - return $this->options; - } - /** * Get content as array from Request object. * @@ -67,7 +61,7 @@ public function contentFromRequest(?\Kirby\Http\Request $request = null): ?array { // default to current request $request = $request ?? $this->kirby->request(); - $path = preg_replace('/rest/', '', (string)$request->path(), 1); + $path = preg_replace('/rest/', '', (string) $request->path(), 1); // @codeCoverageIgnoreStart // auto detect language @@ -85,11 +79,16 @@ public function contentFromRequest(?\Kirby\Http\Request $request = null): ?array $this->kirby->setCurrentLanguage($language); } + // options from query + $queryToOptions = array_merge(\Kirby\Toolkit\A::get($this->options, 'query', []), $request->query()->toArray()); + $this->options = array_merge($this->options, $this->optionsFromQuery($queryToOptions)); + // method api() is @internal $render = $this->kirby->api()->render( - (string)$path, - (string)$request->method(), + (string) $path, + (string) $request->method(), [ + // 'body' => $request->body()->toArray(), 'headers' => $request->headers(), 'query' => $request->query()->toArray(), ] @@ -120,6 +119,8 @@ public function modifyContent(array $array = null): ?array // flat? exit early if (! is_array($value)) { + // NOTE: order of calls is important + $value = $betterrest->applySmartypants((string) $value); $value = $betterrest->applyKirbytags((string) $value); return $value; } @@ -146,6 +147,15 @@ public function applyKirbytags(?string $value): string return \Kirby\Toolkit\A::get($this->options, 'kirbytags') ? \kirbytags($value) : $value; } + /** + * @param string $value + * @return string + */ + public function applySmartypants(?string $value): string + { + return \Kirby\Toolkit\A::get($this->options, 'smartypants') ? \smartypants($value) : $value; + } + /** * @param $value * @return array @@ -159,6 +169,36 @@ public function applySrcSet($value): array return $value; } + /** + * @param array|null $query + * @return array + */ + private function optionsFromQuery(?array $query = null): array + { + if (! $query) { + return []; + } + + $query = array_change_key_case($query); // to lowercase + $optionsFromQuery = []; + + if ($kirbytags = \Kirby\Toolkit\A::get($query, 'br-kirbytags')) { + $optionsFromQuery['kirbytags'] = self::isTrue($kirbytags); + } + if ($smartypants = \Kirby\Toolkit\A::get($query, 'br-smartypants')) { + $optionsFromQuery['smartypants'] = self::isTrue($smartypants); + } + if ($language = \Kirby\Toolkit\A::get($query, 'br-language')) { + $optionsFromQuery['language'] = strval($language); + } + if ($srcset = \Kirby\Toolkit\A::get($query, 'br-srcset')) { + $srcset = str_replace([' ', '%20'], ['', ''], (string) $srcset); + $optionsFromQuery['srcset'] = in_array($srcset, ['false', '0']) ? null : explode(',', $srcset); + } + + return $optionsFromQuery; + } + /** * Build data for a response. * 1) fetch content from current request @@ -194,6 +234,14 @@ public static function rest(array $options = []) return $betterrest->response(); } + /** + * @return array + */ + public function getOptions(): array + { + return $this->options; + } + /** * @return null */ @@ -225,4 +273,16 @@ public function setData($data): void { $this->data = $data; } + + /** + * @param $val + * @param bool $return_null + * @return bool|mixed|null + */ + public static function isTrue($val, bool $return_null = false) + { + $boolval = ( is_string($val) ? filter_var($val, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) : (bool) $val ); + $boolval = $boolval === null && ! $return_null ? false : $boolval; + return $boolval; + } } diff --git a/composer.json b/composer.json index 7476fa8..2e5559e 100755 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "robinscholz/better-rest", "description": "Kirby Plugin for better REST requests", "type": "kirby-plugin", - "version": "1.1.1", + "version": "1.2.0", "license": "MIT", "authors": [ { diff --git a/index.php b/index.php index 5afe760..49c796b 100755 --- a/index.php +++ b/index.php @@ -6,6 +6,7 @@ 'options' => [ 'srcset' => [375, 667, 1024, 1680], // array|boolean|null 'kirbytags' => true, // boolean + 'smartypants' => false, // boolean 'language' => null, // null = autodetect | string {language code} ], 'blueprints' => [ diff --git a/tests/BetterrestTest.php b/tests/BetterrestTest.php index c4885bb..7c66949 100644 --- a/tests/BetterrestTest.php +++ b/tests/BetterrestTest.php @@ -22,7 +22,9 @@ public function testDefaultOptions() // this makes sure the defaults do not change later $this->assertCount(4, $options['srcset']); $this->assertTrue($options['kirbytags'] === true); + $this->assertTrue($options['smartypants'] === false); $this->assertTrue($options['language'] === null); + $this->assertTrue($options['query'] === null); } public function testCustomOptions() @@ -30,14 +32,20 @@ public function testCustomOptions() $rest = new Robinscholz\Betterrest([ 'srcset' => false, 'kirbytags' => false, + 'smartypants' => true, 'language' => 'de', + 'query' => [ + 'select' => 'files', + ], ]); $options = $rest->getOptions(); $this->assertIsArray($options); $this->assertTrue($options['srcset'] === false); $this->assertTrue($options['kirbytags'] === false); + $this->assertTrue($options['smartypants'] === true); $this->assertTrue($options['language'] === 'de'); + $this->assertCount(1, $options['query']); } public function testContentFromAPICall() @@ -139,4 +147,39 @@ public function testLanguage() $this->assertTrue($content['code'] === 200); $this->assertTrue(kirby()->language()->code() === 'de'); } + + public function testCustomQuery() + { + kirby()->impersonate('kirby'); + + $rest = new Robinscholz\Betterrest([ + 'query' => [ + 'select' => 'files', + ] + ]); + $this->assertTrue($rest->getOptions()['query']['select'] === 'files'); + + $content = $rest->contentFromRequest( + new \Kirby\Http\Request([ + 'url' => 'pages/test', + 'query' => [ + 'select' => 'files', + 'br-smartypants' => 1, + 'br-language' => 'de', + 'br-kirbytags' => 'false', + 'br-srcset' => '375,1200', + ] + ]) + ); + $rest->setContent($content); + + // check if options got applied + $this->assertTrue($rest->getOptions()['smartypants'] === true); + $this->assertTrue($rest->getOptions()['kirbytags'] === false); + $this->assertTrue($rest->getOptions()['language'] === 'de'); + $this->assertCount(2, $rest->getOptions()['srcset']); + + $response = $rest->response(); + $this->assertTrue($response['data']['files'][0]['id'] === 'test/test.jpeg'); + } }