diff --git a/plugins/admin-media-actions/CHANGELOG.md b/plugins/admin-media-actions/CHANGELOG.md deleted file mode 100644 index f56a2a1..0000000 --- a/plugins/admin-media-actions/CHANGELOG.md +++ /dev/null @@ -1,32 +0,0 @@ -# v1.0.4 -## 2/15/2018 - -1. [](#new) - * Update styles for Grav Admin v1.7. - -# v1.0.3 -## 2/15/2018 - -1. [](#new) - * Add column margin to media actions. - * Add border-radius to media actions. - -# v1.0.2 -## 2/14/2018 - -1. [](#new) - * Update bugs URL. - * Update addAction signature - -# v1.0.1 -## 2/7/2018 - -1. [](#new) - * Show alert dialog for sample actions. - * Update sample action log message. - -# v1.0.0 -## 1/24/2018 - -1. [](#Initial) - * \ No newline at end of file diff --git a/plugins/admin-media-actions/LICENSE b/plugins/admin-media-actions/LICENSE deleted file mode 100644 index bef72fe..0000000 --- a/plugins/admin-media-actions/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2018 TwelveTone LLC - -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/plugins/admin-media-actions/README.md b/plugins/admin-media-actions/README.md deleted file mode 100644 index 9897898..0000000 --- a/plugins/admin-media-actions/README.md +++ /dev/null @@ -1,34 +0,0 @@ -# Admin Media Actions Plugin - -The **Admin Media Actions** Plugin is for [Grav CMS](http://github.com/getgrav/grav). A plugin which adds an API for adding actions items to media items in the media bin. - -## Installation - -Installing the Admin Media Actions plugin can be done in one of two ways. The GPM (Grav Package Manager) installation method enables you to quickly and easily install the plugin with a simple terminal command, while the manual method enables you to do so via a zip file. - -### GPM Installation (Preferred) - -The simplest way to install this plugin is via the [Grav Package Manager (GPM)](http://learn.getgrav.org/advanced/grav-gpm) through your system's terminal (also called the command line). From the root of your Grav install type: - - bin/gpm install admin-media-actions - -This will install the Admin Media Actions plugin into your `/user/plugins` directory within Grav. Its files can be found under `/your/site/grav/user/plugins/admin-media-actions`. - -### Manual Installation - -To install this plugin, just download the zip version of this repository and unzip it under `/your/site/grav/user/plugins`. Then, rename the folder to `admin-media-actions`. You can find these files on [GitHub](https://github.com) or via [GetGrav.org](http://getgrav.org/downloads/plugins#extras). - -You should now have all the plugin files under - - /your/site/grav/user/plugins/admin-media-actions - -> NOTE: This plugin is a modular component for Grav which requires [Grav](http://github.com/getgrav/grav) and the [Admin](https://github.com/getgrav/grav-plugin-admin) plugin to operate. - -## Usage - -See online [documentation](https://www.twelvetone.tv/docs/developer-tools/grav-plugins/grav-admin-media-actions-plugin) - -## Credits - -A big thanks to David Szabo and his development on the grav-plugin-admin-addon-media-rename for some clever approaches -on tapping into the Grav architecture. \ No newline at end of file diff --git a/plugins/admin-media-actions/admin-media-actions.php b/plugins/admin-media-actions/admin-media-actions.php deleted file mode 100644 index 1314264..0000000 --- a/plugins/admin-media-actions/admin-media-actions.php +++ /dev/null @@ -1,227 +0,0 @@ - ['onPluginsInitialized', 0] - ]; - } - - public function getPath() - { - return '/' . trim($this->grav['admin']->base, '/') . '/' . trim(self::ROUTE, '/'); - } - - public function buildBaseUrl() - { - $ret = rtrim($this->grav['uri']->rootUrl(false), '/') . '/' . trim($this->getPath(), '/'); - return $ret; - } - - public function onPluginsInitialized() - { - if (!$this->isAdmin() || !$this->grav['user']->authenticated) { - return; - } - - // Register the media actions service - $this->grav['media-actions'] = function ($c) { - return new MediaActionsController(); - }; - - // Ignore requests to the plugin URL - if ($this->grav['uri']->path() == $this->getPath()) { - return; - } - - if ($this->config->get('plugins.admin-media-actions.show_samples')) { - // Sample Actions - $this->grav['media-actions']->addAction("SampleAction1", "Sample Action 1", "play-circle", function ($page, $mediaName, $payload) { - return [ - "path" => $page->path(), - "route" => $page->route(), - "mediaName" => $mediaName, - ]; - }); - $this->grav['media-actions']->addAction("SampleAction2", "Sample Action 2", "play-circle", function ($page, $mediaName, $payload) { - return [ - "path" => $page->path(), - "route" => $page->route(), - "mediaName" => $mediaName, - ]; - }); - $this->grav['media-actions']->addAction("SampleAction3", "Sample Action 3", "play-circle", function ($page, $mediaName, $payload) { - return [ - "path" => $page->path(), - "route" => $page->route(), - "mediaName" => $mediaName, - ]; - }); - - $this->grav['media-actions']->addAction("SampleForm", "Sample Form", "list", function ($page, $mediaName, $payload) { - return "ok"; - }); - } - - - $this->enable([ - 'onAdminTwigTemplatePaths' => ['onAdminTwigTemplatePaths', 0], - 'onTwigTemplatePaths' => ['onTwigTemplatePaths', 0], - 'onPagesInitialized' => ['onTwigExtensions', 0], - 'onAdminTaskExecute' => ['onAdminTaskExecute', 0], - ]); - } - - public function onAdminTaskExecute($e) - { - $method = $e['method']; - switch ($method) { - case "taskMedia-action": - - $page = $this->grav['admin']->page(false); - //$route = $page->route(); - - $actionId = $_POST['action_id']; - $media_name = $_POST['media_name']; - $payload = json_decode($_POST['payload'], true); - - $handler = $this->grav['media-actions']->getHandlerForAction($actionId); - if ($handler) { - $json = $handler($page, $media_name, $payload); - die("{\"result\":" . json_encode($json) . "}"); - } else { - die("{\"result\":{\"error\":true}}"); - } - break; - default: - return false; - } - } - - public function onAdminTwigTemplatePaths() - { -// $event['paths'] = __DIR__ . '/themes/grav/templates'; - } - - public function onTwigTemplatePaths() - { - $this->grav['twig']->twig_paths[] = __DIR__ . '/templates'; - } - - public function onTwigExtensions() - { - $page = $this->grav['admin']->page(true); - if (!$page) { - return; - } - - if ($this->config->get('plugins.admin-media-actions.show_samples')) { - $this->grav['assets']->addJs('plugin://admin-media-actions/assets/samples/sample_actions.js', -1000, false); - $this->grav['assets']->addJs('plugin://admin-media-actions/assets/samples/sample_form_action.js', -1000, false); - } - - $oCopy = []; - foreach ($this->grav['media-actions']->actions as $action) { - $oCopy[] = [ - 'actionId' => $action['actionId'], - 'icon' => $action['icon'], - 'caption' => $action['caption'], - ]; - } - $this->grav['assets']->addInlineJs('const MEDIA_ACTIONS = ' . json_encode($oCopy) . ';', -1000, false); - - $taskUrl = $this->buildBaseUrl() . $page->route() . '/task:media-action'; - $this->grav['assets']->addInlineJs('const MEDIA_ACTION_TASK_URL = ' . json_encode($taskUrl) . ';', -1000, false); - - $this->grav['assets']->addJs('plugin://admin-media-actions/assets/admin-media-actions.js', -1000, false); - $this->grav['assets']->addCss('plugin://admin-media-actions/assets/admin-media-actions.css', -1000, false); - } - - public function outputError($msg) - { - header('HTTP/1.1 400 Bad Request'); - die(json_encode(['error' => ['msg' => $msg]])); - } - -} - -class MediaActionsController -{ - public $actions = []; - - /** - * @param $actionId A unique id for the action. Must be a valid Javascript function name. - * This can also be an array containing keys of the same parameter names. - * - * @param $caption The caption for the action. Used for the tooltip. - * @param $icon The font-awesome icon name. The 'fa-' prefix is optional. - * @param $handler A handler for the action. (page, mediaName, payload) => object. - */ - function addAction($actionId, $caption = null, $icon = null, $handler = null) - { - if (is_array($actionId)) { - if (isset($actionId['caption'])) { - $caption = $actionId['caption']; - } - if (isset($actionId['icon'])) { - $icon = $actionId['icon']; - } - if (isset($actionId['handler'])) { - $handler = $actionId['handler']; - } - // do this last... - $actionId = $actionId['actionId']; - } - $this->actions[$actionId] = [ - 'handler' => $handler, - 'caption' => $caption, - 'icon' => $icon, - 'actionId' => $actionId, - ]; - } - - function getHandlerForAction($actionId) - { - if (isset($this->actions[$actionId])) { - return $this->actions[$actionId]['handler']; - } else { - return null; - } - } -} diff --git a/plugins/admin-media-actions/admin-media-actions.yaml b/plugins/admin-media-actions/admin-media-actions.yaml deleted file mode 100644 index 3f5ccd3..0000000 --- a/plugins/admin-media-actions/admin-media-actions.yaml +++ /dev/null @@ -1,26 +0,0 @@ -# -# The MIT License (MIT) -# -# Copyright (c) 2018 TwelveTone LLC -# -# 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. -# - -enabled: true -show_samples: false \ No newline at end of file diff --git a/plugins/admin-media-actions/assets/admin-media-actions.css b/plugins/admin-media-actions/assets/admin-media-actions.css deleted file mode 100644 index 60755a8..0000000 --- a/plugins/admin-media-actions/assets/admin-media-actions.css +++ /dev/null @@ -1,62 +0,0 @@ -/** - * The MIT License (MIT) - * - * Copyright (c) 2018 TwelveTone LLC - * - * 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. - */ -span[data-dz-name] { - cursor: text; -} - -.dz-rename:hover:after { - color: #0082ba; -} - -/*.dropzone .dz-preview:hover .dz-rename {*/ -/*display: block;*/ -/*}*/ - -.dropzone .dz-preview:hover .dz-media-action { - display: flex; -} - -.dz-media-action { - display: none; - position: absolute; - width: 25px; - height: 25px; - cursor: pointer; - background: #e1e1e1; - justify-content: center; - align-items: center; - border-radius: 2px; -} - -body.ga-theme-17x .dz-media-action { - background: #f2f2f2; -} - -.dz-media-action i { - color: #737c81; -} - -.dz-media-action i:hover { - color: #0082ba; -} \ No newline at end of file diff --git a/plugins/admin-media-actions/assets/admin-media-actions.js b/plugins/admin-media-actions/assets/admin-media-actions.js deleted file mode 100644 index 024747e..0000000 --- a/plugins/admin-media-actions/assets/admin-media-actions.js +++ /dev/null @@ -1,119 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2018 TwelveTone LLC - * - * 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. - */ -// MEDIA_ACTIONS must be set -// MEDIA_ACTION_TASK_URL must be set - - -function _onMediaAction(actionId, mediaName, dz) { - let fn = "onMediaAction_" + actionId; - if (typeof window[fn] === 'function') { - window[fn].apply(null, [actionId, mediaName, dz]); - } else { - submitMediaAction(actionId, mediaName, ""); - } -} - -function submitMediaAction(actionId, mediaName, payload = "", callback = null, modal = null) { - if (modal) { - $('.loading', modal).removeClass('hidden'); - $('.button', modal).addClass('hidden'); - } - var data = new FormData(); - data.append('admin-nonce', GravAdmin.config.admin_nonce); - data.append("action_id", actionId); - data.append("media_name", mediaName); - data.append("payload", JSON.stringify(payload)); - fetch(MEDIA_ACTION_TASK_URL, {method: 'POST', body: data, credentials: 'same-origin'}) - .then(res => res.json()) - .then(result => { - if (modal) { - if (!result.error) { - modal.close(); - } - } - if (callback) { - callback(result); - } - }); -} - -// Check for new media every 1000 ms and add actions -setInterval(function () { - const size = 25; // The action icon size - const maxRows = 5; - const colMargin = 2; - - $('.dz-preview').each(function (i, dz) { - if (!dz._actions) { - dz._actions = true; - let actionsIndex = 3; //TODO hardcoded to standard action count - //let top = 72; //TODO get max top of children (they are not in order) - //let top = actionsCount * size - size; // the standard icons ar off by 1 pixel!? - - const that = this; - MEDIA_ACTIONS.forEach(function (item) { - actionsIndex++; - let faIcon = item.icon; - if (!faIcon) { - faIcon = "fa-play-circle"; - } - if (!faIcon.startsWith('fa-')) { - faIcon = 'fa-' + faIcon; - } - const ele = document.createElement('a'); - ele.className = 'dz-media-action'; - ele.style.top = (Math.floor(actionsIndex % maxRows) * size - (Math.floor(actionsIndex % maxRows)) - 1) + 'px'; - let right; - const col = Math.floor(actionsIndex / maxRows); - if (col === 0) { - right = -size; - } else { - right = -((1 + Math.floor((actionsIndex) / maxRows)) * size) - (col * colMargin); - } - ele.style.right = right + 'px'; - ele.href = 'javascript:undefined;'; - ele.title = item.caption; - ele.innerText = "";//item.caption; - const nameEle = $(dz).find('[data-dz-name]'); - ele._file_name = nameEle.text(); - ele._dz_preview = dz; - $(that).append(ele); - const i = document.createElement("i"); - ele.appendChild(i); - i.className = 'fa fa-fw ' + faIcon; - ele.addEventListener('click', () => _onMediaAction(item.actionId, nameEle.text(), dz)); - - //Invisible div to maintain hover when the mouseover is on the column margin - const ele2 = document.createElement('div'); - ele2.className = 'dz-media-action'; - ele2.style.background = 'transparent'; - ele2.style.right = (right + colMargin) + "px"; - ele2.style.top = ele.style.top; - $(ele2).insertBefore(ele); - }); - dz.style.marginRight = 15 + Math.floor(actionsIndex / maxRows) * (size + colMargin) + "px"; - } - }); -}, 1000); - diff --git a/plugins/admin-media-actions/assets/samples/sample_actions.js b/plugins/admin-media-actions/assets/samples/sample_actions.js deleted file mode 100644 index a2414f6..0000000 --- a/plugins/admin-media-actions/assets/samples/sample_actions.js +++ /dev/null @@ -1,47 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2018 TwelveTone LLC - * - * 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. - */ - -function onMediaAction_SampleAction1(actionId, mediaName, mediaElement) { - console.log(`Media action ${actionId} was selected.`); - alert(`Media action ${actionId} was selected.`); - submitMediaAction(actionId, mediaName, `${actionId} was selected`, function (result) { - console.log(result); - }); -} - -function onMediaAction_SampleAction2(actionId, mediaName, mediaElement) { - console.log(`Media action ${actionId} was selected.`); - alert(`Media action ${actionId} was selected.`); - submitMediaAction(actionId, mediaName, `${actionId} was selected`, function (result) { - console.log(result); - }); -} - -function onMediaAction_SampleAction3(actionId, mediaName, mediaElement) { - console.log(`Media action ${actionId} was selected.`); - alert(`Media action ${actionId} was selected.`); - submitMediaAction(actionId, mediaName, `${actionId} was selected`, function (result) { - console.log(result); - }); -} diff --git a/plugins/admin-media-actions/assets/samples/sample_form_action.js b/plugins/admin-media-actions/assets/samples/sample_form_action.js deleted file mode 100644 index fa54b77..0000000 --- a/plugins/admin-media-actions/assets/samples/sample_form_action.js +++ /dev/null @@ -1,29 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2018 TwelveTone LLC - * - * 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. - */ -// Sample Form Action - -function onMediaAction_SampleForm(actionId, mediaName, mediaElement) { - alert("This is a sample form."); - submitMediaAction(actionId, mediaName, '{"key1":"value1", "key2":"value2"}'); -} \ No newline at end of file diff --git a/plugins/admin-media-actions/blueprints.yaml b/plugins/admin-media-actions/blueprints.yaml deleted file mode 100644 index 83b70dd..0000000 --- a/plugins/admin-media-actions/blueprints.yaml +++ /dev/null @@ -1,66 +0,0 @@ -# -# The MIT License (MIT) -# -# Copyright (c) 2018 TwelveTone LLC -# -# 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. -# - -name: Admin Media Actions -version: 1.0.4 -description: A plugin that extends Grav with an API for adding actions to media items in the page media bin. This plugin is required by other plugins that add media actions. -icon: plug -author: - name: TwelveTone LLC - email: info@twelvetone.tv -homepage: https://www.twelvetone.tv/docs/developer-tools/grav-plugins/grav-admin-media-actions-plugin -keywords: grav, plugin, admin, media, action -bugs: https://github.com/Flamenco/grav-admin-media-actions/issues -docs: https://www.twelvetone.tv/docs/developer-tools/grav-plugins/grav-admin-media-actions-plugin -license: MIT - -dependencies: - - { name: grav, version: '>=1.0.0' } - - { name: admin, version: '>=1.0.0' } - -form: - validation: strict - fields: - enabled: - type: toggle - label: Plugin status - highlight: 1 - default: 0 - options: - 1: Enabled - 0: Disabled - validate: - type: bool - - show_samples: - type: toggle - label: Show sample actions - description: For testing purposes, several actions will be added to each media item. - highlight: 0 - default: 0 - options: - 1: Enabled - 0: Disabled - validate: - type: bool diff --git a/plugins/admin-media-actions/build.gradle b/plugins/admin-media-actions/build.gradle deleted file mode 100644 index 8ec85cc..0000000 --- a/plugins/admin-media-actions/build.gradle +++ /dev/null @@ -1,17 +0,0 @@ -plugins { - id("com.github.hierynomus.license").version("0.14.0") -} -apply plugin:'java' - -sourceSets { - grav { - resources { - srcDirs += "." - include "**/*.yaml" - include "**/*.php" - include "**/*.css" - include "**/*.js" - include "**/*.twig" - } - } -} \ No newline at end of file diff --git a/plugins/admin-media-actions/settings.gradle b/plugins/admin-media-actions/settings.gradle deleted file mode 100644 index e69de29..0000000 diff --git a/plugins/admin-media-actions/templates/media-actions-dialog-modal.html.twig b/plugins/admin-media-actions/templates/media-actions-dialog-modal.html.twig deleted file mode 100644 index d67ec01..0000000 --- a/plugins/admin-media-actions/templates/media-actions-dialog-modal.html.twig +++ /dev/null @@ -1,29 +0,0 @@ - -
-
- {% for field in fields %} - {% if field.type %} - {% set value = data.value(field.name) %} -
- {% include ["forms/fields/#{field.type}/#{field.type}.html.twig", 'forms/fields/text/text.html.twig'] %} -
- {% endif %} - {% endfor %} - - - - - -
-
- {{ "Moving" }}... -
- - -
-
-
\ No newline at end of file diff --git a/plugins/admin-media-move/CHANGELOG.md b/plugins/admin-media-move/CHANGELOG.md deleted file mode 100644 index 78d241c..0000000 --- a/plugins/admin-media-move/CHANGELOG.md +++ /dev/null @@ -1,30 +0,0 @@ -# v1.0.4 -## 12/11/2018 - -1. [](#bugfix) - * Update addInlineJs load order - -# v1.0.3 -## 2/24/2018 - -1. [](#new) - * Check that dependencies are enabled before loading - -# v1.0.2 -## 2/24/2018 - -1. [](#new) - * Check for dependencies before loading - -# v1.0.1 -## 2/14/2018 - -1. [](#new) - * Update bugs URL - * Update addAction signature - -# v1.0.0 -## 1/24/2018 - -1. [](#initial) - * \ No newline at end of file diff --git a/plugins/admin-media-move/LICENSE b/plugins/admin-media-move/LICENSE deleted file mode 100644 index bef72fe..0000000 --- a/plugins/admin-media-move/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2018 TwelveTone LLC - -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/plugins/admin-media-move/README.md b/plugins/admin-media-move/README.md deleted file mode 100644 index fa37de8..0000000 --- a/plugins/admin-media-move/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# Admin Media Move Plugin - -The **Admin Media Move** Plugin is for [Grav CMS](http://github.com/getgrav/grav). A plugin which adds the option to move media files in the page bin to another page. - -## Installation - -Installing the Admin Media Move plugin can be done in one of two ways. The GPM (Grav Package Manager) installation method enables you to quickly and easily install the plugin with a simple terminal command, while the manual method enables you to do so via a zip file. - -### GPM Installation (Preferred) - -The simplest way to install this plugin is via the [Grav Package Manager (GPM)](http://learn.getgrav.org/advanced/grav-gpm) through your system's terminal (also called the command line). From the root of your Grav install type: - - bin/gpm install admin-media-move - -This will install the Admin Media Move plugin into your `/user/plugins` directory within Grav. Its files can be found under `/your/site/grav/user/plugins/admin-media-move`. - -### Manual Installation - -To install this plugin, just download the zip version of this repository and unzip it under `/your/site/grav/user/plugins`. Then, rename the folder to `admin-media-move`. You can find these files on [GitHub](https://github.com) or via [GetGrav.org](http://getgrav.org/downloads/plugins#extras). - -You should now have all the plugin files under - - /your/site/grav/user/plugins/admin-media-move - -> NOTE: This plugin is a modular component for Grav which requires [Grav](http://github.com/getgrav/grav) and the [Admin](https://github.com/getgrav/grav-plugin-admin) plugin to operate. - -## Usage diff --git a/plugins/admin-media-move/admin-media-move.php b/plugins/admin-media-move/admin-media-move.php deleted file mode 100644 index 14be869..0000000 --- a/plugins/admin-media-move/admin-media-move.php +++ /dev/null @@ -1,234 +0,0 @@ - ['onPluginsInitialized', 0] - ]; - } - - public function getPath() - { - return '/' . trim($this->grav['admin']->base, '/') . '/' . trim(self::ROUTE, '/'); - } - - public function buildBaseUrl() - { - $ret = rtrim($this->grav['uri']->rootUrl(false), '/') . '/' . trim($this->getPath(), '/'); - return $ret; - } - - public function onPluginsInitialized() - { - if (!$this->isAdmin() || !$this->grav['user']->authenticated) { - return; - } - - if ($this->grav['uri']->path() == $this->getPath()) { - return; - } - - if (!self::_checkDependencies($this)) { - return; - } - - $this->enable([ - 'onTwigTemplatePaths' => ['onTwigTemplatePaths', 0], - 'onPagesInitialized' => ['onTwigExtensions', 0], - ]); - - $this->grav['media-actions']->addAction([ - 'actionId' => "MediaMove", - 'caption' => "Move", - 'icon' => "arrows", - 'handler' => function ($page, $mediaName, $payload) { - - $destination_route = $payload['destination_route']; - - if (!$destination_route || !$page || !$mediaName || !$payload) { - $this->outputError("Invalid input"); - } - - $basePath = $page->path() . DS; - $filePath = $basePath . $mediaName; - if (!file_exists($filePath)) { - $this->outputError("Media file not found"); - } - - // Locate the target page - $targetPage = $this->grav['pages']->find($destination_route); - if (!$targetPage) { - $this->outputError("Page for route $destination_route not found"); - } - - $path = $targetPage->path(); - try { - rename($filePath, "$path/$mediaName"); - $this->grav['log']->info("Moved media file '$mediaName' to '$path'"); - } catch (\Exception $e) { - $this->outputError("Could not move file: " . $e); - } - - $ret = [ - "error" => false - ]; - - // Redirects will not work for fetch, so send destination url in result - if (get($payload, "go", false)) { - // Get the admin edit-page url - //$url = $this->grav['twig']->twig->getExtension('Grav\Plugin\Admin\AdminTwigExtension')->getPageUrl($this, $targetPage); - $url = $this->grav['uri']->rootUrl(false) . "/admin/pages" . $targetPage->route(); - $ret["destination_url"] = $url; - } - - //header('HTTP/1.1 200 OK'); - return $ret; - } - ]); - } - - public function onTwigTemplatePaths() - { - $this->grav['twig']->twig_paths[] = __DIR__ . '/templates'; - } - - public function onTwigExtensions() - { - $page = $this->grav['admin']->page(true); - if (!$page) { - return; - } - - $modal_move = $this->grav['twig']->twig()->render('move-modal.twig.html', $this->config->get('plugins.admin-media-move.modal_move')); - $jsConfig_move = [ - 'MODAL' => $modal_move - ]; - $this->grav['assets']->addInlineJs('var ADMIN_ADDON_MEDIA_MOVE = ' . json_encode($jsConfig_move) . ';', -1000); - $this->grav['assets']->addJs('plugin://admin-media-move/assets/media_move_action.js', -1000, false); - } - - public function outputError($msg) - { - header('HTTP/1.1 400 Bad Request'); - die(json_encode(['error' => ['msg' => $msg]])); - } - - /** - * Checks plugin dependencies. Call this after all plugins have been loaded and are enabled. - * - * @param $plugin - * @param $issues array Receives issues as strings. If null, grav['messages'] is used. - * @return bool true if dependencies are met. - */ - public static function _checkDependencies($plugin, &$issues = null) - { - $grav = Grav::instance(); - $errors = 0; - $messages = $grav['messages']; - $plugins = $grav['plugins']; - - $deps = $plugin->getBlueprint()->dependencies; - if ($deps) { - foreach ($deps as $dep) { - $name = $dep['name']; - if ($name === 'grav') { - //TODO check grav version - continue; - } - $version = $dep['version']; - if (!preg_match("#^([<>=]+)?(.*)#", $version, $m)) { - continue; - } - $compare = $m[1]; - $version = $m[2]; - if (!$compare) { - $compare = '='; - } - - $found = $plugins->get($name); - if (!$found) { - $msg = "Missing Dependency: '$name'"; - if (is_array($issues)) { - $issues[] = $msg; - } else { - $messages->add($msg, 'error'); - } - $errors++; - continue; - } - if (!$grav['config']->get("plugins.$name.enabled")) { - //BUG admin should always be enabled if installed - if ($name !== 'admin') { - $msg = "Dependency Not Enabled: '$name'"; - if (is_array($issues)) { - $issues[] = $msg; - } else { - $messages->add($msg, 'error'); - } - $errors++; - continue; - } - } - $realVersion = $found->blueprints()->version; - if (!version_compare($realVersion, $version, $compare)) { - $msg = "Missing Dependency: '$name' $version"; - if (is_array($issues)) { - $issues[] = $msg; - } else { - $messages->add($msg, 'error'); - } - $errors++; - continue; - } - } - } - if ($errors > 0) { - $msg = "Plugin '$plugin->name' was not loaded due to dependency issues"; - if (is_array($issues)) { - $issues[] = $msg; - } else { - $messages->add($msg, 'error'); - } - } - return $errors === 0; - } - - -} diff --git a/plugins/admin-media-move/admin-media-move.yaml b/plugins/admin-media-move/admin-media-move.yaml deleted file mode 100644 index 6c76c4b..0000000 --- a/plugins/admin-media-move/admin-media-move.yaml +++ /dev/null @@ -1,44 +0,0 @@ -# -# The MIT License (MIT) -# -# Copyright (c) 2018 TwelveTone LLC -# -# 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. -# - -enabled: true - -modal_move: - fields: - - type: section - title: "Move Media" - - - type: text - label: Filename - name: file_name - readonly: true - - - type: pages - label: Destination Page - name: destination_page - - - type: text - label: Destination Route - name: destination_route - autofocus: on diff --git a/plugins/admin-media-move/assets/media_move_action.js b/plugins/admin-media-move/assets/media_move_action.js deleted file mode 100644 index 8e6ebd5..0000000 --- a/plugins/admin-media-move/assets/media_move_action.js +++ /dev/null @@ -1,70 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2018 TwelveTone LLC - * - * 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. - */ - -// This must be in a function call for remodal to register it -$(function () { - $('body').append(ADMIN_ADDON_MEDIA_MOVE.MODAL); -}); - -function onMediaAction_MediaMove(actionId, mediaName, mediaElement) { - var modal = $.remodal.lookup[$('[data-remodal-id=modal-admin-media-move]').data('remodal')]; - modal.open(); - - var $modal = modal.$modal; - // Populate fields - $('[name=file_name]', $modal).val(mediaName); - $('[name=destination_route]', $modal).val(""); - $('[name=destination_page]', $modal).val(""); - - // Reset loading state - $('.loading', $modal).addClass('hidden'); - $('.button', $modal).removeClass('hidden').css('visibility', 'visible'); - - $(document).off('click', '[data-remodal-id=modal-admin-media-move] .button'); - $(document).on('click', '[data-remodal-id=modal-admin-media-move] .button', function (e) { - var destination_route = $('[name=destination_route]').val(); - if (!destination_route) { - destination_route = $('[name=destination_page]').val(); - } - if (destination_route) { - const payload = { - destination_route - }; - if (e.target.name === 'move_and_go') { - payload.go = true; - } - const callback = function (result) { - if (result.error) { - alert(result.error.msg); - } else { - $(mediaElement).remove(); - if (payload.go) { - window.location = result.result.destination_url; - } - } - }; - submitMediaAction(actionId, mediaName, payload, callback, modal); - } - }); -} \ No newline at end of file diff --git a/plugins/admin-media-move/blueprints.yaml b/plugins/admin-media-move/blueprints.yaml deleted file mode 100644 index 73faaad..0000000 --- a/plugins/admin-media-move/blueprints.yaml +++ /dev/null @@ -1,55 +0,0 @@ -# -# The MIT License (MIT) -# -# Copyright (c) 2018 TwelveTone LLC -# -# 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. -# - -name: Admin Media Move -version: 1.0.4 -description: Moves media from one page to another. -icon: plug -author: - name: TwelveTone LLC - email: info@twelvetone.tv -homepage: https://www.twelvetone.tv/docs/developer-tools/grav-plugins/grav-admin-media-move-plugin -keywords: grav, plugin, admin, media -bugs: https://github.com/Flamenco/grav-admin-media-move -docs: https://www.twelvetone.tv/docs/developer-tools/grav-plugins/grav-admin-media-move-plugin -license: MIT - -dependencies: - - { name: grav, version: '>=1.0.0' } - - { name: admin, version: '>=1.0.0' } - - { name: admin-media-actions, version: '>=1.0.0' } - -form: - validation: strict - fields: - enabled: - type: toggle - label: Plugin status - highlight: 1 - default: 0 - options: - 1: Enabled - 0: Disabled - validate: - type: bool diff --git a/plugins/admin-media-move/build.gradle b/plugins/admin-media-move/build.gradle deleted file mode 100644 index 8ec85cc..0000000 --- a/plugins/admin-media-move/build.gradle +++ /dev/null @@ -1,17 +0,0 @@ -plugins { - id("com.github.hierynomus.license").version("0.14.0") -} -apply plugin:'java' - -sourceSets { - grav { - resources { - srcDirs += "." - include "**/*.yaml" - include "**/*.php" - include "**/*.css" - include "**/*.js" - include "**/*.twig" - } - } -} \ No newline at end of file diff --git a/plugins/admin-media-move/settings.gradle b/plugins/admin-media-move/settings.gradle deleted file mode 100644 index e69de29..0000000 diff --git a/plugins/admin-media-move/templates/move-modal.twig.html b/plugins/admin-media-move/templates/move-modal.twig.html deleted file mode 100644 index b66cf7e..0000000 --- a/plugins/admin-media-move/templates/move-modal.twig.html +++ /dev/null @@ -1,23 +0,0 @@ -
-
- {% for field in fields %} - {% if field.type %} - {% set value = data.value(field.name) %} -
- {% include ["forms/fields/#{field.type}/#{field.type}.html.twig", 'forms/fields/text/text.html.twig'] %} -
- {% endif %} - {% endfor %} - -
Select a destination page or enter the destination page route.
- -
-
- {{ "Moving" }}... -
- - - -
-
-
\ No newline at end of file diff --git a/plugins/admin-media-replace/CHANGELOG.md b/plugins/admin-media-replace/CHANGELOG.md deleted file mode 100644 index 38041e4..0000000 --- a/plugins/admin-media-replace/CHANGELOG.md +++ /dev/null @@ -1,32 +0,0 @@ -# v1.0.4 -## 12/11/2018 - -1. [](#feature) - * Update documentation - -# v1.0.3 -## 2/24/2018 - -1. [](#new) - * Check that dependencies are enabled before loading - -# v1.0.2 -## 2/24/2018 - -1. [](#new) - * Check for dependencies before loading - -# v1.0.1 -## 1/25/2018 - -1. [](#new) - * Add dialog - * Add quicksend option - * Enforce extension, image, and file-rename options - * Refactor project layout - -# v1.0.0 -## 1/24/2018 - -1. [](#initial) - * \ No newline at end of file diff --git a/plugins/admin-media-replace/LICENSE b/plugins/admin-media-replace/LICENSE deleted file mode 100644 index bef72fe..0000000 --- a/plugins/admin-media-replace/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2018 TwelveTone LLC - -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/plugins/admin-media-replace/README.md b/plugins/admin-media-replace/README.md deleted file mode 100644 index f9be009..0000000 --- a/plugins/admin-media-replace/README.md +++ /dev/null @@ -1,29 +0,0 @@ -# Admin Media Replace Plugin - -The **Admin Media Replace** Plugin is for [Grav CMS](http://github.com/getgrav/grav). A plugin which adds the option to replace media. - -## Installation - -Installing the Admin Media Replace plugin can be done in one of two ways. The GPM (Grav Package Manager) installation method enables you to quickly and easily install the plugin with a simple terminal command, while the manual method enables you to do so via a zip file. - -### GPM Installation (Preferred) - -The simplest way to install this plugin is via the [Grav Package Manager (GPM)](http://learn.getgrav.org/advanced/grav-gpm) through your system's terminal (also called the command line). From the root of your Grav install type: - - bin/gpm install admin-media-replace - -This will install the Admin Media Replace plugin into your `/user/plugins` directory within Grav. Its files can be found under `/your/site/grav/user/plugins/admin-media-replace`. - -### Manual Installation - -To install this plugin, just download the zip version of this repository and unzip it under `/your/site/grav/user/plugins`. Then, rename the folder to `admin-media-replace`. You can find these files on [GitHub](https://github.com) or via [GetGrav.org](http://getgrav.org/downloads/plugins#extras). - -You should now have all the plugin files under - - /your/site/grav/user/plugins/admin-media-replace - -> NOTE: This plugin is a modular component for Grav which requires [Grav](http://github.com/getgrav/grav) and the [Admin](https://github.com/getgrav/grav-plugin-admin) plugin to operate. - -## Usage - -See [Official Documentation](https://www.twelvetone.tv/docs/developer-tools/grav-plugins/admin-media-replace-plugin) diff --git a/plugins/admin-media-replace/admin-media-replace.php b/plugins/admin-media-replace/admin-media-replace.php deleted file mode 100644 index 78c80cf..0000000 --- a/plugins/admin-media-replace/admin-media-replace.php +++ /dev/null @@ -1,297 +0,0 @@ - ['onPluginsInitialized', 0] - ]; - } - - public function onPluginsInitialized() - { - if (!$this->isAdmin() || !$this->grav['user']->authenticated) { - return; - } - - if (!self::_checkDependencies($this)) { - return; - } - - $this->enable([ - 'onAdminTwigTemplatePaths' => ['onAdminTwigTemplatePaths', 0], - 'onTwigTemplatePaths' => ['onTwigTemplatePaths', 0], - 'onTwigInitialized' => ['onTwigInitialized', 0], - 'onTwigExtensions' => ['onTwigExtensions', -1], - 'onPageNotFound' => ['onPageNotFound', 1], - ]); - - $this->grav['media-actions']->addAction([ - 'actionId' => "MediaReplace", - 'caption' => "Replace", - 'icon' => "exchange", - 'handler' => function ($page, $mediaName, $payload) { - $ret = [ - "error" => false - ]; - return $ret; - } - ]); - } - - public function onPageNotFound($e) - { - if (!$this->isAdmin()) { - return; - } - - $route = $this->grav['admin']->location . "/" . $this->grav['admin']->route; - switch ($route) { - case "admin-media-replace/replace": - try { - $filename = array_get($_POST, "media-new-filename"); - $route = array_get($_POST, "media-route"); - $media = array_get($_POST, "media-filename"); - - $media_rename = array_get($_POST, "media-rename", "1") === "1"; - $require_image = array_get($_POST, "media-require-image", "1") === "1"; - $match_extension = array_get($_POST, "media-match-extension", "1") === "1"; - - $page = $this->grav['pages']->find($route); - if (!$page) { - throw new \Exception("Page not found."); - } - $mediaPath = $page->path() . "/" . $media; - if (!is_file($mediaPath)) { - throw new \Exception("Media not found."); - } - - $tmp_name = $_FILES['mediaupload']['tmp_name']; - - if ($match_extension) { - if (basename($filename) !== basename($media)) { - throw new \Exception("Media extensions do not match."); - } - } - - if ($require_image) { - $finfo = finfo_open(FILEINFO_MIME_TYPE); - $mime = finfo_file($finfo, $_FILES['mediaupload']['tmp_name']); - finfo_close($finfo); - if (!Utils::startsWith($mime, "image/")) { - throw new \Exception("Media must be an image."); - } - } - - if ($media_rename) { - // overwrite current file - $finalName = basename($mediaPath); - } else { - // delete current file - unlink($page->path() . '/' . $media); - $finalName = basename($filename); - } - - move_uploaded_file($tmp_name, $page->path() . '/' . $finalName); - //$tmp_name = $_FILES["pictures"]["tmp_name"][$key]; - // basename() may prevent filesystem traversal attacks; - // further validation/sanitation of the filename may be appropriate - //$name = basename($_FILES["pictures"]["name"][$key]); - - $media1 = new Media($page->path()); - $medium = $media1[basename($finalName)]; - $url = $medium->display($medium->get('extension') === 'svg' ? 'source' : 'thumbnail')->cropZoom(400, 300)->url(); - - $ret = ["thumbnail" => $url]; - $ret['newName'] = $finalName; -// if (!$media_rename) { -// $ret['toast'] = "Refresh the page to update the new page media name."; -// } - die(json_encode($ret)); - - // Get original name - //$source = $medium->higherQualityAlternative()->get('filename'); - //$media_list[$name] = ['url' => $medium->display($medium->get('extension') === 'svg' ? 'source' : 'thumbnail')->cropZoom(400, 300)->url(), 'size' => $medium->get('size'), 'metadata' => $metadata, 'original' => $source->get('filename')]; - - } catch - (\Exception $exception) { -// die(print_r($_SERVER)); - die(json_encode(["error" => $exception->getMessage()])); - } - break; - } - } - - public - function onTwigTemplatePaths() - { - $this->grav['twig']->twig_paths[] = __DIR__ . '/templates'; - } - - public - function onTwigInitialized() - { - $this->grav['assets']->addJs('plugin://admin-media-replace/assets/dialog_util.js', -1000, false); - $this->grav['assets']->addJs('plugin://admin-media-replace/assets/media_replace_action.js', -1000, false); - if ($this->config->get("plugins.admin-media-replace.quicksend", false)) { - $this->grav['assets']->addInlineJs("const _media_replace_isQuicksend = true;"); - } - } - - public - function onTwigExtensions() - { - if (!$this->isAdmin()) { - return; - } - addModalForm("MediaReplace", "generic-modal.twig.html"); - } - - public - function onAdminTwigTemplatePaths($event) - { - $event['paths'] = array_merge($event['paths'], [__DIR__ . '/templates']); - return $event; - } - - public - function outputError($msg) - { - header('HTTP/1.1 400 Bad Request'); - die(json_encode(['error' => ['msg' => $msg]])); - } - - /** - * Checks plugin dependencies. Call this after all plugins have been loaded and are enabled. - * - * @param $plugin - * @param $issues array Receives issues as strings. If null, grav['messages'] is used. - * @return bool true if dependencies are met. - */ - public static function _checkDependencies($plugin, &$issues = null) - { - $grav = Grav::instance(); - $errors = 0; - $messages = $grav['messages']; - $plugins = $grav['plugins']; - - $deps = $plugin->getBlueprint()->dependencies; - if ($deps) { - foreach ($deps as $dep) { - $name = $dep['name']; - if ($name === 'grav') { - //TODO check grav version - continue; - } - $version = $dep['version']; - if (!preg_match("#^([<>=]+)?(.*)#", $version, $m)) { - continue; - } - $compare = $m[1]; - $version = $m[2]; - if (!$compare) { - $compare = '='; - } - - $found = $plugins->get($name); - if (!$found) { - $msg = "Missing Dependency: '$name'"; - if (is_array($issues)) { - $issues[] = $msg; - } else { - $messages->add($msg, 'error'); - } - $errors++; - continue; - } - if (!$grav['config']->get("plugins.$name.enabled")) { - //BUG admin should always be enabled if installed - if ($name !== 'admin') { - $msg = "Dependency Not Enabled: '$name'"; - if (is_array($issues)) { - $issues[] = $msg; - } else { - $messages->add($msg, 'error'); - } - $errors++; - continue; - } - } - $realVersion = $found->blueprints()->version; - if (!version_compare($realVersion, $version, $compare)) { - $msg = "Missing Dependency: '$name' $version"; - if (is_array($issues)) { - $issues[] = $msg; - } else { - $messages->add($msg, 'error'); - } - $errors++; - continue; - } - } - } - if ($errors > 0) { - $msg = "Plugin '$plugin->name' was not loaded due to dependency issues"; - if (is_array($issues)) { - $issues[] = $msg; - } else { - $messages->add($msg, 'error'); - } - } - return $errors === 0; - } - - -} diff --git a/plugins/admin-media-replace/admin-media-replace.yaml b/plugins/admin-media-replace/admin-media-replace.yaml deleted file mode 100644 index c452d30..0000000 --- a/plugins/admin-media-replace/admin-media-replace.yaml +++ /dev/null @@ -1,26 +0,0 @@ -# -# The MIT License (MIT) -# -# Copyright (c) 2018 TwelveTone LLC -# -# 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. -# - -enabled: true -quicksend: false \ No newline at end of file diff --git a/plugins/admin-media-replace/assets/dialog_util.js b/plugins/admin-media-replace/assets/dialog_util.js deleted file mode 100644 index 079fa3b..0000000 --- a/plugins/admin-media-replace/assets/dialog_util.js +++ /dev/null @@ -1,55 +0,0 @@ -/** - * A re-modal wrapper to simplify usage. - */ - -function openModalDialog(remodalId) { - const dlgElement = $(`[data-remodal-id=${remodalId}]`); - const modal = $.remodal.lookup[dlgElement.data('remodal')]; - modal.open(); - - $(dlgElement).find('input[temporary=true]').remove(); - - return { - show: function () { - modal.open(); - }, - close: function () { - modal.close(); - }, - /** - * Replaces a message listener - * @param selector - * @param message - * @param callback - */ - on: function (selector, message, callback) { - const found = dlgElement.find(selector); - found.off(message); - found.on(message, callback); - }, - /** - * - * @param selector {string} - * @returns {element} The HTML element - */ - get: function (selector) { - const found = dlgElement.find(selector); - return found[0]; - }, - /** - * - * @param selector {string} - * @returns {jquery element} - */ - jget: function (selector) { - const found = dlgElement.find(selector); - return found; - }, - setHiddenField: function (name, value, temporary = true) { - const form = $(dlgElement).find('form'); - form.append(``); - } - } - // For getting/setting values - // var $modal = modal.$modal; -} \ No newline at end of file diff --git a/plugins/admin-media-replace/assets/media_replace_action.js b/plugins/admin-media-replace/assets/media_replace_action.js deleted file mode 100644 index 0d64651..0000000 --- a/plugins/admin-media-replace/assets/media_replace_action.js +++ /dev/null @@ -1,157 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2018 TwelveTone LLC - * - * 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. - */ - -//TODO refactor AJAX code - -function onMediaAction_MediaReplace(actionId, mediaName, mediaElement) { - - if (window._media_replace_isQuicksend) { - doQuicksend(actionId, mediaName, mediaElement); - return; - } - - const form = openModalDialog('MediaReplace'); - - form.on('.button[name=cancel]', 'click', () => { - form.close(); - }); - - form.on('.button[name=continue]', 'click', () => { - form.close(); - - const input = form.get('input[type=file]'); - if (input.files.length === 0) { - return; - } - - let file = input.files[0]; - let data = new FormData(); - data.append('mediaupload', file, file.name); - - let xhr = new XMLHttpRequest(); - xhr.open("POST", GravAdmin.config.base_url_relative + '/admin-media-replace/replace', true); - // xhr.setRequestHeader("X_FILENAME", file.name); - // Grav is stripping out X_ from $_SERVER - xhr.setRequestHeader("X-MEDIA-NEW-FILENAME", file.name); - xhr.setRequestHeader("X-MEDIA-ROUTE", '/' + GravAdmin.config.route); - xhr.setRequestHeader("X-MEDIA-FILENAME", mediaName); - - data.append("media-new-filename", file.name); - data.append("media-route", '/' + GravAdmin.config.route); - data.append("media-filename", mediaName); - data.append("media-rename", form.jget('input[name=rename_file]:checked').val()); - data.append("media-match-extension", form.jget('input[name=match_extension]:checked').val()); - data.append("media-require-image", form.jget('input[name=require_image]:checked').val()); - - xhr.onload = function () { - //get response and show the uploading status - if (xhr.status === 200) { - let response = JSON.parse(xhr.responseText); - if (response.error) { - alert(response.error); - } - else if (response.thumbnail) { - let img = mediaElement.querySelector('img'); - if (!img) { - return; - } - img.src = response.thumbnail + "?refresh=" + new Date().getTime(); - - if (response.toast) { - Grav.default.Utils.toastr.info(response.toast); - } - if (response.newName) { - const nameEle = $(mediaElement).find('[data-dz-name]'); - nameEle.text(response.newName); - } - } else { - location.reload(); - } - } - }; - - xhr.send(data); - }); - -} - -function doQuicksend(actionId, mediaName, mediaElement) { - let form = document.querySelector('form[id="replace-media"]'); - if (!form) { - form = $("
" + - "" + - "
")[0]; - document.body.appendChild(form); - - let input = form.querySelector('input[type=file]'); - - input.addEventListener('change', function () { - if (input.files.length !== 1) { - return; - } - - let file = input.files[0]; - let data = new FormData(); - data.append('mediaupload', file, file.name); - - let xhr = new XMLHttpRequest(); - xhr.open("POST", GravAdmin.config.base_url_relative + '/admin-media-replace/replace', true); - // xhr.setRequestHeader("X_FILENAME", file.name); - // Grav is stripping out X_ from $_SERVER - xhr.setRequestHeader("X-MEDIA-NEW-FILENAME", file.name); - xhr.setRequestHeader("X-MEDIA-ROUTE", '/' + GravAdmin.config.route); - xhr.setRequestHeader("X-MEDIA-FILENAME", mediaName); - - data.append("media-new-filename", file.name); - data.append("media-route", '/' + GravAdmin.config.route); - data.append("media-filename", mediaName); - data.append("media-rename", "1"); - data.append("media-match-extension", "1"); - data.append("media-require-image", "1"); - - xhr.onload = function () { - //get response and show the uploading status - if (xhr.status === 200) { - let response = JSON.parse(xhr.responseText); - if (response.error) { - alert(response.error); - } - else if (response.thumbnail) { - let img = mediaElement.querySelector('img'); - if (!img) { - return; - } - img.src = response.thumbnail + "?refresh=" + new Date().getTime(); - } else { - location.reload(); - } - } - }; - - xhr.send(data); - }); - } - let input = form.querySelector('input[type=file]'); - input.click(); -} \ No newline at end of file diff --git a/plugins/admin-media-replace/blueprints.yaml b/plugins/admin-media-replace/blueprints.yaml deleted file mode 100644 index 9c62ace..0000000 --- a/plugins/admin-media-replace/blueprints.yaml +++ /dev/null @@ -1,67 +0,0 @@ -# -# The MIT License (MIT) -# -# Copyright (c) 2018 TwelveTone LLC -# -# 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. -# - -name: Admin Media Replace -version: 1.0.4 -description: Replaces media in the page media bin. -icon: plug -author: - name: TwelveTone LLC - email: info@twelvetone.tv -homepage: https://www.twelvetone.tv/docs/developer-tools/grav-plugins/grav-admin-media-replace-plugin -keywords: grav, plugin, admin, media -bugs: https://www.twelvetone.tv/docs/developer-tools/grav-plugins/grav-admin-media-replace-plugin -docs: https://www.twelvetone.tv/docs/developer-tools/grav-plugins/grav-admin-media-replace-plugin -license: MIT - -dependencies: - - { name: grav, version: '>=1.0.0' } - - { name: admin, version: '>=1.0.0' } - - { name: admin-media-actions, version: '>=1.0.2' } - -form: - validation: strict - fields: - enabled: - type: toggle - label: Plugin status - highlight: 1 - default: 0 - options: - 1: Enabled - 0: Disabled - validate: - type: bool - - quicksend: - type: toggle - label: Quick send - description: Bypasses the upload dialog. - highlight: 1 - default: 1 - options: - 1: Enabled - 0: Disabled - validate: - type: bool \ No newline at end of file diff --git a/plugins/admin-media-replace/blueprints/media-replace.yaml b/plugins/admin-media-replace/blueprints/media-replace.yaml deleted file mode 100644 index af3f216..0000000 --- a/plugins/admin-media-replace/blueprints/media-replace.yaml +++ /dev/null @@ -1,51 +0,0 @@ -form: - fields: - - foobar: - type: section - title: Replace Media - - rename_file: - type: toggle - label: Rename file - description: Renames the uploaded file to the target file name. This includes the basename and extension. - highlight: 1 - default: 1 - options: - 1: Yes - 0: No - validate: - type: bool - - require_image: - type: toggle - label: Require image - description: Require upload to be an image MIME type. - highlight: 0 - default: 0 - options: - 1: Yes - 0: No - validate: - type: bool - - match_extension: - type: toggle - label: Match Extension - description: Require new file extension to match current file extension. - highlight: 0 - default: 0 - options: - 1: Yes - 0: No - validate: - type: bool - - file: - type: singlefile - label: File - description: You can also drop a file on the choose file button. - - spacer: - type: spacer - text: To bypass this dialog and simply pick and send the file using default values, go to the plugin settings and enable quicksend. \ No newline at end of file diff --git a/plugins/admin-media-replace/build.gradle b/plugins/admin-media-replace/build.gradle deleted file mode 100644 index 8ec85cc..0000000 --- a/plugins/admin-media-replace/build.gradle +++ /dev/null @@ -1,17 +0,0 @@ -plugins { - id("com.github.hierynomus.license").version("0.14.0") -} -apply plugin:'java' - -sourceSets { - grav { - resources { - srcDirs += "." - include "**/*.yaml" - include "**/*.php" - include "**/*.css" - include "**/*.js" - include "**/*.twig" - } - } -} \ No newline at end of file diff --git a/plugins/admin-media-replace/classes/DialogUtil.php b/plugins/admin-media-replace/classes/DialogUtil.php deleted file mode 100644 index 36b4473..0000000 --- a/plugins/admin-media-replace/classes/DialogUtil.php +++ /dev/null @@ -1,29 +0,0 @@ -setContext(__DIR__ . "/../blueprints"); - $bpNewPage = $bpNewPage->load()->init(); - - $params = []; - $params["remodalId"] = $jsid; - $params["fields"] = $bpNewPage->toArray()['form']['fields']; - - $grav = \Grav\Common\Grav::instance(); - $rendered = $grav['twig']->twig()->render($twigName, $params); - $arr = [ - 'MODAL' => $rendered - ]; - - $grav['assets']->addInlineJs("var $jsid = " . json_encode($arr) . ';', -1000, false); - - $modalReg = " - $(function () { - $('body').append($jsid.MODAL); - });"; - $grav['assets']->addInlineJs($modalReg, -999, false); - -} \ No newline at end of file diff --git a/plugins/admin-media-replace/settings.gradle b/plugins/admin-media-replace/settings.gradle deleted file mode 100644 index e69de29..0000000 diff --git a/plugins/admin-media-replace/templates/forms/fields/singlefile/singlefile.html.twig b/plugins/admin-media-replace/templates/forms/fields/singlefile/singlefile.html.twig deleted file mode 100644 index 95b76ff..0000000 --- a/plugins/admin-media-replace/templates/forms/fields/singlefile/singlefile.html.twig +++ /dev/null @@ -1,9 +0,0 @@ -{% extends "forms/field.html.twig" %} - -{% block label %} - {{ label ?: "File" }} -{% endblock %} - -{% block input %} - -{% endblock %} \ No newline at end of file diff --git a/plugins/admin-media-replace/templates/generic-modal.twig.html b/plugins/admin-media-replace/templates/generic-modal.twig.html deleted file mode 100644 index 800e72d..0000000 --- a/plugins/admin-media-replace/templates/generic-modal.twig.html +++ /dev/null @@ -1,22 +0,0 @@ -
-
- {% for name, field in fields %} - {% if field.type %} - {% set value = data.value(name) %} -
- {% include ["forms/fields/#{field.type}/#{field.type}.html.twig", 'forms/fields/text/text.html.twig'] %} -
- {% endif %} - {% endfor %} - -
{{message}}
- -
- - - - - -
-
-
\ No newline at end of file diff --git a/plugins/admin/.github/FUNDING.yml b/plugins/admin/.github/FUNDING.yml deleted file mode 100644 index e84f52b..0000000 --- a/plugins/admin/.github/FUNDING.yml +++ /dev/null @@ -1,8 +0,0 @@ -# These are supported funding model platforms - -github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] -patreon: # Replace with a single Patreon username -open_collective: grav -ko_fi: # Replace with a single Ko-fi username -tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel -custom: # Replace with a single custom sponsorship URL diff --git a/plugins/admin/.github/dependabot.yml b/plugins/admin/.github/dependabot.yml deleted file mode 100644 index 203f3c8..0000000 --- a/plugins/admin/.github/dependabot.yml +++ /dev/null @@ -1,6 +0,0 @@ -version: 2 -updates: -- package-ecosystem: "github-actions" - directory: "/" - schedule: - interval: "weekly" diff --git a/plugins/admin/CHANGELOG.md b/plugins/admin/CHANGELOG.md deleted file mode 100644 index ad75e84..0000000 --- a/plugins/admin/CHANGELOG.md +++ /dev/null @@ -1,2725 +0,0 @@ -# v1.10.49.4 -## 04/16/2026 - -1. [](#new) - * Grav 2.0 migration banner on the dashboard — surfaces when the remote advertises a next-major release, with stacked CTAs for either "Start migration" (when migrate-grav is enabled) or "Install Migrate plugin" (deep-linking to `/admin/plugins/migrate-grav`), plus an external "Learn how to migrate" link -2. [](#improved) - * Log date handling in Tools → Logs now renders more reliably ([#2497](https://github.com/getgrav/grav-plugin-admin/pull/2497)) - * Backup dates now carry a `title` attribute for the full timestamp on hover ([#2499](https://github.com/getgrav/grav-plugin-admin/pull/2499)) -3. [](#bugfix) - * Scheduler status display now matches runtime enabled logic — no more "enabled" showing for jobs that won't actually run - * Single-file save path fixed - * Module folder renames now preserve the leading underscore (`_folder`) - * 2FA verification no longer fails when the pasted token carries trailing/embedded whitespace ([#2489](https://github.com/getgrav/grav-plugin-admin/issues/2489)) - * scheduler-webhook plugin compatibility fixes - -# v1.10.49.3 -## 01/27/2026 - -1. [](#improved) - * Support new `licensing.getgrav.org` server for premium downloads - -# v1.10.49.2 -## 12/29/2025 - -1. [](#improved) - * Added fallback autoloader to handle class location changes during upgrades - * Lazy-load WhiteLabel and ScssCompiler to avoid loading scssphp during upgrades - * Use sendJsonResponse() to exit early after package install/reinstall tasks - -# v1.10.49.1 -## 09/03/2025 - -1. [](#bugfix) - * Fixed several JS issues with Notifications and Scheduler - -# v1.10.49 -## 08/25/2025 - -1. [](#new) - * Upgraded to very latest FontAwesome 7.0 with custom ForkAwesome Shim - * Support for enhanced Scheduler in admin - * PHP 8.4 compatibility -1. [](#improved) - * Vendor libraries updated - * Added translations for Fetchpriority Trait [#2436](https://github.com/getgrav/grav-plugin-admin/pull/2346) - * Other various missing langs strings added to 'english' translation -1. [](#bugfix) - * Fix `force_ssl` use schema instead of server var [#2435](https://github.com/getgrav/grav-plugin-admin/pull/2345) - * Fix for fully turning off notifications JS - -# v1.10.48 -## 10/28/2024 - -1. [](#improved) - * Treat AVIF as image when inserting / drag & dropping - * PHP 8.4 fixes - Implicitly nullable parameter declarations deprecate - -# v1.10.47 -## 10/22/2024 - -1. [](#improved) - * Added missing `show_label` logic in list field - * Use plugin's selected icon when in plugin properties - -# v1.10.46 -## 05/15/2024 - -1. [](#improved) - * Used Login's new `site_host` security setting for Admin password reset. Requires Login version `3.7.8+` - -# v1.10.45 -## 03/18/2024 - -1. [](#improved) - * Improved class assignment for form fields [#2399](https://github.com/getgrav/grav-plugin-admin/pull/2379) - * Added label, sublabel, and icon help to list field [#2384](https://github.com/getgrav/grav-plugin-admin/pull/2384) - * Set admin language to user preference [#2369](https://github.com/getgrav/grav-plugin-admin/pull/2369) - * Updated language files to [latest translations](https://crowdin.com/project/grav-admin) - -# v1.10.44 -## 01/05/2024 - -1. [](#improved) - * Updated language files for Image Decoding [getgrav/grav#3796](https://github.com/getgrav/grav/pull/3796) - -# v1.10.44 -## 01/05/2024 - -1. [](#improved) - * Updated languages with fresh **Crowdin.com** builds - * Updated copyright date -1. [](#bugfix) - * fixed `medium` tags in select fields [#2376]((https://github.com/getgrav/grav-plugin-admin/pull/2376) - -# v1.10.43 -## 10/02/2023 - -1. [](#improved) - * Updated vendor libraries - -# v1.10.42 -## 06/14/2023 - -1. [](#new) - * Added a couple of string translations - -# v1.10.41.2 -## 05/11/2023 - -1. [](#improved) - * Fixed an issue with `lastBackup()` that caused admin dashboard to fail with an error. - -# v1.10.41.1 -## 05/09/2023 - -1. [](#improved) - * Fixed another Toolbox deprecation error for `lastBackup()` - -# v1.10.41 -## 05/09/2023 - -1. [](#new) - * Updated to use new `BaconQRCode` version `2.0.8` for new SVG features + PHP 8.2+ fixes -1. [](#improved) - * Require Grav `v1.7.41` - * Fixed a deprecated message where `Admin::$routes` was being dynamically defined - * Fixes to use non-deprecated methods in `ScssCompiler` - -# v1.10.40 -## 03/22/2023 - -1. [](#new) - * Added Github actions for dependabot [#2258](https://github.com/getgrav/grav-plugin-admin/pull/2258) -1. [](#improved) - * Syslog tag fields label added [#2296](https://github.com/getgrav/grav-plugin-admin/pull/2296) - * Updated vendor libraries to the latest versions -1. [](#bugfix) - * Fix more than one file upload [#2317](https://github.com/getgrav/grav-plugin-admin/pull/2317) - -# v1.10.39 -## 02/19/2023 - -1. [](#bugfix) - * Forked and fixed PicoFeed library to support PHP 8.2 - -# v1.10.38 -## 01/02/2023 - -1. [](#new) - * Update copyright dates - * Keep version number in sync with Grav version - -# 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 -## 09/08/2022 - -1. [](#bugfix) - * Fixed `fieldset.html.twig` not rendering with `markdown: false` [#2313](https://github.com/getgrav/grav-plugin-admin/pull/2313) - -# v1.10.35 -## 08/04/2022 - -1. [](#improved) - * Improvements in CodeMirror editor in RTL mode [#359](https://github.com/getgrav/grav-plugin-admin/issues/359), [#2297](https://github.com/getgrav/grav-plugin-admin/pull/2297) - -# v1.10.34 -## 06/22/2022 - -1. [](#improved) - * Exposed `UriToMarkdown` util (`Grav.default.Utils.UriToMarkdown`) in admin, to convert links/images -1. [](#bugfix) - * Fixed `Latest Page Updates` permissions [#2294](https://github.com/getgrav/grav-plugin-admin/pull/2294) - -# v1.10.33.1 -## 04/25/2022 - -1. [](#bugfix) - * Reverted [PR#2265](https://github.com/getgrav/grav-plugin-admin/pull/2265) as it broke sections output - -# v1.10.33 -## 04/25/2022 - -1. [](#new) - * Require **Form 6.0.1** -2. [](#improved) - * Added support for a single `field:` vs `fields:` in element form field to store a single value to the option field - * Allow new media collapser logic to configure different cookie storage name location via `data-storage-location` -1. [](#bugfix) - * Fixed nested element form fields - * Fixed `columns` and `column` fields with `.dotted` variables inside to ignore columns and column names - * Fixed initial elements state not being restored - -# v1.10.32 -## 03/28/2022 - -1. [](#new) - * Require **Grav 1.7.32**, **Form 6.0.0**, **Login 3.7.0**, **Email 3.1.6** and **Flex Objects 1.2.0** -2. [](#improved) - * List field: Support for default values other than key/value [#2255](https://github.com/getgrav/grav-plugin-admin/issues/2255) - * Added question icon to admin fields with help text [#2261](https://github.com/getgrav/grav-plugin-admin/issues/2261) -3. [](#bugfix) - * Fix nested `toggleable`: originalValue now checks with `??` instead of `is defined` - -# v1.10.31 -## 03/14/2022 - -1. [](#new) - * Added new local Multiavatar (local generation). **This will be default in Grav 1.8** -2. [](#bugfix) - * Patch `collection.js` [#2235](https://github.com/getgrav/grav-plugin-admin/issues/2235) - -# v1.10.30.2 -## 02/09/2022 - -2. [](#bugfix) - * Fixed regression preventing new `elements` field from saving its state - -# v1.10.30.1 -## 02/09/2022 - -1. [](#improved) - * List field items will now require confirmation before getting deleted - -# v1.10.30 -## 02/07/2022 - -1. [](#new) - * Require **Grav 1.7.30** - * Updated SCSS compiler to v1.10 - * PageMedia can now be collapsed and thumbnails previewed smaller, in order to save room on the page. Selection will be remembered. - * DEPRECATED: Admin field `pages_list_display_field` is no longer available as an option [#2191](https://github.com/getgrav/grav-plugin-admin/issues/2191) - * When listing installable themes/plugins, it is now possible to sort them by [Premium](https://getgrav.org/premium) -2. [](#improved) - * Updated JavaScript dependencies - * Cleaned up JavaScript unused dependencies and warnings - * Removed unused style assets - * Plugins list rows now properly highlight on hover, no more guessing when wanting to disable a plugin! -3. [](#bugfix) - * Fixed `elements` field when it's used inside `list` field - * Fixed issue uploading non-images media when Resolution setting enabled in Admin [#2172](https://github.com/getgrav/grav-plugin-admin/issues/2172) - * Prevent fields from being toggled incorrectly by adding originalValue to childs of fieldset. [#2218](https://github.com/getgrav/grav-plugin-admin/pull/2218) - * Fixed persistent focus on Folder field when Adding page (Safari) [#2209](https://github.com/getgrav/grav-plugin-admin/issues/2209) - * Fixed performance of Plugins / Themes sort in the installation table - * Fixed list field with key/value pairs throwing an exception due to bad value [#2199](https://github.com/getgrav/grav-plugin-admin/issues/2199) - * Fixed disabling/enabling plugin from the list breaking the plugin configuration - -# v1.10.29 -## 01/28/2022 - -1. [](#new) - * Require **Grav 1.7.29** -3. [](#improved) - * Made path handling unicode-safe, use new `Utils::basename()` and `Utils::pathinfo()` everywhere - -# v1.10.28 -## 01/24/2022 - -1. [](#bugfix) - * Clean file names before displaying errors/metadata modals - * Recompiled JS for production [#2225](https://github.com/getgrav/grav-plugin-admin/issues/2225) - -# v1.10.27 -## 01/12/2022 - -1. [](#new) - * Support for `YubiKey OTP` 2-Factor authenticator - * New `elements` container field that shows/hides children fields based on boolean trigger value - * Requires Grav `v1.7.27` and Login `v3.6.2` -2. [](#improved) - * Added new asset language strings - -# v1.10.26.1 -## 01/03/2022 - -3. [](#bugfix) - * Fixed an issue with missing files reference by cached autoloader - -# v1.10.26 -## 01/03/2022 - -2. [](#improved) - * Updated SCSS compiler to v1.9 and other vendor libraries - * Fixed various deprecation warnings - * Localized dialog buttons and icons [#2207](https://github.com/getgrav/grav-plugin-admin/pull/2207) - * Updated copyright year - -# v1.10.25 -## 11/16/2021 - -3. [](#bugfix) - * Fixed unescaped messages in JSON responses - -# v1.10.24 -## 10/26/2021 - -1. [](#new) - * Require **Grav 1.7.24** -2. [](#improved) - * Use new `Http\Response` rather than deprecated `GPM\Response` -3. [](#bugfix) - * Fixed an issue with invalid HTML throwing errors on HTML security scanning - * Clear cache when installing plugins - -# v1.10.23 -## 09/29/2021 - -1. [](#new) - * Updated SCSS compiler to v1.8 -2. [](#improved) - * Updated with latest language strings from Crowdin.com -3. [](#bugfix) - * Fixed images from plugins/themes disappearing when saving twice - -# v1.10.22 -## 09/16/2021 - -1. [](#new) - * Updated SCSS compiler to v1.7 - -# v1.10.21 -## 09/14/2021 - -1. [](#new) - * Require **Grav 1.7.21** -2. [](#improved) - * Added a note about UTC times in scheduler AT syntax help - * Now using a monospaced text-based scheduler AT field in scheduler for simplicity - * Improved `Admin:data()` and `Admin::getConfigurationData()` to be more strict -3. [](#bugfix) - * Fixed configuration save location to point to existing config folder [#2176](https://github.com/getgrav/grav-plugin-admin/issues/2176) - -# v1.10.20 -## 09/01/2021 - -1. [](#bugfix) - * Fixed regression `Argument 4 passed to Grav\Plugin\Form\TwigExtension::prepareFormField() must be of the type array` [#2177](https://github.com/getgrav/grav-plugin-admin/issues/2177) - * Fixed `X-Frame-Options` to be `DENY` in all admin pages to prevent a clickjacking attack - -# v1.10.19 -## 08/31/2021 - -1. [](#new) - * Require **Grav 1.7.19** and **Form 5.1.0** and **Login 3.5.0** - * Updated SCSS compiler to v1.6 -2. [](#improved) - * Updated forms and nested fields to use new form logic - * Admin form now use layout `admin`, meaning you can create admin specific field templates by `forms/fields/myfield/admin-field.html.twig` - * Stop using `|tu` filter, Grav already has the same logic in `|t` for admin - * Remove unneeded escapes - * Allow removal of plugin when disabled [#2167](https://github.com/getgrav/grav-plugin-admin/issues/2167) -3. [](#bugfix) - * Fixed missing values in `fieldset` form field - -# v1.10.18 -## 07/19/2021 - -1. [](#improved) - * Add logic to allow fieldset form field inside a list field [#2159](https://github.com/getgrav/grav-plugin-admin/pull/2159) - -# v1.10.17 -## 06/15/2021 - -1. [](#improved) - * Added timestamp as title in logs date [#2141](https://github.com/getgrav/grav-plugin-admin/issues/2141) - * Use `base64_encode` filter rather than function - * Composer update -1. [](#bugfix) - * Fixed missing `Remove Theme` button when the theme is inactive - * Update taskGetChildTypes() to use Flex Pages (works without the plugin) [#2087](https://github.com/getgrav/grav-plugin-admin/issues/2087) - -# v1.10.16 -## 06/02/2021 - -1. [](#bugfix) - * Fixed issue with some elements overflowing closed list items [#2146](https://github.com/getgrav/grav-plugin-admin/issues/2146) - * Fixed configuration not fully updating on save [#2149](https://github.com/getgrav/grav-plugin-admin/issues/2149) - * Fixed display issue with "+ Add Page" and picking a different route [#2136](https://github.com/getgrav/grav-plugin-admin/issues/2136), [#2145](https://github.com/getgrav/grav-plugin-admin/issues/2145) - * Treat WebP as image when inserting / drag & dropping [#2150](https://github.com/getgrav/grav-plugin-admin/issues/2150) - -# v1.10.15 -## 05/19/2021 - -1. [](#new) - * Updated SCSS compiler to v1.5 -1. [](#improved) - * Updated node modules dev dependencies - * Package.json scripts cleanup - * Recompiled JS for production - * Use `base645_encode` filter rather than function - * Editor: Do not assume images URLs are going to be `http://` (wrong assumption plus not SSL) [#2127](https://github.com/getgrav/grav-plugin-admin/issues/2127) - * Improved Theme Activation + Plugin Enabled logic to ensure configuration is not displayed unless activation/enabled state. Fixes [#2140](https://github.com/getgrav/grav-plugin-admin/issues/2140) -1. [](#bugfix) - * Fixed issue with slugify where single curly quotes in titles would translate to straight single quote [#2101](https://github.com/getgrav/grav-plugin-admin/issues/2101) - * Fix z-index issue with fullscreeen editor (and toolips) [#2143](https://github.com/getgrav/grav-plugin-admin/issues/2143) - -# v1.10.14 -## 04/29/2021 - -1. [](#improved) - * Added a `min_height:` option for list field -1. [](#bugfix) - * Fixed z-index issue for tooltips in sidebar - * Fixed custom files being overridden during theme update [#2135](https://github.com/getgrav/grav-plugin-admin/issues/2135) - -# v1.10.13 -## 04/23/2021 - -1. [](#new) - * Added refresh action button for Folder to ease the regeneration of the slug based on the title. Available also as API entry `Grav.default.Forms.Fields.FolderField.Regenerate()` [#1738](https://github.com/getgrav/grav-plugin-admin/issues/1738) -1. [](#improved) - * Removed sourcemaps references from fork-awesome.min.css [#2122](https://github.com/getgrav/grav-plugin-admin/issues/2122) - * Support native spell checkers in CodeMirror editor [#1266](https://github.com/getgrav/grav-plugin-admin/issues/1266) - * Added new 'Content Highlight' color to presets - * Copying Pages now prompts a dedicated modal that allows for picking title, folder name, parent location, page template and visibility [#1738](https://github.com/getgrav/grav-plugin-admin/issues/1738) - * Updated with latest language translations from Crowdin.com -1. [](#bugfix) - * Moved preset CSS compile to earlier in the process to ensure compilation happens in time. - * Prevent Save actions from Flex Objects to trigger the unsaved unload notice [#2125](https://github.com/getgrav/grav-plugin-admin/issues/2125) - * Fixed audit vulnerabilities in module dependencies and house cleanup [#2096](https://github.com/getgrav/grav-plugin-admin/issues/2096) - * Fixed issue preventing Drag & Drop of media files while in Expert Mode [#1927](https://github.com/getgrav/grav-plugin-admin/issues/1927) - * Fixed broken link colors in `preset.css` which was causing issues with tabs and dropdowns - * Fixed permissions for page related tasks and actions - * Fixed permission check for configuration save [#2130](https://github.com/getgrav/grav-plugin-admin/issues/2130) - * Fixed missing/wrong page categories and tags when multi-language support is enabled [#2107](https://github.com/getgrav/grav-plugin-admin/issues/2107) - -# v1.10.12 -## 04/15/2021 - -1. [](#bugfix) - * Regression: Fixed broken plugin/theme installer in admin - * Fixed error reporting for AJAX tasks if user has no permissions - * Fixed missing slash in password reset URL [#2119](https://github.com/getgrav/grav-plugin-admin/issues/2119) - -# v1.10.11 -## 04/13/2021 - -1. [](#bugfix) - * **IMPORTANT** Fixed security vulnerability that allows installation of plugins with minimal admin privileges [GHSA-wg37-cf5x-55hq](https://github.com/getgrav/grav-plugin-admin/security/advisories/GHSA-wg37-cf5x-55hq) - * Fixed `You have been logged out` message when entering to 2FA authentication due to `/admin/task:getNotifications` AJAX call - * Fixed broken 2FA login when site is not configured to use Flex Users [#2109](https://github.com/getgrav/grav-plugin-admin/issues/2109) - * Fixed error message when user clicks logout link after the session has been expired - -# v1.10.10 -## 04/07/2021 - -1. [](#bugfix) - * Fixed missing `admin-preset.css` in multisite environments - * Regression: Fixed broken 2FA form [#2109](https://github.com/getgrav/grav-plugin-admin/issues/2109) - -# v1.10.9 -## 04/06/2021 - -1. [](#new) - * Requires **Grav 1.7.10** -1. [](#improved) - * Better isolate admin to prevent session related vulnerabilities - * Removed support for custom login redirects for improved security - * Shorten forgot password link lifetime from 7 days to 1 hour - * Updated with latest language translations from Crowdin.com -1. [](#bugfix) - * Fixed issue where Adding a new page and canceling from within Editing would alter the Parent location of the edited page [#2067](https://github.com/getgrav/grav-plugin-admin/issues/2067) - * Fixed and enhanced Range field to be Lists compatible [#2062](https://github.com/getgrav/grav-plugin-admin/issues/2062) - * Fixed ERR_TOO_MANY_REDIRECTS with HTTPS = 'On' [#2100](https://github.com/getgrav/grav-plugin-admin/issues/2100) - * Prevent expert editing mode from anyone else than super users [#2094](https://github.com/getgrav/grav-plugin-admin/issues/2094) - * Fixed login related pages being accessible from admin when user has logged in - * Fixed admin user creation and password reset allowing unsafe passwords - * Fixed missing validation when registering the first admin user - * Fixed reset password email not to have session specific token in it - * Fixed admin controller running before setting `$grav['page']` - -# v1.10.8 -## 03/19/2021 - -1. [](#improved) - * Include alt text and title for images added to the editor [#2098](https://github.com/getgrav/grav-plugin-admin/issues/2098) -1. [](#bugfix) - * Fixed issue replacing `wildcard` field names in flex collections [#2092](https://github.com/getgrav/grav-plugin-admin/pull/2092) - * Fixed legacy Pages having old `modular` reference instead of `module` [#2093](https://github.com/getgrav/grav-plugin-admin/issues/2093) - * Fixed issue where Add New modal would close if selecting an item outside of the modal window. It is now necessary go through the Cancel button and clicking the overlay won't trigger the closing of the modal [#2089](https://github.com/getgrav/grav-plugin-admin/issues/2089), [#2065](https://github.com/getgrav/grav-plugin-admin/issues/2065) - -# v1.10.7 -## 03/17/2021 - -1. [](#improved) - * Force height of Flex pages admin to fit available space - * Updated languages from Crowdin.com - * Better field type definitions for file, pagemedia, filepicker and pagemediafield -1. [](#bugfix) - * Fixed error when checking missing log file [#2088](https://github.com/getgrav/grav-plugin-admin/issues/2088) - -# v1.10.6 -## 02/23/2021 - -1. [](#new) - * Vastly improved support for RTL languages [#2078](https://github.com/getgrav/grav-plugin-admin/pull/2078) -1. [](#improved) - * Flex pages admin better uses available space [#2075](https://github.com/getgrav/grav/issues/2075) -1. [](#bugfix) - * Regression: Fixed enabling/disabling plugin or theme corrupting configuration - * Fixed unnecessary closing bracket causing JS error [#2079](https://github.com/getgrav/grav-plugin-admin/issues/2079) - * Fixed wrong language in Admin Tools [#2077](https://github.com/getgrav/grav-plugin-admin/issues/2077) - -# v1.10.5 -## 02/18/2021 - -1. [](#bugfix) - * Regression: Fixed fatal error in admin if POST request has `data` in it [#2074](https://github.com/getgrav/grav-plugin-admin/issues/2074) - * Fixed Admin creating empty `user/config/info.yaml` file (the file can be safely removed, it is not in use) - * Fixed ACL for users with mixed case usernames [#2073](https://github.com/getgrav/grav-plugin-admin/issues/2073) - -# v1.10.4 -## 02/17/2021 - -1. [](#new) - * Added support to include new page creation modals in other pages by using `form_action` twig variable [#2024](https://github.com/getgrav/grav-plugin-admin/pull/2024) - * Updated all languages from [Crowdin](https://crowdin.com/project/grav-admin) - Please update any translations here -1. [](#improved) - * Removed `noscript` template, because 2021... - * List field: added new `placement` property to decide wether to add new items at the top, bottom or based on the *position* of the clicked button [#2055](https://github.com/getgrav/grav-plugin-admin/pull/2055) - * Ensure admin default CSS styles load **first**, and presets loads **last** - * Tweaked handling of uploaded files [#1429](https://github.com/getgrav/grav-plugin-admin/issues/1429) - * Provide media object and filename in `onAdminAfterDelMedia` event [#1905](https://github.com/getgrav/grav-plugin-admin/pull/1905) -1. [](#bugfix) - * Fixed case-sensitive `accept` in `filepicker` field - * Fixed HTML Entities in titles [#2028](https://github.com/getgrav/grav-plugin-admin/issues/2028) - * Fixed deleting list field options completely, didn't save changes [#2056](https://github.com/getgrav/grav-plugin-admin/issues/2056) - * Fixed `onAdminAfterAddMedia` and `onAdminAfterDelMedia` events always pointing to the home page - * Fixed ACL for Configuration tabs [#771](https://github.com/getgrav/grav-plugin-admin/issues/771) - * Fixed changelog button showing up in Info page even if user cannot access it - * Fixed toggleable checkboxes being unchecked in fieldset columns [#2063](https://github.com/getgrav/grav-plugin-admin/issues/2063) - * Fixed issue with max backups of zero [#2070](https://github.com/getgrav/grav-plugin-admin/issues/2070) - -# v1.10.3 -## 02/01/2021 - -1. [](#new) - * Requires **Grav 1.7.4** (SemVer library moved to Grav) - * Added back special fonts (including Gantry) -2. [](#bugfix) - * Fixed field type `range` not taking into account legitimate `0` values - * Fixed `Call to a member function trackHit() on null` [#2049](https://github.com/getgrav/grav-plugin-admin/issues/2049) - -# v1.10.2 -## 01/21/2021 - -2. [](#bugfix) - * Fixed admin style compilation failing to save CSS if assets folder does not exist - -# v1.10.1 -## 01/20/2021 - -1. [](#improved) - * Added `watch.sh` for compiling SCSS with native sass compiler -2. [](#bugfix) - * Fixed issue with overlapping sidebar when using fullscreen editor [#2022](https://github.com/getgrav/grav-plugin-admin/issues/2022) - -# v1.10.0 -## 01/19/2021 - -1. [](#new) - * Requires **Grav 1.7 and PHP 7.3.6** - * Read about this release in the [Grav 1.7 Released](https://getgrav.org/blog/grav-1.7-released) blog post - * Read the full list of changes in the [Changelog on GitHub](https://github.com/getgrav/grav-plugin-admin/blob/1.10.0/CHANGELOG.md) - * Please read [Grav 1.7 Upgrade Guide](https://learn.getgrav.org/17/advanced/grav-development/grav-17-upgrade-guide) before upgrading! -1. [](#improved) - * Various notifications improvements -1. [](#bugfix) - * Fixed missed highlight on the selected page in Parents field - * Fixed notifications that would not be remembered as hidden - * Fixed taxonomy field not listing existing options in Flex Pages - * Fixed taxonomy field not working outside pages - * Fixed fatal error when moving a page using the old implementation [#2019](https://github.com/getgrav/grav-plugin-admin/issues/2019) - * Fixed evaluating default value in `hidden` field (thanks @NicoHood) - -# v1.10.0-rc.20 -## 12/14/2020 - -1. [](#improved) - * Cookies now explicitly set `SameSite` to `Lax` unless otherwise specified [#1998](https://github.com/getgrav/grav-plugin-admin/issues/1998) - * Exposed **Cookies** class (`Grav.default.Utils.Cookies`) for developers that need it in Admin. -1. [](#bugfix) - * Fixed Plugins references in Themes details page. - * Fixed issue preventing purchase of Themes within Admin and redirecting instead. - * Regression: Values inside Fieldset do not display [#1995](https://github.com/getgrav/grav-plugin-admin/issues/1995) - -# v1.10.0-rc.19 -## 12/02/2020 - -1. [](#improved) - * Just keeping sync with Grav rc.19 - -# v1.10.0-rc.18 -## 12/02/2020 - -1. [](#new) - * Retired "Secure Delete" and "Warn on page delete". You are now always warned and asked to confirm a deletion. -1. [](#improved) - * Auto-link a plugin/theme license in details if it starts with `http` - * Allow to fallback to `docs:` instead of `readme:` - * Forward a `sid` to GPM when downloading a premium package - * Better support for array field key/value when either key or value is stored empty [#1972](https://github.com/getgrav/grav-plugin-admin/issues/1972) - * Remember the open state of the sidebar [#1973](https://github.com/getgrav/grav-plugin-admin/issues/1973) - * Upgraded node dependencies to latest version. Improved speed of JS compilation. - * Added modal to confirm updating Grav as well as cool down counter before enabling Update button [#1257](https://github.com/getgrav/grav-plugin-admin/issues/1257) - * Better handling of offline/intranet mode when the repository index is missing. Faster admin. [#1916](https://github.com/getgrav/grav-plugin-admin/issues/1916) - * Statistics is now Page View Statistics [#1885](https://github.com/getgrav/grav-plugin-admin/issues/1885) - * It is now possible to use regex as values for "Hide page types in Admin" and "Hide modular page types in Admin" settings [#1828](https://github.com/getgrav/grav-plugin-admin/issues/1828) - * Default to `disabled` state for all cron-jobs -1. [](#bugfix) - * Fixed Safari issue with new ACL picker field [#1955](https://github.com/getgrav/grav-plugin-admin/issues/1955) - * Stop propagation of ACL add button in ACL picker [flex-objects#83](https://github.com/trilbymedia/grav-plugin-flex-objects/issues/83) - * Fixed missing special groups `authors` and `defaults` for pages - * Fixed Page Move action and selection highlight in Parents selector modal [flex-objects#80](https://github.com/trilbymedia/grav-plugin-flex-objects/issues/80) - * Fixed folder auto-naming in Add Module [#1937](https://github.com/getgrav/grav-plugin-admin/issues/1937) - * Fixed remodal issue triggering close when selecting a dropdown item ending outside of scope [#1682](https://github.com/getgrav/grav-plugin-admin/issues/1682) - * Reworked how collapsed lists work so the tooltip is not cut off [#1928](https://github.com/getgrav/grav-plugin-admin/issues/1928) - * Fixed KeepAlive issue where too large of a session value would fire the keep alive immediately [#1860](https://github.com/getgrav/grav-plugin-admin/issues/1860) - * Fixed stringable objects breaking the inputs - * Fixed filepicker, pagemediaselect fields with `multiple: true` and `array: true` [#1580](https://github.com/getgrav/grav-plugin-admin/issues/1580) - -# v1.10.0-rc.17 -## 10/07/2020 - -1. [](#new) - * Support premium themes -1. [](#improved) - * Improved some error messages for better readability - * Strip tags from browser title -1. [](#bugfix) - * More multi-site routing fixes - * Fixed issue that would force a page reload when failing to install/update a plugin or theme. - * Fixed proxy/browser caching issues in admin pages - -# v1.10.0-rc.16 -## 09/01/2020 - -1. [](#improved) - * Made all the `onAdmin*` CRUD events to pass `object` (and backwards compatible `page`) to make them easier to use - * Updated vendor libraries including `SCSSPHP` to v1.2 -1. [](#bugfix) - * Fixed issue with File field being used in Theme/Plugins - * Fixed bad redirection after successful admin login in subdirectory multisite [#1487](https://github.com/getgrav/grav-plugin-admin/issues/1487) - -# v1.10.0-rc.15 -## 07/22/2020 - -1. [](#bugfix) - * Disabled the EXIF library for Dropzone for fixing the orientation as it was getting applied twice [#1923](https://github.com/getgrav/grav-plugin-admin/issues/1923) - * Forked Dropzone fo fix issue with Resize + Exif orientation [#1923](https://github.com/getgrav/grav-plugin-admin/issues/1923) - * Fixed URI encode for the preview of images names - -# v1.10.0-rc.14 -## 07/09/2020 - -1. [](#improved) - * Completely removed old Google font support for upgrade compatibility -1. [](#bugfix) - * Fixed bad `use` reference to `UserObject` - -# v1.10.0-rc.13 -## 07/01/2020 - -1. [](#improved) - * Improved color picker field - * Trim login route for safety - * Composer update to grab latest vendor libs - -# v1.10.0-rc.12 -## 06/08/2020 - -1. [](#new) - * Added ability to set a preferred markdown editor in user profile - * Added new `onAdminListContentEditors` event to add a custom editor to the list of available -1. [](#bugfix) - * Fixed issue deleting file from a plugin's configuration - * Use `Pages::find()` instead of `Pages::dispatch()` as we do not want to redirect out of admin - * Fixed broken `parent` field when using the old pages - * Fixed broken `file` field preview when using streams in the path - -# v1.10.0-rc.11 -## 05/14/2020 - -1. [](#new) - * Major enhancements to "White Label" functionality including ability to export/import presets - * New horizontal scroller for theme presets - * Codemirror Fontsize / Preset / Font preference options -1. [](#improved) - * Fixed lots of styling issues related to "White Label" presets - * Changed out "One Light" theme for new "Firewatch Light" theme - * New scrolling system based on `SimpleBar` + native CSS scrollbar styling - -# v1.10.0-rc.10 -## 04/30/2020 - -1. [](#new) - * Addd new `taskConvertUrls` method for use with 3rd party editors - -# v1.10.0-rc.9 -## 04/27/2020 - -1. [](#new) - * Added new "White Label" functionality to customize admin colors + logos - * Added badge count for children in the Parents field -1. [](#improved) - * Added markdown support to `text` in `section` field -1. [](#bugfix) - * Prevent loading Pages in Parents field if they don't have children - * Fixed custom folder in `mediapicker` field not working with streams - * Fixed language redirect adding extra language prefix in Flex - * Fixed `Invalid input in "Parent"` when saving page in raw mode [#1869](https://github.com/getgrav/grav-plugin-admin/issues/1869) - -# v1.10.0-rc.8 -## 03/19/2020 - -1. [](#new) - * Added `has-children` flag in parent field data response - * Added `RESET` en lang string -1. [](#bugfix) - * Fixed parent field not working with regular pages - -# v1.10.0-rc.7 -## 03/05/2020 - -1. [](#new) - * Enable admin cache by default (for existing sites, check `Plugins > Admin Panel > Enable Admin Caching`) -1. [](#improved) - * Removed old `scss.sh` and `watch.sh` scripts, use `gulp watch-css` - * Added keysOnly parameter to `AdminPlugin::pagesTypes()` and `AdminPlugin::pagesModularTypes()` methods - * Added ignore parameter to `Admin::types()` and `Admin::modularTypes()` methods - * Improved configuration fields for hiding page types in Admin -1. [](#bugfix) - * Fixed minor UI padding in Flex pages [#1825](https://github.com/getgrav/grav-plugin-admin/issues/1825) - * Fixed `column` and `section` fields loosing user entered value when form submit fails - * Fixed `order` field not working with a new Flex Page - -# v1.10.0-rc.6 -## 02/11/2020 - -1. [](#new) - * Pass phpstan level 1 tests - * Updated semver library to v1.5 - * Require flex-objects plugin -1. [](#improved) - * Added some debugging messages (turned off by default) - -# v1.10.0-rc.5 -## 02/03/2020 - -1. [](#new) - * No changes, just keeping things in sync with Grav RC version - -# v1.10.0-rc.4 -## 02/03/2020 - -1. [](#new) - * Added message to dashboard to install Flex Objects plugin if it is missing - * Updated `permissions` field to use new `$grav['permissions']` - * DEPRECATED `onAdminRegisterPermissions` event, use `PermissionsRegisterEvent::class` event instead - * DEPRECATED `Admin::setPermissions()` and `Admin::addPermissions()`, use `PermissionsRegisterEvent::class` event instead - * DEPRECATED `Admin::getPermissions()`, use `$grav['permissions']->getInstances()` instead -1. [](#improved) - * Added `field.show_label` and `field.label` display logic from frontend forms -1. [](#bugfix) - * Fixed user profile when using `Flex Users` only in admin - * Fixed saving data with empty field, default value (from config, plugin, theme) was used instead - * Fixed JS bug is using empty Grav URI param key - * Fixed bug in toggleable field being disabled with empty value (`''` `0`, `false`, `[]`...) - * Fixed `admin_route()` twig function to work properly with Grav 1.7.0-rc.4, which fixes `Route` base - * Fixed misleading 'Show sensitive data' configuration option wording [#1818](https://github.com/getgrav/grav-plugin-admin/issues/1818) - -# v1.10.0-rc.3 -## 01/02/2020 - -1. [](#new) - * Added ability to display **Changelogs** for `Grav`, `Plugins` and `Themes` - * Added raw root page support for `Flex Pages` - -# v1.10.0-rc.2 -## 12/04/2019 - -1. [](#new) - * Added support for hiding parts of admin by `Deny` permissions (`Flex Users` only) - * Optimized `parent` field for Flex Pages -1. [](#improved) - * Improved `permissions` field to add support for displaying calculated permissions - * Grav 1.7: Updated deprecated `$page->modular()` method calls to `$page->isModule()` - * Output the current process user name in Scheduler instructions - * Translations: rename MODULAR to MODULE everywhere -1. [](#bugfix) - * Fixed `permissions` field with nested permissions - * Fixed Save Shortcut (CTRL + S / CMD + S) not working with new Flex Pages [#1787](https://github.com/getgrav/grav-plugin-admin/issues/1787) - -# v1.10.0-rc.1 -## 11/06/2019 - -1. [](#new) - * Added a new `onAdminLogFiles()` event for 3rd party plugins to register log files for log viewer [#1765](https://github.com/getgrav/grav-plugin-admin/issues/1765) -1. [](#improved) - * Improved delete button UI [#1769](https://github.com/getgrav/grav-plugin-admin/issues/1769) - * Ability to configure display of 3rd party dashboard widgets [#1766](https://github.com/getgrav/grav-plugin-admin/issues/1766) -1. [](#bugfix) - * Fixed administrator user creation when `Flex Users` is enabled - * Fixed minor button alignment in FF [#1760](https://github.com/getgrav/grav-plugin-admin/issues/1760) - -# v1.10.0-beta.10 -## 10/03/2019 - -1. [](#bugfix) - * Regression: Fixed language assignments for the pages without set language - -# v1.10.0-beta.9 -## 09/26/2019 - -1. [](#bugfix) - * Make pages field to work with Flex Pages - -# v1.10.0-beta.8 -## 09/19/2019 - -1. [](#new) - * Add ability to Sanitize SVGs on file upload - * Add ability to Sanitize SVGs in Page media -1. [](#improved) - * YAML linter report now supports multi-language - * Better colors/placement of toolbar buttons in page edit view -1. [](#bugfix) - * Fixed missing language for AJAX requests - * Fixed redirect with absolute language URL - * Fixed issue with user avatar reference not being deleted when image removed - -# v1.10.0-beta.7 -## 08/30/2019 - -1. [](#bugfix) - * Fixed regression: Do not require Flex Objects plugin [grav#2653](https://github.com/getgrav/grav/issues/2653) - -# v1.10.0-beta.6 -## 08/29/2019 - -1. [](#improved) - * Optimized admin for speed (only load frontend pages on demand) - * Updated navigation menu to be fully controlled and overrideable by `onAdminMenu` event - * Lots of Flex Page speed improvements - -# v1.10.0-beta.5 -## 08/11/2019 - -1. [](#new) - * Added `data()` twig function to create data object from an array -1. [](#improved) - * Better support for `array` field into `list` field - * Made RAW blueprints (expert mode) to work properly with Flex Form - * Better support for `clockwork` logs -1. [](#bugfix) - * Fixed issue with nested `list` fields both utilizing the custom `key` functionality - * Regression: Page Preview not working, bad url [#1715](https://github.com/getgrav/grav-plugin-admin/issues/1715) - * Fixed '+New Folder' to work with new parent picker - * Fixed missing XSS check field when editing modular page as raw - * Fixed minor CSS layout issue [#1717](https://github.com/getgrav/grav-plugin-admin/issues/1717) - -# v1.10.0-beta.4 -## 07/01/2019 - -1. [](#new) - * Added `Admin::redirect()` method to allow redirects to be used outside of controllers - * Added `$admin->adminRoute()` method and `admin_route()` twig function to create language aware admin page links - * Renamed `Admin::route()` to `Admin::getCurrentRoute()` and deprecated the old call -1. [](#improved) - * Much improved multi-language support for pages - * Admin redirects should now work better with multiple languages enabled -1. [](#bugfix) - * Fixed default language being renamed to `page.en.md` (English) instead of keeping existing `page.md` filename - * Fixed possibility to override already existing translation by `Save As Language` - * Fixed missing default translation if page used plain `.md` file extension without language code - * Fixed wrong translation showing up as page fallback language - * Integrated Admin 1.9.8 bug fixes - -# v1.10.0-beta.3 -## 06/24/2019 - -1. [](#improved) - * Smarter handling of symlinks in parent field -1. [](#bugfix) - * Fixed issue with windows paths in `parent` field [#1699](https://github.com/getgrav/grav-plugin-admin/issues/1699) - -# v1.10.0-beta.2 -## 06/21/2019 - -1. [](#improved) - * Moved Remodal in-house and added support for stackable modals [#1698](https://github.com/getgrav/grav-plugin-admin/issues/1698), [#1699](https://github.com/getgrav/grav-plugin-admin/issues/1699) -1. [](#bugfix) - * Fixed missing check for maximum allowed files in `files` field - -# v1.10.0-beta.1 -## 06/14/2019 - -1. [](#new) - * New Parent/Move field using Ajax for better performance - * Improvements to cache clearing when admin cache is enabled - * Require Grav v1.7 - * Use PSR-4 for plugin classes - * Added support for Twig 2.11 (compatible with Twig 1.40+) -1. [](#improved) - * Various admin performance improvements -1. [](#bugfix) - * Fixed admin caching issues - -# v1.9.19 -## 12/14/2020 - -1. [](#bugfix) - * Fixed `pages` field escaping issues, needs Grav update, too [#1990](https://github.com/getgrav/grav-plugin-admin/issues/1990) - * Fixed Plugins references in Themes details page. - * Fixed issue preventing purchase of Themes within Admin and redirecting instead. - * Fixed Page Picker not passing admin token - -# v1.9.18 -## 12/02/2020 - -1. [](#new) - * Never allow Admin pages to be rendered in ``, `'); - return true; - } - - return false; - } - - /** - * Generate HTML from item URL - * - * @access public - * @param Item $item - * @return bool - */ - public function generateHtmlFromUrl(Item $item) - { - if (preg_match('/youtube\.com\/watch\?v=(.*)/', $item->getUrl(), $matches)) { - $item->setContent(''); - return true; - } - - return false; - } -} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Logging/Logger.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Logging/Logger.php deleted file mode 100644 index caec463..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Logging/Logger.php +++ /dev/null @@ -1,114 +0,0 @@ -format('Y-m-d H:i:s').'] '.$message; - } - } - - /** - * Get all logged messages. - * - * @static - * - * @return array - */ - public static function getMessages() - { - return self::$messages; - } - - /** - * Remove all logged messages. - * - * @static - */ - public static function deleteMessages() - { - self::$messages = array(); - } - - /** - * Set a different timezone. - * - * @static - * - * @see http://php.net/manual/en/timezones.php - * - * @param string $timezone Timezone - */ - public static function setTimeZone($timezone) - { - self::$timezone = $timezone ?: self::$timezone; - } - - /** - * Get all messages serialized into a string. - * - * @static - * - * @return string - */ - public static function toString() - { - return implode(PHP_EOL, self::$messages).PHP_EOL; - } -} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Parser/Atom.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Parser/Atom.php deleted file mode 100644 index 0496869..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Parser/Atom.php +++ /dev/null @@ -1,395 +0,0 @@ - 'http://www.w3.org/2005/Atom', - ); - - /** - * Get the path to the items XML tree. - * - * @param SimpleXMLElement $xml Feed xml - * @return SimpleXMLElement[] - */ - public function getItemsTree(SimpleXMLElement $xml) - { - return XmlParser::getXPathResult($xml, 'atom:entry', $this->namespaces) - ?: XmlParser::getXPathResult($xml, 'entry'); - } - - /** - * Find the feed url. - * - * @param SimpleXMLElement $xml Feed xml - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findFeedUrl(SimpleXMLElement $xml, Feed $feed) - { - $feed->setFeedUrl($this->getUrl($xml, 'self')); - } - - /** - * Find the site url. - * - * @param SimpleXMLElement $xml Feed xml - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findSiteUrl(SimpleXMLElement $xml, Feed $feed) - { - $feed->setSiteUrl($this->getUrl($xml, 'alternate', true)); - } - - /** - * Find the feed description. - * - * @param SimpleXMLElement $xml Feed xml - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findFeedDescription(SimpleXMLElement $xml, Feed $feed) - { - $description = XmlParser::getXPathResult($xml, 'atom:subtitle', $this->namespaces) - ?: XmlParser::getXPathResult($xml, 'subtitle'); - - $feed->setDescription(XmlParser::getValue($description)); - } - - /** - * Find the feed logo url. - * - * @param SimpleXMLElement $xml Feed xml - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findFeedLogo(SimpleXMLElement $xml, Feed $feed) - { - $logo = XmlParser::getXPathResult($xml, 'atom:logo', $this->namespaces) - ?: XmlParser::getXPathResult($xml, 'logo'); - - $feed->setLogo(XmlParser::getValue($logo)); - } - - /** - * Find the feed icon. - * - * @param SimpleXMLElement $xml Feed xml - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findFeedIcon(SimpleXMLElement $xml, Feed $feed) - { - $icon = XmlParser::getXPathResult($xml, 'atom:icon', $this->namespaces) - ?: XmlParser::getXPathResult($xml, 'icon'); - - $feed->setIcon(XmlParser::getValue($icon)); - } - - /** - * Find the feed title. - * - * @param SimpleXMLElement $xml Feed xml - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findFeedTitle(SimpleXMLElement $xml, Feed $feed) - { - $title = XmlParser::getXPathResult($xml, 'atom:title', $this->namespaces) - ?: XmlParser::getXPathResult($xml, 'title'); - - $feed->setTitle(Filter::stripWhiteSpace(XmlParser::getValue($title)) ?: $feed->getSiteUrl()); - } - - /** - * Find the feed language. - * - * @param SimpleXMLElement $xml Feed xml - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findFeedLanguage(SimpleXMLElement $xml, Feed $feed) - { - $language = XmlParser::getXPathResult($xml, '*[not(self::atom:entry)]/@xml:lang', $this->namespaces) - ?: XmlParser::getXPathResult($xml, '@xml:lang'); - - $feed->setLanguage(XmlParser::getValue($language)); - } - - /** - * Find the feed id. - * - * @param SimpleXMLElement $xml Feed xml - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findFeedId(SimpleXMLElement $xml, Feed $feed) - { - $id = XmlParser::getXPathResult($xml, 'atom:id', $this->namespaces) - ?: XmlParser::getXPathResult($xml, 'id'); - - $feed->setId(XmlParser::getValue($id)); - } - - /** - * Find the feed date. - * - * @param SimpleXMLElement $xml Feed xml - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findFeedDate(SimpleXMLElement $xml, Feed $feed) - { - $updated = XmlParser::getXPathResult($xml, 'atom:updated', $this->namespaces) - ?: XmlParser::getXPathResult($xml, 'updated'); - - $feed->setDate($this->getDateParser()->getDateTime(XmlParser::getValue($updated))); - } - - /** - * Find the item published date. - * - * @param SimpleXMLElement $entry Feed item - * @param Item $item Item object - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findItemPublishedDate(SimpleXMLElement $entry, Item $item, Feed $feed) - { - $date = XmlParser::getXPathResult($entry, 'atom:published', $this->namespaces) - ?: XmlParser::getXPathResult($entry, 'published'); - - $item->setPublishedDate(!empty($date) ? $this->getDateParser()->getDateTime((string) current($date)) : null); - } - - /** - * Find the item updated date. - * - * @param SimpleXMLElement $entry Feed item - * @param Item $item Item object - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findItemUpdatedDate(SimpleXMLElement $entry, Item $item, Feed $feed) - { - $date = XmlParser::getXPathResult($entry, 'atom:updated', $this->namespaces) - ?: XmlParser::getXPathResult($entry, 'updated'); - - $item->setUpdatedDate(!empty($date) ? $this->getDateParser()->getDateTime((string) current($date)) : null); - } - - /** - * Find the item title. - * - * @param SimpleXMLElement $entry Feed item - * @param Item $item Item object - */ - public function findItemTitle(SimpleXMLElement $entry, Item $item) - { - $title = XmlParser::getXPathResult($entry, 'atom:title', $this->namespaces) - ?: XmlParser::getXPathResult($entry, 'title'); - - $item->setTitle(Filter::stripWhiteSpace(XmlParser::getValue($title)) ?: $item->getUrl()); - } - - /** - * Find the item author. - * - * @param SimpleXMLElement $xml Feed - * @param SimpleXMLElement $entry Feed item - * @param \PicoFeed\Parser\Item $item Item object - */ - public function findItemAuthor(SimpleXMLElement $xml, SimpleXMLElement $entry, Item $item) - { - $author = XmlParser::getXPathResult($entry, 'atom:author/atom:name', $this->namespaces) - ?: XmlParser::getXPathResult($entry, 'author/name') - ?: XmlParser::getXPathResult($xml, 'atom:author/atom:name', $this->namespaces) - ?: XmlParser::getXPathResult($xml, 'author/name'); - - $item->setAuthor(XmlParser::getValue($author)); - } - - /** - * Find the item author URL. - * - * @param SimpleXMLElement $xml Feed - * @param SimpleXMLElement $entry Feed item - * @param \PicoFeed\Parser\Item $item Item object - */ - public function findItemAuthorUrl(SimpleXMLElement $xml, SimpleXMLElement $entry, Item $item) - { - $authorUrl = XmlParser::getXPathResult($entry, 'atom:author/atom:uri', $this->namespaces) - ?: XmlParser::getXPathResult($entry, 'author/uri') - ?: XmlParser::getXPathResult($xml, 'atom:author/atom:uri', $this->namespaces) - ?: XmlParser::getXPathResult($xml, 'author/uri'); - - $item->setAuthorUrl(XmlParser::getValue($authorUrl)); - } - - /** - * Find the item content. - * - * @param SimpleXMLElement $entry Feed item - * @param \PicoFeed\Parser\Item $item Item object - */ - public function findItemContent(SimpleXMLElement $entry, Item $item) - { - $item->setContent($this->getContent($entry)); - } - - /** - * Find the item URL. - * - * @param SimpleXMLElement $entry Feed item - * @param \PicoFeed\Parser\Item $item Item object - */ - public function findItemUrl(SimpleXMLElement $entry, Item $item) - { - $item->setUrl($this->getUrl($entry, 'alternate', true)); - } - - /** - * Genereate the item id. - * - * @param SimpleXMLElement $entry Feed item - * @param \PicoFeed\Parser\Item $item Item object - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findItemId(SimpleXMLElement $entry, Item $item, Feed $feed) - { - $id = XmlParser::getXPathResult($entry, 'atom:id', $this->namespaces) - ?: XmlParser::getXPathResult($entry, 'id'); - - if (!empty($id)) { - $item->setId($this->generateId(XmlParser::getValue($id))); - } else { - $item->setId($this->generateId( - $item->getTitle(), $item->getUrl(), $item->getContent() - )); - } - } - - /** - * Find the item enclosure. - * - * @param SimpleXMLElement $entry Feed item - * @param \PicoFeed\Parser\Item $item Item object - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findItemEnclosure(SimpleXMLElement $entry, Item $item, Feed $feed) - { - $enclosure = $this->findLink($entry, 'enclosure'); - - if ($enclosure) { - $item->setEnclosureUrl(Url::resolve((string) $enclosure['href'], $feed->getSiteUrl())); - $item->setEnclosureType((string) $enclosure['type']); - } - } - - /** - * Find the item language. - * - * @param SimpleXMLElement $entry Feed item - * @param \PicoFeed\Parser\Item $item Item object - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findItemLanguage(SimpleXMLElement $entry, Item $item, Feed $feed) - { - $language = XmlParser::getXPathResult($entry, './/@xml:lang'); - $item->setLanguage(XmlParser::getValue($language) ?: $feed->getLanguage()); - } - - /** - * Find the item categories. - * - * @param SimpleXMLElement $entry Feed item - * @param Item $item Item object - * @param Feed $feed Feed object - */ - public function findItemCategories(SimpleXMLElement $entry, Item $item, Feed $feed) - { - $categories = XmlParser::getXPathResult($entry, 'atom:category/@term', $this->namespaces) - ?: XmlParser::getXPathResult($entry, 'category/@term'); - $item->setCategoriesFromXml($categories); - } - - /** - * Get the URL from a link tag. - * - * @param SimpleXMLElement $xml XML tag - * @param string $rel Link relationship: alternate, enclosure, related, self, via - * @return string - */ - private function getUrl(SimpleXMLElement $xml, $rel, $fallback = false) - { - $link = $this->findLink($xml, $rel); - - if ($link) { - return (string) $link['href']; - } - - if ($fallback) { - $link = $this->findLink($xml, ''); - return $link ? (string) $link['href'] : ''; - } - - return ''; - } - - /** - * Get a link tag that match a relationship. - * - * @param SimpleXMLElement $xml XML tag - * @param string $rel Link relationship: alternate, enclosure, related, self, via - * @return SimpleXMLElement|null - */ - private function findLink(SimpleXMLElement $xml, $rel) - { - $links = XmlParser::getXPathResult($xml, 'atom:link', $this->namespaces) - ?: XmlParser::getXPathResult($xml, 'link'); - - foreach ($links as $link) { - if ($rel === (string) $link['rel']) { - return $link; - } - } - - return null; - } - - /** - * Get the entry content. - * - * @param SimpleXMLElement $entry XML Entry - * @return string - */ - private function getContent(SimpleXMLElement $entry) - { - $content = current( - XmlParser::getXPathResult($entry, 'atom:content', $this->namespaces) - ?: XmlParser::getXPathResult($entry, 'content') - ); - - if (!empty($content) && count($content->children())) { - $xml_string = ''; - - foreach ($content->children() as $child) { - $xml_string .= $child->asXML(); - } - - return $xml_string; - } elseif (trim((string) $content) !== '') { - return (string) $content; - } - - $summary = XmlParser::getXPathResult($entry, 'atom:summary', $this->namespaces) - ?: XmlParser::getXPathResult($entry, 'summary'); - - return (string) current($summary); - } -} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Parser/DateParser.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Parser/DateParser.php deleted file mode 100644 index b7a015d..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Parser/DateParser.php +++ /dev/null @@ -1,128 +0,0 @@ - length ]. - * - * @var array - */ - public $formats = array( - DATE_ATOM => null, - DATE_RSS => null, - DATE_COOKIE => null, - DATE_ISO8601 => null, - DATE_RFC822 => null, - DATE_RFC850 => null, - DATE_RFC1036 => null, - DATE_RFC1123 => null, - DATE_RFC2822 => null, - DATE_RFC3339 => null, - 'l, d M Y H:i:s' => null, - 'D, d M Y H:i:s' => 25, - 'D, d M Y h:i:s' => 25, - 'D M d Y H:i:s' => 24, - 'j M Y H:i:s' => 20, - 'Y-m-d H:i:s' => 19, - 'Y-m-d\TH:i:s' => 19, - 'd/m/Y H:i:s' => 19, - 'D, d M Y' => 16, - 'Y-m-d' => 10, - 'd-m-Y' => 10, - 'm-d-Y' => 10, - 'd.m.Y' => 10, - 'm.d.Y' => 10, - 'd/m/Y' => 10, - 'm/d/Y' => 10, - ); - - /** - * Try to parse all date format for broken feeds. - * - * @param string $value Original date format - * - * @return DateTime - */ - public function getDateTime($value) - { - $value = trim($value); - - foreach ($this->formats as $format => $length) { - $truncated_value = $value; - if ($length !== null) { - $truncated_value = substr($truncated_value, 0, $length); - } - - $date = $this->getValidDate($format, $truncated_value); - if ($date !== false) { - return $date; - } - } - - return $this->getCurrentDateTime(); - } - - /** - * Get a valid date from a given format. - * - * @param string $format Date format - * @param string $value Original date value - * - * @return DateTime|bool - */ - public function getValidDate($format, $value) - { - $date = DateTime::createFromFormat($format, $value, $this->getTimeZone()); - - if ($date !== false) { - $errors = DateTime::getLastErrors(); - - if ($errors === false || ($errors['error_count'] === 0 && $errors['warning_count'] === 0)) { - return $date; - } - } - - return false; - } - - /** - * Get the current datetime. - * - * @return DateTime - */ - public function getCurrentDateTime() - { - return new DateTime('now', $this->getTimeZone()); - } - - /** - * Get DateTimeZone instance - * - * @access public - * @return DateTimeZone - */ - public function getTimeZone() - { - return new DateTimeZone($this->config->getTimezone() ?: $this->timezone); - } -} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Parser/Feed.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Parser/Feed.php deleted file mode 100644 index a56e71c..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Parser/Feed.php +++ /dev/null @@ -1,315 +0,0 @@ -$property.PHP_EOL; - } - - $output .= 'Feed::date = '.$this->date->format(DATE_RFC822).PHP_EOL; - $output .= 'Feed::isRTL() = '.($this->isRTL() ? 'true' : 'false').PHP_EOL; - $output .= 'Feed::items = '.count($this->items).' items'.PHP_EOL; - - foreach ($this->items as $item) { - $output .= '----'.PHP_EOL; - $output .= $item; - } - - return $output; - } - - /** - * Get title. - */ - public function getTitle() - { - return $this->title; - } - - /** - * Get description. - */ - public function getDescription() - { - return $this->description; - } - - /** - * Get the logo url. - */ - public function getLogo() - { - return $this->logo; - } - - /** - * Get the icon url. - */ - public function getIcon() - { - return $this->icon; - } - - /** - * Get feed url. - */ - public function getFeedUrl() - { - return $this->feedUrl; - } - - /** - * Get site url. - */ - public function getSiteUrl() - { - return $this->siteUrl; - } - - /** - * Get date. - */ - public function getDate() - { - return $this->date; - } - - /** - * Get language. - */ - public function getLanguage() - { - return $this->language; - } - - /** - * Get id. - */ - public function getId() - { - return $this->id; - } - - /** - * Get feed items. - */ - public function getItems() - { - return $this->items; - } - - /** - * Return true if the feed is "Right to Left". - * - * @return bool - */ - public function isRTL() - { - return Parser::isLanguageRTL($this->language); - } - - /** - * Set feed items. - * - * @param Item[] $items - * @return Feed - */ - public function setItems(array $items) - { - $this->items = $items; - return $this; - } - - /** - * Set feed id. - * - * @param string $id - * @return Feed - */ - public function setId($id) - { - $this->id = $id; - return $this; - } - - /** - * Set feed title. - * - * @param string $title - * @return Feed - */ - public function setTitle($title) - { - $this->title = $title; - return $this; - } - - /** - * Set feed description. - * - * @param string $description - * @return Feed - */ - public function setDescription($description) - { - $this->description = $description; - return $this; - } - - /** - * Set feed url. - * - * @param string $feedUrl - * @return Feed - */ - public function setFeedUrl($feedUrl) - { - $this->feedUrl = $feedUrl; - return $this; - } - - /** - * Set feed website url. - * - * @param string $siteUrl - * @return Feed - */ - public function setSiteUrl($siteUrl) - { - $this->siteUrl = $siteUrl; - return $this; - } - - /** - * Set feed date. - * - * @param \DateTime $date - * @return Feed - */ - public function setDate($date) - { - $this->date = $date; - return $this; - } - - /** - * Set feed language. - * - * @param string $language - * @return Feed - */ - public function setLanguage($language) - { - $this->language = $language; - return $this; - } - - /** - * Set feed logo. - * - * @param string $logo - * @return Feed - */ - public function setLogo($logo) - { - $this->logo = $logo; - return $this; - } - - /** - * Set feed icon. - * - * @param string $icon - * @return Feed - */ - public function setIcon($icon) - { - $this->icon = $icon; - return $this; - } -} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Parser/Item.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Parser/Item.php deleted file mode 100644 index 98214b8..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Parser/Item.php +++ /dev/null @@ -1,562 +0,0 @@ -namespaces); - } - - /** - * Get specific XML tag or attribute value. - * - * @param string $tag Tag name (examples: guid, media:content) - * @param string $attribute Tag attribute - * - * @return array|false Tag values or error - */ - public function getTag($tag, $attribute = '') - { - if ($attribute !== '') { - $attribute = '/@'.$attribute; - } - - $query = './/'.$tag.$attribute; - $elements = XmlParser::getXPathResult($this->xml, $query, $this->namespaces); - - if ($elements === false) { // xPath error - return false; - } - - return array_map(function ($element) { return (string) $element;}, $elements); - } - - /** - * Return item information. - * - * @return string - */ - public function __toString() - { - $output = ''; - - foreach (array('id', 'title', 'url', 'language', 'author', 'enclosureUrl', 'enclosureType') as $property) { - $output .= 'Item::'.$property.' = '.$this->$property.PHP_EOL; - } - - $publishedDate = $this->publishedDate != null ? $this->publishedDate->format(DATE_RFC822) : null; - $updatedDate = $this->updatedDate != null ? $this->updatedDate->format(DATE_RFC822) : null; - - $categoryString = $this->categories != null ? implode(',', $this->categories) : null; - - $output .= 'Item::date = '.$this->date->format(DATE_RFC822).PHP_EOL; - $output .= 'Item::publishedDate = '.$publishedDate.PHP_EOL; - $output .= 'Item::updatedDate = '.$updatedDate.PHP_EOL; - $output .= 'Item::isRTL() = '.($this->isRTL() ? 'true' : 'false').PHP_EOL; - $output .= 'Item::categories = ['.$categoryString.']'.PHP_EOL; - $output .= 'Item::content = '.strlen($this->content).' bytes'.PHP_EOL; - - return $output; - } - - /** - * Get title. - * - * @return string - */ - public function getTitle() - { - return $this->title; - } - - /** - * Get URL - * - * @access public - * @return string - */ - public function getUrl() - { - return $this->url; - } - - /** - * Set URL - * - * @access public - * @param string $url - * @return Item - */ - public function setUrl($url) - { - $this->url = $url; - return $this; - } - - /** - * Get id. - * - * @return string - */ - public function getId() - { - return $this->id; - } - - /** - * Get date. - * - * @return \DateTime - */ - public function getDate() - { - return $this->date; - } - - /** - * Get published date. - * - * @return \DateTime - */ - public function getPublishedDate() - { - return $this->publishedDate; - } - - /** - * Get updated date. - * - * @return \DateTime - */ - public function getUpdatedDate() - { - return $this->updatedDate; - } - - /** - * Get content. - * - * @return string - */ - public function getContent() - { - return $this->content; - } - - /** - * Set content - * - * @access public - * @param string $value - * @return Item - */ - public function setContent($value) - { - $this->content = $value; - return $this; - } - - /** - * Get enclosure url. - * - * @return string - */ - public function getEnclosureUrl() - { - return $this->enclosureUrl; - } - - /** - * Get enclosure type. - * - * @return string - */ - public function getEnclosureType() - { - return $this->enclosureType; - } - - /** - * Get language. - * - * @return string - */ - public function getLanguage() - { - return $this->language; - } - - /** - * Get categories. - * - * @return array - */ - public function getCategories() - { - return $this->categories; - } - - /** - * Get author. - * - * @return string - */ - public function getAuthor() - { - return $this->author; - } - - /** - * Get author URL. - * - * @return string - */ - public function getAuthorUrl() - { - return $this->authorUrl; - } - - /** - * Return true if the item is "Right to Left". - * - * @return bool - */ - public function isRTL() - { - return Parser::isLanguageRTL($this->language); - } - - /** - * Set item id. - * - * @param string $id - * @return Item - */ - public function setId($id) - { - $this->id = $id; - return $this; - } - - /** - * Set item title. - * - * @param string $title - * @return Item - */ - public function setTitle($title) - { - $this->title = $title; - return $this; - } - - /** - * Set author. - * - * @param string $author - * @return Item - */ - public function setAuthor($author) - { - $this->author = $author; - return $this; - } - - /** - * Set author URL. - * - * @param string $authorUrl - * @return Item - */ - public function setAuthorUrl($authorUrl) - { - $this->authorUrl = $authorUrl; - return $this; - } - - /** - * Set item date. - * - * @param \DateTime $date - * @return Item - */ - public function setDate($date) - { - $this->date = $date; - return $this; - } - - /** - * Set item published date. - * - * @param \DateTime $publishedDate - * @return Item - */ - public function setPublishedDate($publishedDate) - { - $this->publishedDate = $publishedDate; - return $this; - } - - /** - * Set item updated date. - * - * @param \DateTime $updatedDate - * @return Item - */ - public function setUpdatedDate($updatedDate) - { - $this->updatedDate = $updatedDate; - return $this; - } - - /** - * Set enclosure url. - * - * @param string $enclosureUrl - * @return Item - */ - public function setEnclosureUrl($enclosureUrl) - { - $this->enclosureUrl = $enclosureUrl; - return $this; - } - - /** - * Set enclosure type. - * - * @param string $enclosureType - * @return Item - */ - public function setEnclosureType($enclosureType) - { - $this->enclosureType = $enclosureType; - return $this; - } - - /** - * Set item language. - * - * @param string $language - * @return Item - */ - public function setLanguage($language) - { - $this->language = $language; - return $this; - } - - /** - * Set item categories. - * - * @param array $categories - * @return Item - */ - public function setCategories($categories) - { - $this->categories = $categories; - return $this; - } - - /** - * Set item categories from xml. - * - * @param |SimpleXMLElement[] $categories - * @return Item - */ - public function setCategoriesFromXml($categories) - { - if ($categories !== false) { - $this->setCategories( - array_map( - function ($element) { - return trim((string) $element); - }, - $categories - ) - ); - } - - return $this; - } - - /** - * Set raw XML. - * - * @param \SimpleXMLElement $xml - * @return Item - */ - public function setXml($xml) - { - $this->xml = $xml; - return $this; - } - - /** - * Get raw XML. - * - * @return \SimpleXMLElement - */ - public function getXml() - { - return $this->xml; - } - - /** - * Set XML namespaces. - * - * @param array $namespaces - * @return Item - */ - public function setNamespaces($namespaces) - { - $this->namespaces = $namespaces; - return $this; - } - - /** - * Get XML namespaces. - * - * @return array - */ - public function getNamespaces() - { - return $this->namespaces; - } -} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Parser/MalformedXmlException.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Parser/MalformedXmlException.php deleted file mode 100644 index efaf0ff..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Parser/MalformedXmlException.php +++ /dev/null @@ -1,13 +0,0 @@ -fallback_url = $fallback_url; - $xml_encoding = XmlParser::getEncodingFromXmlTag($content); - - // Strip XML tag to avoid multiple encoding/decoding in the next XML processing - $this->content = Filter::stripXmlTag($content); - - // Encode everything in UTF-8 - Logger::setMessage(get_called_class().': HTTP Encoding "'.$http_encoding.'" ; XML Encoding "'.$xml_encoding.'"'); - $this->content = Encoding::convert($this->content, $xml_encoding ?: $http_encoding); - - $this->itemPostProcessor = new ItemPostProcessor($this->config); - $this->itemPostProcessor->register(new ContentGeneratorProcessor($this->config)); - $this->itemPostProcessor->register(new ContentFilterProcessor($this->config)); - } - - /** - * Parse the document. - * @return Feed - * @throws MalformedXmlException - */ - public function execute() - { - Logger::setMessage(get_called_class().': begin parsing'); - - $xml = XmlParser::getSimpleXml($this->content); - - if ($xml === false) { - Logger::setMessage(get_called_class().': Applying XML workarounds'); - $this->content = Filter::normalizeData($this->content); - $xml = XmlParser::getSimpleXml($this->content); - - if ($xml === false) { - Logger::setMessage(get_called_class().': XML parsing error'); - Logger::setMessage(XmlParser::getErrors()); - throw new MalformedXmlException('XML parsing error'); - } - } - - $this->used_namespaces = $xml->getNamespaces(true); - $xml = $this->registerSupportedNamespaces($xml); - - $feed = new Feed(); - - $this->findFeedUrl($xml, $feed); - $this->checkFeedUrl($feed); - - $this->findSiteUrl($xml, $feed); - $this->checkSiteUrl($feed); - - $this->findFeedTitle($xml, $feed); - $this->findFeedDescription($xml, $feed); - $this->findFeedLanguage($xml, $feed); - $this->findFeedId($xml, $feed); - $this->findFeedDate($xml, $feed); - $this->findFeedLogo($xml, $feed); - $this->findFeedIcon($xml, $feed); - - foreach ($this->getItemsTree($xml) as $entry) { - $entry = $this->registerSupportedNamespaces($entry); - - $item = new Item(); - $item->xml = $entry; - $item->namespaces = $this->used_namespaces; - - $this->findItemAuthor($xml, $entry, $item); - $this->findItemAuthorUrl($xml, $entry, $item); - - $this->findItemUrl($entry, $item); - $this->checkItemUrl($feed, $item); - - $this->findItemTitle($entry, $item); - $this->findItemContent($entry, $item); - - // Id generation can use the item url/title/content (order is important) - $this->findItemId($entry, $item, $feed); - $this->findItemDate($entry, $item, $feed); - $this->findItemEnclosure($entry, $item, $feed); - $this->findItemLanguage($entry, $item, $feed); - $this->findItemCategories($entry, $item, $feed); - - $this->itemPostProcessor->execute($feed, $item); - $feed->items[] = $item; - } - - Logger::setMessage(get_called_class().PHP_EOL.$feed); - - return $feed; - } - - /** - * Check if the feed url is correct. - * - * @param Feed $feed Feed object - */ - public function checkFeedUrl(Feed $feed) - { - if ($feed->getFeedUrl() === '') { - $feed->feedUrl = $this->fallback_url; - } else { - $feed->feedUrl = Url::resolve($feed->getFeedUrl(), $this->fallback_url); - } - } - - /** - * Check if the site url is correct. - * - * @param Feed $feed Feed object - */ - public function checkSiteUrl(Feed $feed) - { - if ($feed->getSiteUrl() === '') { - $feed->siteUrl = Url::base($feed->getFeedUrl()); - } else { - $feed->siteUrl = Url::resolve($feed->getSiteUrl(), $this->fallback_url); - } - } - - /** - * Check if the item url is correct. - * - * @param Feed $feed Feed object - * @param Item $item Item object - */ - public function checkItemUrl(Feed $feed, Item $item) - { - $item->url = Url::resolve($item->getUrl(), $feed->getSiteUrl()); - } - - /** - * Find the item date. - * - * @param SimpleXMLElement $entry Feed item - * @param Item $item Item object - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findItemDate(SimpleXMLElement $entry, Item $item, Feed $feed) - { - $this->findItemPublishedDate($entry, $item, $feed); - $this->findItemUpdatedDate($entry, $item, $feed); - - if ($item->getPublishedDate() === null) { - // Use the updated date if available, otherwise use the feed date - $item->setPublishedDate($item->getUpdatedDate() ?: $feed->getDate()); - } - - if ($item->getUpdatedDate() === null) { - // Use the published date as fallback - $item->setUpdatedDate($item->getPublishedDate()); - } - - // Use the most recent of published and updated dates - $item->setDate(max($item->getPublishedDate(), $item->getUpdatedDate())); - } - - /** - * Get Item Post Processor instance - * - * @access public - * @return ItemPostProcessor - */ - public function getItemPostProcessor() - { - return $this->itemPostProcessor; - } - - /** - * Get DateParser instance - * - * @access public - * @return DateParser - */ - public function getDateParser() - { - if ($this->dateParser === null) { - $this->dateParser = new DateParser($this->config); - } - - return $this->dateParser; - } - - /** - * Generate a unique id for an entry (hash all arguments). - * - * @return string - */ - public function generateId() - { - return hash($this->hash_algo, implode(func_get_args())); - } - - /** - * Return true if the given language is "Right to Left". - * - * @static - * @param string $language Language: fr-FR, en-US - * @return bool - */ - public static function isLanguageRTL($language) - { - $language = strtolower($language); - - $rtl_languages = array( - 'ar', // Arabic (ar-**) - 'fa', // Farsi (fa-**) - 'ur', // Urdu (ur-**) - 'ps', // Pashtu (ps-**) - 'syr', // Syriac (syr-**) - 'dv', // Divehi (dv-**) - 'he', // Hebrew (he-**) - 'yi', // Yiddish (yi-**) - ); - - foreach ($rtl_languages as $prefix) { - if (strpos($language, $prefix) === 0) { - return true; - } - } - - return false; - } - - /** - * Set Hash algorithm used for id generation. - * - * @param string $algo Algorithm name - * @return \PicoFeed\Parser\Parser - */ - public function setHashAlgo($algo) - { - $this->hash_algo = $algo ?: $this->hash_algo; - return $this; - } - - /** - * Set config object. - * - * @param \PicoFeed\Config\Config $config Config instance - * @return \PicoFeed\Parser\Parser - */ - public function setConfig($config) - { - $this->config = $config; - $this->itemPostProcessor->setConfig($config); - return $this; - } - - /** - * Enable the content grabber. - * - * @return \PicoFeed\Parser\Parser - */ - public function disableContentFiltering() - { - $this->itemPostProcessor->unregister('PicoFeed\Processor\ContentFilterProcessor'); - return $this; - } - - /** - * Enable the content grabber. - * - * @param bool $needsRuleFile true if only pages with rule files should be - * scraped - * @param null|\Closure $scraperCallback Callback function that gets called for each - * scraper execution - * @return \PicoFeed\Parser\Parser - */ - public function enableContentGrabber($needsRuleFile = false, $scraperCallback = null) - { - $processor = new ScraperProcessor($this->config); - - if ($needsRuleFile) { - $processor->getScraper()->disableCandidateParser(); - } - - if ($scraperCallback !== null) { - $processor->setExecutionCallback($scraperCallback); - } - - $this->itemPostProcessor->register($processor); - return $this; - } - - /** - * Set ignored URLs for the content grabber. - * - * @param array $urls URLs - * @return \PicoFeed\Parser\Parser - */ - public function setGrabberIgnoreUrls(array $urls) - { - $this->itemPostProcessor->getProcessor('PicoFeed\Processor\ScraperProcessor')->ignoreUrls($urls); - return $this; - } - - /** - * Register all supported namespaces to be used within an xpath query. - * - * @param SimpleXMLElement $xml Feed xml - * @return SimpleXMLElement - */ - public function registerSupportedNamespaces(SimpleXMLElement $xml) - { - foreach ($this->namespaces as $prefix => $ns) { - $xml->registerXPathNamespace($prefix, $ns); - } - - return $xml; - } -} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Parser/ParserException.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Parser/ParserException.php deleted file mode 100644 index b5fbb69..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Parser/ParserException.php +++ /dev/null @@ -1,15 +0,0 @@ - 'http://purl.org/rss/1.0/', - 'dc' => 'http://purl.org/dc/elements/1.1/', - 'content' => 'http://purl.org/rss/1.0/modules/content/', - 'feedburner' => 'http://rssnamespace.org/feedburner/ext/1.0', - ); - - /** - * Get the path to the items XML tree. - * - * @param SimpleXMLElement $xml Feed xml - * @return SimpleXMLElement[] - */ - public function getItemsTree(SimpleXMLElement $xml) - { - return XmlParser::getXPathResult($xml, 'rss:item', $this->namespaces) - ?: XmlParser::getXPathResult($xml, 'item') - ?: $xml->item; - } - - /** - * Find the feed url. - * - * @param SimpleXMLElement $xml Feed xml - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findFeedUrl(SimpleXMLElement $xml, Feed $feed) - { - $feed->setFeedUrl(''); - } - - /** - * Find the site url. - * - * @param SimpleXMLElement $xml Feed xml - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findSiteUrl(SimpleXMLElement $xml, Feed $feed) - { - $value = XmlParser::getXPathResult($xml, 'rss:channel/rss:link', $this->namespaces) - ?: XmlParser::getXPathResult($xml, 'channel/link') - ?: $xml->channel->link; - - $feed->setSiteUrl(XmlParser::getValue($value)); - } - - /** - * Find the feed description. - * - * @param SimpleXMLElement $xml Feed xml - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findFeedDescription(SimpleXMLElement $xml, Feed $feed) - { - $description = XmlParser::getXPathResult($xml, 'rss:channel/rss:description', $this->namespaces) - ?: XmlParser::getXPathResult($xml, 'channel/description') - ?: $xml->channel->description; - - $feed->setDescription(XmlParser::getValue($description)); - } - - /** - * Find the feed logo url. - * - * @param SimpleXMLElement $xml Feed xml - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findFeedLogo(SimpleXMLElement $xml, Feed $feed) - { - $logo = XmlParser::getXPathResult($xml, 'rss:image/rss:url', $this->namespaces) - ?: XmlParser::getXPathResult($xml, 'image/url'); - - $feed->setLogo(XmlParser::getValue($logo)); - } - - /** - * Find the feed icon. - * - * @param SimpleXMLElement $xml Feed xml - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findFeedIcon(SimpleXMLElement $xml, Feed $feed) - { - $feed->setIcon(''); - } - - /** - * Find the feed title. - * - * @param SimpleXMLElement $xml Feed xml - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findFeedTitle(SimpleXMLElement $xml, Feed $feed) - { - $title = XmlParser::getXPathResult($xml, 'rss:channel/rss:title', $this->namespaces) - ?: XmlParser::getXPathResult($xml, 'channel/title') - ?: $xml->channel->title; - - $feed->setTitle(Filter::stripWhiteSpace(XmlParser::getValue($title)) ?: $feed->getSiteUrl()); - } - - /** - * Find the feed language. - * - * @param SimpleXMLElement $xml Feed xml - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findFeedLanguage(SimpleXMLElement $xml, Feed $feed) - { - $language = XmlParser::getXPathResult($xml, 'rss:channel/dc:language', $this->namespaces) - ?: XmlParser::getXPathResult($xml, 'channel/dc:language', $this->namespaces); - - $feed->setLanguage(XmlParser::getValue($language)); - } - - /** - * Find the feed id. - * - * @param SimpleXMLElement $xml Feed xml - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findFeedId(SimpleXMLElement $xml, Feed $feed) - { - $feed->setId($feed->getFeedUrl() ?: $feed->getSiteUrl()); - } - - /** - * Find the feed date. - * - * @param SimpleXMLElement $xml Feed xml - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findFeedDate(SimpleXMLElement $xml, Feed $feed) - { - $date = XmlParser::getXPathResult($xml, 'rss:channel/dc:date', $this->namespaces) - ?: XmlParser::getXPathResult($xml, 'channel/dc:date', $this->namespaces); - - $feed->setDate($this->getDateParser()->getDateTime(XmlParser::getValue($date))); - } - - /** - * Find the item published date. - * - * @param SimpleXMLElement $entry Feed item - * @param Item $item Item object - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findItemPublishedDate(SimpleXMLElement $entry, Item $item, Feed $feed) - { - $date = XmlParser::getXPathResult($entry, 'dc:date', $this->namespaces); - - $item->setPublishedDate(!empty($date) ? $this->getDateParser()->getDateTime(XmlParser::getValue($date)) : null); - } - - /** - * Find the item updated date. - * - * @param SimpleXMLElement $entry Feed item - * @param Item $item Item object - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findItemUpdatedDate(SimpleXMLElement $entry, Item $item, Feed $feed) - { - if ($item->publishedDate === null) { - $this->findItemPublishedDate($entry, $item, $feed); - } - $item->setUpdatedDate($item->getPublishedDate()); // No updated date in RSS 1.0 specifications - } - - /** - * Find the item title. - * - * @param SimpleXMLElement $entry Feed item - * @param \PicoFeed\Parser\Item $item Item object - */ - public function findItemTitle(SimpleXMLElement $entry, Item $item) - { - $title = XmlParser::getXPathResult($entry, 'rss:title', $this->namespaces) - ?: XmlParser::getXPathResult($entry, 'title') - ?: $entry->title; - - $item->setTitle(Filter::stripWhiteSpace(XmlParser::getValue($title)) ?: $item->getUrl()); - } - - /** - * Find the item author. - * - * @param SimpleXMLElement $xml Feed - * @param SimpleXMLElement $entry Feed item - * @param \PicoFeed\Parser\Item $item Item object - */ - public function findItemAuthor(SimpleXMLElement $xml, SimpleXMLElement $entry, Item $item) - { - $author = XmlParser::getXPathResult($entry, 'dc:creator', $this->namespaces) - ?: XmlParser::getXPathResult($xml, 'rss:channel/dc:creator', $this->namespaces) - ?: XmlParser::getXPathResult($xml, 'channel/dc:creator', $this->namespaces); - - $item->setAuthor(XmlParser::getValue($author)); - } - - /** - * Find the item author URL. - * - * @param SimpleXMLElement $xml Feed - * @param SimpleXMLElement $entry Feed item - * @param \PicoFeed\Parser\Item $item Item object - */ - public function findItemAuthorUrl(SimpleXMLElement $xml, SimpleXMLElement $entry, Item $item) - { - // There appears to be no support for author URL in the dc: terms - $item->setAuthorUrl(''); - } - - /** - * Find the item content. - * - * @param SimpleXMLElement $entry Feed item - * @param \PicoFeed\Parser\Item $item Item object - */ - public function findItemContent(SimpleXMLElement $entry, Item $item) - { - $content = XmlParser::getXPathResult($entry, 'content:encoded', $this->namespaces); - - if (XmlParser::getValue($content) === '') { - $content = XmlParser::getXPathResult($entry, 'rss:description', $this->namespaces) - ?: XmlParser::getXPathResult($entry, 'description') - ?: $entry->description; - } - - $item->setContent(XmlParser::getValue($content)); - } - - /** - * Find the item URL. - * - * @param SimpleXMLElement $entry Feed item - * @param \PicoFeed\Parser\Item $item Item object - */ - public function findItemUrl(SimpleXMLElement $entry, Item $item) - { - $link = XmlParser::getXPathResult($entry, 'feedburner:origLink', $this->namespaces) - ?: XmlParser::getXPathResult($entry, 'rss:link', $this->namespaces) - ?: XmlParser::getXPathResult($entry, 'link') - ?: $entry->link; - - $item->setUrl(XmlParser::getValue($link)); - } - - /** - * Genereate the item id. - * - * @param SimpleXMLElement $entry Feed item - * @param \PicoFeed\Parser\Item $item Item object - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findItemId(SimpleXMLElement $entry, Item $item, Feed $feed) - { - $item->setId($this->generateId( - $item->getTitle(), $item->getUrl(), $item->getContent() - )); - } - - /** - * Find the item enclosure. - * - * @param SimpleXMLElement $entry Feed item - * @param \PicoFeed\Parser\Item $item Item object - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findItemEnclosure(SimpleXMLElement $entry, Item $item, Feed $feed) - { - } - - /** - * Find the item language. - * - * @param SimpleXMLElement $entry Feed item - * @param \PicoFeed\Parser\Item $item Item object - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findItemLanguage(SimpleXMLElement $entry, Item $item, Feed $feed) - { - $language = XmlParser::getXPathResult($entry, 'dc:language', $this->namespaces); - - $item->setLanguage(XmlParser::getValue($language) ?: $feed->getLanguage()); - } - - /** - * Find the item categories. - * - * @param SimpleXMLElement $entry Feed item - * @param Item $item Item object - * @param Feed $feed Feed object - */ - public function findItemCategories(SimpleXMLElement $entry, Item $item, Feed $feed) - { - $categories = XmlParser::getXPathResult($entry, 'dc:subject', $this->namespaces); - $item->setCategoriesFromXml($categories); - } -} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Parser/Rss20.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Parser/Rss20.php deleted file mode 100644 index da9c0d5..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Parser/Rss20.php +++ /dev/null @@ -1,330 +0,0 @@ - 'http://purl.org/dc/elements/1.1/', - 'content' => 'http://purl.org/rss/1.0/modules/content/', - 'feedburner' => 'http://rssnamespace.org/feedburner/ext/1.0', - 'atom' => 'http://www.w3.org/2005/Atom', - ); - - /** - * Get the path to the items XML tree. - * - * @param SimpleXMLElement $xml Feed xml - * @return SimpleXMLElement[] - */ - public function getItemsTree(SimpleXMLElement $xml) - { - return XmlParser::getXPathResult($xml, 'channel/item'); - } - - /** - * Find the feed url. - * - * @param SimpleXMLElement $xml Feed xml - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findFeedUrl(SimpleXMLElement $xml, Feed $feed) - { - $feed->setFeedUrl(''); - } - - /** - * Find the site url. - * - * @param SimpleXMLElement $xml Feed xml - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findSiteUrl(SimpleXMLElement $xml, Feed $feed) - { - $value = XmlParser::getXPathResult($xml, 'channel/link'); - $feed->setSiteUrl(XmlParser::getValue($value)); - } - - /** - * Find the feed description. - * - * @param SimpleXMLElement $xml Feed xml - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findFeedDescription(SimpleXMLElement $xml, Feed $feed) - { - $value = XmlParser::getXPathResult($xml, 'channel/description'); - $feed->setDescription(XmlParser::getValue($value)); - } - - /** - * Find the feed logo url. - * - * @param SimpleXMLElement $xml Feed xml - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findFeedLogo(SimpleXMLElement $xml, Feed $feed) - { - $value = XmlParser::getXPathResult($xml, 'channel/image/url'); - $feed->setLogo(XmlParser::getValue($value)); - } - - /** - * Find the feed icon. - * - * @param SimpleXMLElement $xml Feed xml - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findFeedIcon(SimpleXMLElement $xml, Feed $feed) - { - $feed->setIcon(''); - } - - /** - * Find the feed title. - * - * @param SimpleXMLElement $xml Feed xml - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findFeedTitle(SimpleXMLElement $xml, Feed $feed) - { - $title = XmlParser::getXPathResult($xml, 'channel/title'); - $feed->setTitle(Filter::stripWhiteSpace(XmlParser::getValue($title)) ?: $feed->getSiteUrl()); - } - - /** - * Find the feed language. - * - * @param SimpleXMLElement $xml Feed xml - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findFeedLanguage(SimpleXMLElement $xml, Feed $feed) - { - $value = XmlParser::getXPathResult($xml, 'channel/language'); - $feed->setLanguage(XmlParser::getValue($value)); - } - - /** - * Find the feed id. - * - * @param SimpleXMLElement $xml Feed xml - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findFeedId(SimpleXMLElement $xml, Feed $feed) - { - $feed->setId($feed->getFeedUrl() ?: $feed->getSiteUrl()); - } - - /** - * Find the feed date. - * - * @param SimpleXMLElement $xml Feed xml - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findFeedDate(SimpleXMLElement $xml, Feed $feed) - { - $publish_date = XmlParser::getXPathResult($xml, 'channel/pubDate'); - $update_date = XmlParser::getXPathResult($xml, 'channel/lastBuildDate'); - - $published = !empty($publish_date) ? $this->getDateParser()->getDateTime(XmlParser::getValue($publish_date)) : null; - $updated = !empty($update_date) ? $this->getDateParser()->getDateTime(XmlParser::getValue($update_date)) : null; - - if ($published === null && $updated === null) { - $feed->setDate($this->getDateParser()->getCurrentDateTime()); // We use the current date if there is no date for the feed - } elseif ($published !== null && $updated !== null) { - $feed->setDate(max($published, $updated)); // We use the most recent date between published and updated - } else { - $feed->setDate($updated ?: $published); - } - } - - /** - * Find the item published date. - * - * @param SimpleXMLElement $entry Feed item - * @param Item $item Item object - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findItemPublishedDate(SimpleXMLElement $entry, Item $item, Feed $feed) - { - $date = XmlParser::getXPathResult($entry, 'pubDate'); - - $item->setPublishedDate(!empty($date) ? $this->getDateParser()->getDateTime(XmlParser::getValue($date)) : null); - } - - /** - * Find the item updated date. - * - * @param SimpleXMLElement $entry Feed item - * @param Item $item Item object - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findItemUpdatedDate(SimpleXMLElement $entry, Item $item, Feed $feed) - { - if ($item->publishedDate === null) { - $this->findItemPublishedDate($entry, $item, $feed); - } - $item->setUpdatedDate($item->getPublishedDate()); // No updated date in RSS 2.0 specifications - } - - /** - * Find the item title. - * - * @param SimpleXMLElement $entry Feed item - * @param \PicoFeed\Parser\Item $item Item object - */ - public function findItemTitle(SimpleXMLElement $entry, Item $item) - { - $value = XmlParser::getXPathResult($entry, 'title'); - $item->setTitle(Filter::stripWhiteSpace(XmlParser::getValue($value)) ?: $item->getUrl()); - } - - /** - * Find the item author. - * - * @param SimpleXMLElement $xml Feed - * @param SimpleXMLElement $entry Feed item - * @param \PicoFeed\Parser\Item $item Item object - */ - public function findItemAuthor(SimpleXMLElement $xml, SimpleXMLElement $entry, Item $item) - { - $value = XmlParser::getXPathResult($entry, 'dc:creator', $this->namespaces) - ?: XmlParser::getXPathResult($entry, 'author') - ?: XmlParser::getXPathResult($xml, 'channel/dc:creator', $this->namespaces) - ?: XmlParser::getXPathResult($xml, 'channel/managingEditor'); - - $item->setAuthor(XmlParser::getValue($value)); - } - - /** - * Find the item author URL. - * - * @param SimpleXMLElement $xml Feed - * @param SimpleXMLElement $entry Feed item - * @param \PicoFeed\Parser\Item $item Item object - */ - public function findItemAuthorUrl(SimpleXMLElement $xml, SimpleXMLElement $entry, Item $item) - { - // There appears to be no support for author URL in the dc: terms or author element - $item->setAuthorUrl(''); - } - - /** - * Find the item content. - * - * @param SimpleXMLElement $entry Feed item - * @param \PicoFeed\Parser\Item $item Item object - */ - public function findItemContent(SimpleXMLElement $entry, Item $item) - { - $content = XmlParser::getXPathResult($entry, 'content:encoded', $this->namespaces); - - if (XmlParser::getValue($content) === '') { - $content = XmlParser::getXPathResult($entry, 'description'); - } - - $item->setContent(XmlParser::getValue($content)); - } - - /** - * Find the item URL. - * - * @param SimpleXMLElement $entry Feed item - * @param \PicoFeed\Parser\Item $item Item object - */ - public function findItemUrl(SimpleXMLElement $entry, Item $item) - { - $link = XmlParser::getXPathResult($entry, 'feedburner:origLink', $this->namespaces) - ?: XmlParser::getXPathResult($entry, 'link') - ?: XmlParser::getXPathResult($entry, 'atom:link/@href', $this->namespaces); - - if (!empty($link)) { - $item->setUrl(XmlParser::getValue($link)); - } else { - $link = XmlParser::getXPathResult($entry, 'guid'); - $link = XmlParser::getValue($link); - - if (filter_var($link, FILTER_VALIDATE_URL) !== false) { - $item->setUrl($link); - } - } - } - - /** - * Genereate the item id. - * - * @param SimpleXMLElement $entry Feed item - * @param \PicoFeed\Parser\Item $item Item object - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findItemId(SimpleXMLElement $entry, Item $item, Feed $feed) - { - $id = XmlParser::getValue(XmlParser::getXPathResult($entry, 'guid')); - - if ($id) { - $item->setId($this->generateId($id)); - } else { - $item->setId($this->generateId( - $item->getTitle(), $item->getUrl(), $item->getContent() - )); - } - } - - /** - * Find the item enclosure. - * - * @param SimpleXMLElement $entry Feed item - * @param \PicoFeed\Parser\Item $item Item object - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findItemEnclosure(SimpleXMLElement $entry, Item $item, Feed $feed) - { - if (isset($entry->enclosure)) { - $type = XmlParser::getXPathResult($entry, 'enclosure/@type'); - $url = XmlParser::getXPathResult($entry, 'feedburner:origEnclosureLink', $this->namespaces) - ?: XmlParser::getXPathResult($entry, 'enclosure/@url'); - - $item->setEnclosureUrl(Url::resolve(XmlParser::getValue($url), $feed->getSiteUrl())); - $item->setEnclosureType(XmlParser::getValue($type)); - } - } - - /** - * Find the item language. - * - * @param SimpleXMLElement $entry Feed item - * @param \PicoFeed\Parser\Item $item Item object - * @param \PicoFeed\Parser\Feed $feed Feed object - */ - public function findItemLanguage(SimpleXMLElement $entry, Item $item, Feed $feed) - { - $language = XmlParser::getXPathResult($entry, 'dc:language', $this->namespaces); - $item->setLanguage(XmlParser::getValue($language) ?: $feed->getLanguage()); - } - - /** - * Find the item categories. - * - * @param SimpleXMLElement $entry Feed item - * @param Item $item Item object - * @param Feed $feed Feed object - */ - public function findItemCategories(SimpleXMLElement $entry, Item $item, Feed $feed) - { - $categories = XmlParser::getXPathResult($entry, 'category'); - $item->setCategoriesFromXml($categories); - } -} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Parser/Rss91.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Parser/Rss91.php deleted file mode 100644 index 058fca1..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Parser/Rss91.php +++ /dev/null @@ -1,13 +0,0 @@ -childNodes->length === 0) { - return false; - } - - return $dom; - } - - /** - * Small wrapper around Laminas Xml to turn their exceptions into PicoFeed exceptions - * - * @static - * @access private - * @param string $input - * @param DOMDocument $dom - * @throws XmlEntityException - * @return SimpleXMLElement|DomDocument|boolean - */ - private static function scan($input, $dom = null) - { - try { - return Security::scan($input, $dom); - } catch(RuntimeException $e) { - throw new XmlEntityException($e->getMessage()); - } - } - - /** - * Load HTML document by using a DomDocument instance or return false on failure. - * - * @static - * @access public - * @param string $input XML content - * @return DOMDocument - */ - public static function getHtmlDocument($input) - { - $dom = new DomDocument(); - - if (empty($input)) { - return $dom; - } - - libxml_use_internal_errors(true); - - if (version_compare(PHP_VERSION, '5.4.0', '>=')) { - $dom->loadHTML($input, LIBXML_NONET); - } else { - $dom->loadHTML($input); - } - - self::$errors = []; - foreach (libxml_get_errors() as $error) { - self::$errors[] = sprintf('XML error: %s (Line: %d - Column: %d - Code: %d)', - $error->message, - $error->line, - $error->column, - $error->code - ); - } - - libxml_use_internal_errors(false); - - return $dom; - } - - /** - * Convert a HTML document to XML. - * - * @static - * @access public - * @param string $html HTML document - * @return string - */ - public static function htmlToXml($html) - { - $dom = self::getHtmlDocument(''.$html); - return $dom->saveXML($dom->getElementsByTagName('body')->item(0)); - } - - /** - * Get XML parser errors. - * - * @static - * @access public - * @return string - */ - public static function getErrors() - { - return implode(', ', self::$errors); - } - - /** - * Get the encoding from a xml tag. - * - * @static - * @access public - * @param string $data Input data - * @return string - */ - public static function getEncodingFromXmlTag($data) - { - $encoding = ''; - - if (strpos($data, '')); - $data = str_replace("'", '"', $data); - - $p1 = strpos($data, 'encoding='); - $p2 = strpos($data, '"', $p1 + 10); - - if ($p1 !== false && $p2 !== false) { - $encoding = substr($data, $p1 + 10, $p2 - $p1 - 10); - $encoding = strtolower($encoding); - } - } - - return $encoding; - } - - /** - * Get the charset from a meta tag. - * - * @static - * @access public - * @param string $data Input data - * @return string - */ - public static function getEncodingFromMetaTag($data) - { - $encoding = ''; - - if (preg_match('/;]+)/i', $data, $match) === 1) { - $encoding = strtolower($match[1]); - } - - return $encoding; - } - - /** - * Rewrite XPath query to use namespace-uri and local-name derived from prefix. - * - * @static - * @access public - * @param string $query XPath query - * @param array $ns Prefix to namespace URI mapping - * @return string - */ - public static function replaceXPathPrefixWithNamespaceURI($query, array $ns) - { - return preg_replace_callback('/([A-Z0-9]+):([A-Z0-9]+)/iu', function ($matches) use ($ns) { - // don't try to map the special prefix XML - if (strtolower($matches[1]) === 'xml') { - return $matches[0]; - } - - return '*[namespace-uri()="'.$ns[$matches[1]].'" and local-name()="'.$matches[2].'"]'; - }, - $query); - } - - /** - * Get the result elements of a XPath query. - * - * @static - * @access public - * @param SimpleXMLElement $xml XML element - * @param string $query XPath query - * @param array $ns Prefix to namespace URI mapping - * @return SimpleXMLElement[] - */ - public static function getXPathResult(SimpleXMLElement $xml, $query, array $ns = array()) - { - if (!empty($ns)) { - $query = static::replaceXPathPrefixWithNamespaceURI($query, $ns); - } - - return $xml->xpath($query); - } - - /** - * Get the first Xpath result or SimpleXMLElement value - * - * @static - * @access public - * @param mixed $value - * @return string - */ - public static function getValue($value) - { - $result = ''; - - if (is_array($value) && count($value) > 0) { - $result = (string) $value[0]; - } elseif (is_a($value, 'SimpleXMLElement')) { - return $result = (string) $value; - } - - return trim($result); - } -} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/PicoFeedException.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/PicoFeedException.php deleted file mode 100644 index 2de9e4b..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/PicoFeedException.php +++ /dev/null @@ -1,14 +0,0 @@ -config->getContentFiltering(true)) { - $filter = Filter::html($item->getContent(), $feed->getSiteUrl()); - $filter->setConfig($this->config); - $item->setContent($filter->execute()); - } else { - Logger::setMessage(get_called_class().': Content filtering disabled'); - } - - return false; - } -} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Processor/ContentGeneratorProcessor.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Processor/ContentGeneratorProcessor.php deleted file mode 100644 index 49adf9c..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Processor/ContentGeneratorProcessor.php +++ /dev/null @@ -1,49 +0,0 @@ -generators as $generator) { - $className = '\PicoFeed\Generator\\'.ucfirst($generator).'ContentGenerator'; - $object = new $className($this->config); - - if ($object->execute($item)) { - return true; - } - } - - return false; - } -} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Processor/ItemPostProcessor.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Processor/ItemPostProcessor.php deleted file mode 100644 index 7b092b5..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Processor/ItemPostProcessor.php +++ /dev/null @@ -1,106 +0,0 @@ -processors as $processor) { - if ($processor->execute($feed, $item)) { - return true; - } - } - - return false; - } - - /** - * Register a new Item post-processor - * - * @access public - * @param ItemProcessorInterface $processor - * @return ItemPostProcessor - */ - public function register(ItemProcessorInterface $processor) - { - $this->processors[get_class($processor)] = $processor; - return $this; - } - - /** - * Remove Processor instance - * - * @access public - * @param string $class - * @return ItemPostProcessor - */ - public function unregister($class) - { - if (isset($this->processors[$class])) { - unset($this->processors[$class]); - } - - return $this; - } - - /** - * Checks whether a specific processor is registered or not - * - * @access public - * @param string $class - * @return bool - */ - public function hasProcessor($class) - { - return isset($this->processors[$class]); - } - - /** - * Get Processor instance - * - * @access public - * @param string $class - * @return ItemProcessorInterface|null - */ - public function getProcessor($class) - { - return isset($this->processors[$class]) ? $this->processors[$class] : null; - } - - public function setConfig(Config $config) - { - foreach ($this->processors as $processor) { - $processor->setConfig($config); - } - - return false; - } -} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Processor/ItemProcessorInterface.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Processor/ItemProcessorInterface.php deleted file mode 100644 index 5d53226..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Processor/ItemProcessorInterface.php +++ /dev/null @@ -1,25 +0,0 @@ -executionCallback = $executionCallback; - return $this; - } - - /** - * Execute Item Processor - * - * @access public - * @param Feed $feed - * @param Item $item - * @return bool - */ - public function execute(Feed $feed, Item $item) - { - if (!in_array($item->getUrl(), $this->ignoredUrls)) { - $scraper = $this->getScraper(); - $scraper->setUrl($item->getUrl()); - $scraper->execute(); - - if ($this->executionCallback && is_callable($this->executionCallback)) { - call_user_func($this->executionCallback, $feed, $item, $scraper); - } - - if ($scraper->hasRelevantContent()) { - $item->setContent($scraper->getFilteredContent()); - } - } - - return false; - } - - /** - * Ignore list of URLs - * - * @access public - * @param array $urls - * @return $this - */ - public function ignoreUrls(array $urls) - { - $this->ignoredUrls = $urls; - return $this; - } - - /** - * Returns Scraper instance - * - * @access public - * @return Scraper - */ - public function getScraper() - { - if ($this->scraper === null) { - $this->scraper = new Scraper($this->config); - } - - return $this->scraper; - } -} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Reader/Favicon.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Reader/Favicon.php deleted file mode 100644 index d4ca07d..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Reader/Favicon.php +++ /dev/null @@ -1,186 +0,0 @@ -content; - } - - /** - * Get the icon file type (available only after the download). - * - * @return string - */ - public function getType() - { - foreach ($this->types as $type) { - if (strpos($this->content_type, $type) === 0) { - return $type; - } - } - - return 'image/x-icon'; - } - - /** - * Get data URI (http://en.wikipedia.org/wiki/Data_URI_scheme). - * - * @return string - */ - public function getDataUri() - { - if (empty($this->content)) { - return ''; - } - - return sprintf( - 'data:%s;base64,%s', - $this->getType(), - base64_encode($this->content) - ); - } - - /** - * Download and check if a resource exists. - * - * @param string $url URL - * @return \PicoFeed\Client\Client Client instance - */ - public function download($url) - { - $client = Client::getInstance(); - $client->setConfig($this->config); - - Logger::setMessage(get_called_class().' Download => '.$url); - - try { - $client->execute($url); - } catch (ClientException $e) { - Logger::setMessage(get_called_class().' Download Failed => '.$e->getMessage()); - } - - return $client; - } - - /** - * Check if a remote file exists. - * - * @param string $url URL - * @return bool - */ - public function exists($url) - { - return $this->download($url)->getContent() !== ''; - } - - /** - * Get the icon link for a website. - * - * @param string $website_link URL - * @param string $favicon_link optional URL - * @return string - */ - public function find($website_link, $favicon_link = '') - { - $website = new Url($website_link); - - if ($favicon_link !== '') { - $icons = array($favicon_link); - } else { - $icons = $this->extract($this->download($website->getBaseUrl('/'))->getContent()); - $icons[] = $website->getBaseUrl('/favicon.ico'); - } - - foreach ($icons as $icon_link) { - $icon_link = Url::resolve($icon_link, $website); - $resource = $this->download($icon_link); - $this->content = $resource->getContent(); - $this->content_type = $resource->getContentType(); - - if ($this->content !== '') { - return $icon_link; - } elseif ($favicon_link !== '') { - return $this->find($website_link); - } - } - - return ''; - } - - /** - * Extract the icon links from the HTML. - * - * @param string $html HTML - * @return array - */ - public function extract($html) - { - $icons = array(); - - if (empty($html)) { - return $icons; - } - - $dom = XmlParser::getHtmlDocument($html); - - $xpath = new DOMXpath($dom); - $elements = $xpath->query('//link[@rel="icon" or @rel="shortcut icon" or @rel="Shortcut Icon" or @rel="icon shortcut"]'); - - for ($i = 0; $i < $elements->length; ++$i) { - $icons[] = $elements->item($i)->getAttribute('href'); - } - - return $icons; - } -} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Reader/Reader.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Reader/Reader.php deleted file mode 100644 index 596b02d..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Reader/Reader.php +++ /dev/null @@ -1,189 +0,0 @@ - '//feed', - 'Rss20' => '//rss[@version="2.0"]', - 'Rss92' => '//rss[@version="0.92"]', - 'Rss91' => '//rss[@version="0.91"]', - 'Rss10' => '//rdf', - ); - - /** - * Download a feed (no discovery). - * - * @param string $url Feed url - * @param string $last_modified Last modified HTTP header - * @param string $etag Etag HTTP header - * @param string $username HTTP basic auth username - * @param string $password HTTP basic auth password - * - * @return \PicoFeed\Client\Client - */ - public function download($url, $last_modified = '', $etag = '', $username = '', $password = '') - { - $url = $this->prependScheme($url); - - return Client::getInstance() - ->setConfig($this->config) - ->setLastModified($last_modified) - ->setEtag($etag) - ->setUsername($username) - ->setPassword($password) - ->execute($url); - } - - /** - * Discover and download a feed. - * - * @param string $url Feed or website url - * @param string $last_modified Last modified HTTP header - * @param string $etag Etag HTTP header - * @param string $username HTTP basic auth username - * @param string $password HTTP basic auth password - * @return Client - * @throws SubscriptionNotFoundException - */ - public function discover($url, $last_modified = '', $etag = '', $username = '', $password = '') - { - $client = $this->download($url, $last_modified, $etag, $username, $password); - - // It's already a feed or the feed was not modified - if (!$client->isModified() || $this->detectFormat($client->getContent())) { - return $client; - } - - // Try to find a subscription - $links = $this->find($client->getUrl(), $client->getContent()); - - if (empty($links)) { - throw new SubscriptionNotFoundException('Unable to find a subscription'); - } - - return $this->download($links[0], $last_modified, $etag, $username, $password); - } - - /** - * Find feed urls inside a HTML document. - * - * @param string $url Website url - * @param string $html HTML content - * - * @return array List of feed links - */ - public function find($url, $html) - { - Logger::setMessage(get_called_class().': Try to discover subscriptions'); - - $dom = XmlParser::getHtmlDocument($html); - $xpath = new DOMXPath($dom); - $links = array(); - - $queries = array( - '//link[@type="application/rss+xml"]', - '//link[@type="application/atom+xml"]', - ); - - foreach ($queries as $query) { - $nodes = $xpath->query($query); - - foreach ($nodes as $node) { - $link = $node->getAttribute('href'); - - if (!empty($link)) { - $feedUrl = new Url($link); - $siteUrl = new Url($url); - - $links[] = $feedUrl->getAbsoluteUrl($feedUrl->isRelativeUrl() ? $siteUrl->getBaseUrl() : ''); - } - } - } - - Logger::setMessage(get_called_class().': '.implode(', ', $links)); - - return $links; - } - - /** - * Get a parser instance. - * - * @param string $url Site url - * @param string $content Feed content - * @param string $encoding HTTP encoding - * @return \PicoFeed\Parser\Parser - * @throws UnsupportedFeedFormatException - */ - public function getParser($url, $content, $encoding) - { - $format = $this->detectFormat($content); - - if (empty($format)) { - throw new UnsupportedFeedFormatException('Unable to detect feed format'); - } - - $className = '\PicoFeed\Parser\\'.$format; - - $parser = new $className($content, $encoding, $url); - $parser->setHashAlgo($this->config->getParserHashAlgo()); - $parser->setConfig($this->config); - - return $parser; - } - - /** - * Detect the feed format. - * - * @param string $content Feed content - * @return string - */ - public function detectFormat($content) - { - $dom = XmlParser::getHtmlDocument($content); - $xpath = new DOMXPath($dom); - - foreach ($this->formats as $parser_name => $query) { - $nodes = $xpath->query($query); - - if ($nodes->length === 1) { - return $parser_name; - } - } - - return ''; - } - - /** - * Add the prefix "http://" if the end-user just enter a domain name. - * - * @param string $url Url - * @return string - */ - public function prependScheme($url) - { - if (!preg_match('%^https?://%', $url)) { - $url = 'http://'.$url; - } - - return $url; - } -} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Reader/ReaderException.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Reader/ReaderException.php deleted file mode 100644 index 4f03dbe..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Reader/ReaderException.php +++ /dev/null @@ -1,14 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.01net.com/editorial/624550/twitter-rachete-madbits-un-specialiste-francais-de-lanalyse-dimages/', - 'body' => array( - '//div[@class="article_ventre_box"]', - ), - 'strip' => array( - '//link', - '//*[contains(@class, "article_navigation")]', - '//h1', - '//*[contains(@class, "article_toolbarMain")]', - '//*[contains(@class, "article_imagehaute_box")]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/24.hu.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/24.hu.php deleted file mode 100644 index 6c269db..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/24.hu.php +++ /dev/null @@ -1,16 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://24.hu/belfold/2017/10/20/millios-lehuzasok-miatt-razziaztak-egy-budapesti-barban-videoval/', - 'body' => array( - '//div[@class="post-title-wrapper"]/h1', - '//div[@class="post-header-wrapper has-img"]/img', - '//div[@class="post-body"]' - - ), - 'strip' => array( - ) - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/444.hu.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/444.hu.php deleted file mode 100644 index e65bad1..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/444.hu.php +++ /dev/null @@ -1,19 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'https://444.hu/2017/10/20/tulszamlazo-helyen-utottek-rajta-budapest-belvarosaban', - 'body' => array( - '//div[@id="headline"]/h1', - '//article' - ), - 'strip' => array( - '//article/footer', - '//article/div[@class="jeti-roadblock ad"]', - '//figcaption', - '//noscript', - '//ul[@class="widget-stream-items"]' - ) - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/888.hu.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/888.hu.php deleted file mode 100644 index 68cfe05..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/888.hu.php +++ /dev/null @@ -1,16 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'https://888.hu/article-a-budapesti-szocik-nem-szeretik-a-videki-szocikat', - 'body' => array( - '//div[@id="cikkholder"]/h1', - '//div[@class="maincontent8"]' - ), - 'strip' => array( - '//div[@class="AdW"]', - '//h1[@class="olvastadmar"]' - ) - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/abstrusegoose.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/abstrusegoose.com.php deleted file mode 100644 index 752d041..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/abstrusegoose.com.php +++ /dev/null @@ -1,8 +0,0 @@ - array( - '%.*%' => array( - '%alt="(.+)" title="(.+)" */>%' => '/>
$1
$2', - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/achgut.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/achgut.com.php deleted file mode 100644 index 1e61fe6..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/achgut.com.php +++ /dev/null @@ -1,16 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.achgut.com/artikel/deutscher_herbst_wg_reichsstrasse_106', - 'body' => array( - '//div[@class="headerpict_half"]/div/img', - '//div[@class="beitrag"]/div[@class="teaser_blog_text"]' - ), - 'strip' => array( - '//div[@class="footer_blog_text"]', - '//div[@class="beitrag"]/div[@class="teaser_blog_text"]/h2[1]' - ) - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/adventuregamers.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/adventuregamers.com.php deleted file mode 100644 index 98d384e..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/adventuregamers.com.php +++ /dev/null @@ -1,23 +0,0 @@ - array( - '%^/news.*%' => array( - 'test_url' => 'http://www.adventuregamers.com/news/view/31079', - 'body' => array( - '//div[@class="bodytext"]', - ) - ), - '%^/videos.*%' => array( - 'test_url' => 'http://www.adventuregamers.com/videos/view/31056', - 'body' => array( - '//iframe', - ) - ), - '%^/articles.*%' => array( - 'test_url' => 'http://www.adventuregamers.com/articles/view/31049', - 'body' => array( - '//div[@class="cleft"]', - ) - ) - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/alainonline.net.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/alainonline.net.php deleted file mode 100644 index f440b23..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/alainonline.net.php +++ /dev/null @@ -1,14 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.alainonline.net/news_details.php?lang=arabic&sid=18907', - 'body' => array( - '//div[@class="news_details"]', - ), - 'strip' => array( - '//div[@class="news_details"]/div/div[last()]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/aljazeera.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/aljazeera.com.php deleted file mode 100644 index c02eb21..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/aljazeera.com.php +++ /dev/null @@ -1,25 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.aljazeera.com/news/2015/09/xi-jinping-seattle-china-150922230118373.html', - 'body' => array( - '//article[@id="main-story"]', - ), - 'strip' => array( - '//script', - '//header', - '//ul', - '//section[contains(@class,"profile")]', - '//a[@target="_self"]', - '//div[contains(@id,"_2")]', - '//div[contains(@id,"_3")]', - '//img[@class="viewMode"]', - '//table[contains(@class,"in-article-item")]', - '//div[@data-embed-type="Brightcove"]', - '//div[@class="QuoteContainer"]', - '//div[@class="BottomByLine"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/allafrica.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/allafrica.com.php deleted file mode 100644 index e8a506d..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/allafrica.com.php +++ /dev/null @@ -1,20 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.aljazeera.com/news/2015/09/xi-jinping-seattle-china-150922230118373.html', - 'body' => array( - '//div[@class="story-body"]', - ), - 'strip' => array( - '//p[@class="kindofstory"]', - '//cite[@class="byline"]', - '//div[@class="useful-top"]', - '//div[contains(@class,"related-topics")]', - '//links', - '//sharebar', - '//related-topics', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/allgemeine-zeitung.de.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/allgemeine-zeitung.de.php deleted file mode 100644 index 8ede99b..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/allgemeine-zeitung.de.php +++ /dev/null @@ -1,23 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.allgemeine-zeitung.de/lokales/polizei/mainz-gonsenheim-unbekannte-rauben-esso-tankstelle-in-kurt-schumacher-strasse-aus_14913147.htm', - 'body' => array( - '//div[contains(@class, "article")][1]', - ), - 'strip' => array( - '//read/h1', - '//*[@id="t-map"]', - '//*[contains(@class, "modules")]', - '//*[contains(@class, "adsense")]', - '//*[contains(@class, "linkbox")]', - '//*[contains(@class, "info")]', - '//*[@class="skip"]', - '//*[@class="funcs"]', - '//span[@class="nd address"]', - '//a[contains(@href, "abo-und-services")]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/amazingsuperpowers.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/amazingsuperpowers.com.php deleted file mode 100644 index 3214c62..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/amazingsuperpowers.com.php +++ /dev/null @@ -1,8 +0,0 @@ - array( - '%.*%' => array( - '%title="(.+)" */>%' => '/>
$1', - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/anythingcomic.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/anythingcomic.com.php deleted file mode 100644 index 51247f7..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/anythingcomic.com.php +++ /dev/null @@ -1,13 +0,0 @@ - array( - '%.*%' => array( - 'body' => array( - '//img[@id="comic_image"]', - '//div[@class="comment-wrapper"][position()=1]', - ), - 'strip' => array(), - 'test_url' => 'http://www.anythingcomic.com/comics/2108929/stress-free/', - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/ap.org.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/ap.org.php deleted file mode 100644 index 5bb2bb6..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/ap.org.php +++ /dev/null @@ -1,13 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://hosted.ap.org/dynamic/stories/A/AS_CHINA_GAO_ZHISHENG?SITE=AP&SECTION=HOME&TEMPLATE=DEFAULT', - 'body' => array( - '//img[@class="ap-smallphoto-img"]', - '//span[@class="entry-content"]', - ), - 'strip' => array(), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/areadvd.de.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/areadvd.de.php deleted file mode 100644 index fc56922..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/areadvd.de.php +++ /dev/null @@ -1,10 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.areadvd.de/news/daily-deals-angebote-bei-lautsprecher-teufel-3/', - 'body' => array('//div[contains(@class,"entry")]'), - 'strip' => array(), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/arstechnica.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/arstechnica.com.php deleted file mode 100644 index 55e01ce..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/arstechnica.com.php +++ /dev/null @@ -1,25 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://arstechnica.com/tech-policy/2015/09/judge-warners-2m-happy-birthday-copyright-is-bogus/', - 'body' => array( - '//article', - ), - 'strip' => array( - '//h4[@class="post-upperdek"]', - '//h1', - '//ul[@class="lSPager lSGallery"]', - '//div[@class="lSAction"]', - '//section[@class="post-meta"]', - '//figcaption', - '//aside', - '//div[@class="gallery-image-credit"]', - '//section[@class="article-author"]', - '//*[contains(@id,"social-")]', - '//div[contains(@id,"footer")]', - ), - ), - ), -); - diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/atv.hu.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/atv.hu.php deleted file mode 100644 index 170ec4d..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/atv.hu.php +++ /dev/null @@ -1,18 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.atv.hu/belfold/20171020-tobb-millio-forintot-csalt-ki-egy-idos-ferfitol-a-budapesti-no', - 'body' => array( - '//article' - ), - 'strip' => array( - '//span[@class="date"]', - '//div[@class="fb-like db_iframe_widget"]', - '//div[@class="ad-wrapper dashed-border"]', - '//div[@class="footer-meta-wrapper"]', - '//div[@class="image-wrapper "]' - ) - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/awkwardzombie.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/awkwardzombie.com.php deleted file mode 100644 index 5ab7051..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/awkwardzombie.com.php +++ /dev/null @@ -1,10 +0,0 @@ - array( - '%/index.php.*comic=.*%' => array( - 'test_url' => 'http://www.awkwardzombie.com/index.php?comic=041315', - 'body' => array('//*[@id="comic"]/img'), - 'strip' => array(), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/backchannel.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/backchannel.com.php deleted file mode 100644 index bc5932a..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/backchannel.com.php +++ /dev/null @@ -1,18 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'https://medium.com/lessons-learned/917b8b63ae3e', - 'body' => array( - '//div[contains(@class,"section-inner")]', - ), - 'strip' => array( - '//div[contains(@class,"metabar")]', - '//img[contains(@class,"thumbnail")]', - '//h1', - '//blockquote', - '//p[contains(@class,"graf-after--h4")]' - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/bangkokpost.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/bangkokpost.com.php deleted file mode 100644 index 165515b..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/bangkokpost.com.php +++ /dev/null @@ -1,19 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.bangkokpost.com/news/politics/704204/new-us-ambassador-arrives-in-bangkok', - 'body' => array( - '//article/div[@class="articleContents"]', - ), - 'strip' => array( - '//h2', - '//h4', - '//div[@class="text-size"]', - '//div[@class="relate-story"]', - '//div[@class="text-ads"]', - '//ul', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/bauerwilli.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/bauerwilli.com.php deleted file mode 100644 index b191a6e..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/bauerwilli.com.php +++ /dev/null @@ -1,17 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.bauerwilli.com/intuitive-eating/', - 'body' => array( - '//div[@class="entry-thumbnail"]', - '//div[@class="entry-content"]', - ), - 'strip' => array( - '//div[@class="tptn_counter"]', - '//div[contains(@class, "sharedaddy")]' - ), - ), - ), -); - diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/bgr.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/bgr.com.php deleted file mode 100644 index 7507a2f..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/bgr.com.php +++ /dev/null @@ -1,15 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://bgr.com/2015/09/27/iphone-6s-waterproof-testing/', - 'body' => array( - '//img[contains(@class,"img")]', - '//div[@class="text-column"]', - ), - 'strip' => array( - '//strong', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/bigfootjustice.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/bigfootjustice.com.php deleted file mode 100644 index d06ed12..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/bigfootjustice.com.php +++ /dev/null @@ -1,8 +0,0 @@ - array( - '%.*%' => array( - '%-150x150%' => '', - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/bigpicture.ru.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/bigpicture.ru.php deleted file mode 100644 index 55c4089..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/bigpicture.ru.php +++ /dev/null @@ -1,31 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://bigpicture.ru/?p=556658', - 'body' => array( - '//div[@class="article container"]', - ), - 'strip' => array( - '//script', - '//form', - '//style', - '//h1', - '//*[@class="wp-smiley"]', - '//div[@class="ipmd"]', - '//div[@class="tags"]', - '//div[@class="social-button"]', - '//div[@class="bottom-share"]', - '//div[@class="raccoonbox"]', - '//div[@class="yndadvert"]', - '//div[@class="we-recommend"]', - '//div[@class="relap-bigpicture_ru-wrapper"]', - '//div[@id="mmail"]', - '//div[@id="mobile-ads-cut"]', - '//div[@id="liquidstorm-alt-html"]', - '//div[contains(@class, "post-tags")]', - '//*[contains(text(),"Смотрите также")]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/bizjournals.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/bizjournals.com.php deleted file mode 100644 index d1cc3da..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/bizjournals.com.php +++ /dev/null @@ -1,12 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.bizjournals.com/milwaukee/news/2015/09/30/bucks-will-hike-prices-on-best-seats-at-new-arena.html', - 'body' => array( - '//figure/div/a/img', - '//p[@class="content__segment"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/biztimes.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/biztimes.com.php deleted file mode 100644 index d21aa98..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/biztimes.com.php +++ /dev/null @@ -1,22 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'https://www.biztimes.com/2017/02/10/settlement-would-revive-fowler-lake-condo-project-in-oconomowoc/', - 'body' => array( - '//h2/span[@class="subhead"]', - '//div[contains(@class,"article-content")]', - ), - 'strip' => array( - '//script', - '//div[contains(@class,"mobile-article-content")]', - '//div[contains(@class,"sharedaddy")]', - '//div[contains(@class,"author-details")]', - '//div[@class="row ad"]', - '//div[contains(@class,"relatedposts")]', - '//div[@class="col-lg-12"]', - '//div[contains(@class,"widget")]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/bleepingcomputer.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/bleepingcomputer.com.php deleted file mode 100644 index 7b74060..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/bleepingcomputer.com.php +++ /dev/null @@ -1,15 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'https://www.bleepingcomputer.com/news/google/chromes-sandbox-feature-infringes-on-three-patents-so-google-must-now-pay-20m/', - 'body' => array( - '//div[@class="article_section"]', - ), - 'strip' => array( - '//*[@itemprop="headline"]', - '//div[@class="cz-news-story-title-section"]' - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/blog.fefe.de.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/blog.fefe.de.php deleted file mode 100644 index 39c88ae..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/blog.fefe.de.php +++ /dev/null @@ -1,13 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://blog.fefe.de/?ts=ad706a73', - 'body' => array( - '/html/body/ul', - ), - 'strip' => array( - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/blog.mapillary.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/blog.mapillary.com.php deleted file mode 100644 index ce01651..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/blog.mapillary.com.php +++ /dev/null @@ -1,11 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://blog.mapillary.com/update/2015/08/26/traffic-sign-updates.html', - 'body' => array( - '//div[contains(@class, "blog-post__content")]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/brewers.mlb.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/brewers.mlb.com.php deleted file mode 100644 index be406fa..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/brewers.mlb.com.php +++ /dev/null @@ -1,22 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://m.brewers.mlb.com/news/article/161364798', - 'body' => array( - '//article[contains(@class,"article")]', - ), - 'strip' => array( - '//div[contains(@class,"ad-slot")]', - '//h1', - '//span[@class="timestamp"]', - '//div[contains(@class,"contributor-bottom")]', - '//div[contains(@class,"video")]', - '//ul[contains(@class,"social")]', - '//p[@class="tagline"]', - '//div[contains(@class,"social")]', - '//div[@class="button-wrap"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/buenosairesherald.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/buenosairesherald.com.php deleted file mode 100644 index 4e73e79..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/buenosairesherald.com.php +++ /dev/null @@ -1,17 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.buenosairesherald.com/article/199344/manzur-named-next-governor-of-tucum%C3%A1n', - 'body' => array( - '//div[@style="float:none"]', - ), - 'strip' => array( - '//div[contains(@class, "bz_alias_short_desc_container"]', - '//td[@id="bz_show_bug_column_1"]', - '//table[@id="attachment_table"]', - '//table[@class="bz_comment_table"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/bunicomic.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/bunicomic.com.php deleted file mode 100644 index ad83e43..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/bunicomic.com.php +++ /dev/null @@ -1,13 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.bunicomic.com/comic/buni-623/', - 'body' => array( - '//div[@class="comic-table"]', - ), - 'strip' => array( - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/buttersafe.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/buttersafe.com.php deleted file mode 100644 index 1f313cd..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/buttersafe.com.php +++ /dev/null @@ -1,13 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://buttersafe.com/2015/04/21/the-incredible-flexible-man/', - 'body' => array( - '//div[@id="comic"]', - '//div[@class="post-comic"]', - ), - 'strip' => array(), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/cad-comic.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/cad-comic.com.php deleted file mode 100644 index a631c97..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/cad-comic.com.php +++ /dev/null @@ -1,12 +0,0 @@ - array( - '%/cad/.+%' => array( - 'test_url' => 'http://www.cad-comic.com/cad/20150417', - 'body' => array( - '//*[@id="content"]/img', - ), - 'strip' => array(), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/chaoslife.findchaos.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/chaoslife.findchaos.com.php deleted file mode 100644 index ea6191e..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/chaoslife.findchaos.com.php +++ /dev/null @@ -1,10 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://chaoslife.findchaos.com/pets-in-the-wild', - 'body' => array('//div[@id="comic"]'), - 'strip' => array(), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/chinafile.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/chinafile.com.php deleted file mode 100644 index 450117b..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/chinafile.com.php +++ /dev/null @@ -1,18 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.chinafile.com/books/shanghai-faithful?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+chinafile%2FAll+%28ChinaFile%29', - 'body' => array( - '//div[contains(@class,"pane-featured-photo-panel-pane-1")]', - '//div[contains(@class,"video-above-fold")]', - '//div[@class="sc-media"]', - '//div[contains(@class,"field-name-body")]', - ), - 'strip' => array( - '//div[contains(@class,"cboxes")]', - '//div[contains(@class,"l-middle")]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/cicero.de.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/cicero.de.php deleted file mode 100644 index 2cd1b70..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/cicero.de.php +++ /dev/null @@ -1,17 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'https://cicero.de/innenpolitik/plaene-der-eu-kommission-der-ganz-normale-terror', - 'body' => array( - '//p[@class="lead"]', - '//article/div[2]/div[contains(@class, "field--name-field-cc-image")]', - '//article/div[2]/div[contains(@class, "image-description")]', - '//div[@class="field field-name-field-cc-body"]', - ), - 'strip' => array( - '//*[contains(@class, "urban-ad-sign")]' - ) - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/cliquerefresh.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/cliquerefresh.com.php deleted file mode 100644 index 9dcc7e5..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/cliquerefresh.com.php +++ /dev/null @@ -1,10 +0,0 @@ - array( - '%/comic.*%' => array( - 'test_url' => 'http://cliquerefresh.com/comic/078-stating-the-obvious/', - 'body' => array('//div[@class="comicImg"]/img | //div[@class="comicImg"]/a/img'), - 'strip' => array(), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/cnet.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/cnet.com.php deleted file mode 100644 index 60767a5..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/cnet.com.php +++ /dev/null @@ -1,37 +0,0 @@ - array( - '%^/products.*%' => array( - 'test_url' => 'http://www.cnet.com/products/fibaro-flood-sensor/#ftag=CADf328eec', - 'body' => array( - '//li[contains(@class,"slide first"] || //figure[contains(@class,(promoFigure))]', - '//div[@class="quickInfo"]', - '//div[@class="col-6 ratings"]', - '//div[@id="editorReview"]', - ), - 'strip' => array( - '//script', - '//a[@class="clickToEnlarge"]', - '//div[@section="topSharebar"]', - '//div[contains(@class,"related")]', - '//div[contains(@class,"ad-")]', - '//div[@section="shortcodeGallery"]', - ), - ), - '%.*%' => array( - 'test_url' => 'http://cnet.com.feedsportal.com/c/34938/f/645093/s/4a340866/sc/28/l/0L0Scnet0N0Cnews0Cman0Eclaims0Eonline0Epsychic0Emade0Ehim0Ebuy0E10Emillion0Epowerball0Ewinning0Eticket0C0Tftag0FCAD590Aa51e/story01.htm', - 'body' => array( - '//p[@itemprop="description"]', - '//div[@itemprop="articleBody"]', - ), - 'strip' => array( - '//script', - '//a[@class="clickToEnlarge"]', - '//div[@section="topSharebar"]', - '//div[contains(@class,"related")]', - '//div[contains(@class,"ad-")]', - '//div[@section="shortcodeGallery"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/coinwelt.de.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/coinwelt.de.php deleted file mode 100644 index 28a8bba..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/coinwelt.de.php +++ /dev/null @@ -1,14 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://coinwelt.de/2017/08/bitcache-kreierer-kim-dotcom-bietet-arbeitsplaetze-fuer-blockchain-goetter/', - 'body' => array( - '//div[@class="post-inner"]//div[@class="entry"]', - ), - 'strip' => array( - '//div[contains(@class, "shariff")]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/consomac.fr.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/consomac.fr.php deleted file mode 100644 index 9209f9c..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/consomac.fr.php +++ /dev/null @@ -1,13 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://consomac.fr/news-2430-l-iphone-6-toujours-un-secret-bien-garde.html', - 'body' => array( - '//div[contains(@id, "newscontent")]', - ), - 'strip' => array( - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/cowbirdsinlove.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/cowbirdsinlove.com.php deleted file mode 100644 index 3214c62..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/cowbirdsinlove.com.php +++ /dev/null @@ -1,8 +0,0 @@ - array( - '%.*%' => array( - '%title="(.+)" */>%' => '/>
$1', - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/crash.net.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/crash.net.php deleted file mode 100644 index 88cef14..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/crash.net.php +++ /dev/null @@ -1,18 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.crash.net/motogp/news/885102/1/dovizioso-mugello-win-was-catalyst-for-title-challenge', - 'body' => array( - '//*[@id="block-system-main"]', - ), - 'strip' => array( - '//script', - '//style', - '//*[@class="social-bar"]', - '//*[@id="below-headline-image-ad"]', - '//*[@class="advert-"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/csmonitor.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/csmonitor.com.php deleted file mode 100644 index 481e4b0..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/csmonitor.com.php +++ /dev/null @@ -1,19 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.csmonitor.com/USA/Politics/2015/0925/John-Boehner-steps-down-Self-sacrificing-but-will-it-lead-to-better-government', - 'body' => array( - '//h2[@id="summary"]', - '//div[@class="flex-video youtube"]', - '//div[contains(@class,"eza-body")]', - ), - 'strip' => array( - '//span[@id="breadcrumb"]', - '//div[@id="byline-wrapper"]', - '//div[@class="injection"]', - '//*[contains(@class,"promo_link")]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/dailyjs.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/dailyjs.com.php deleted file mode 100644 index 20eb1d7..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/dailyjs.com.php +++ /dev/null @@ -1,19 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://dailyjs.com/2014/08/07/p5js/', - 'body' => array( - '//div[@id="post"]', - ), - 'strip' => array( - '//h2[@class="post"]', - '//div[@class="meta"]', - '//*[contains(@class, "addthis_toolbox")]', - '//*[contains(@class, "addthis_default_style")]', - '//*[@class="navigation small"]', - '//*[@id="related"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/dailyreporter.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/dailyreporter.com.php deleted file mode 100644 index db3fc0e..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/dailyreporter.com.php +++ /dev/null @@ -1,15 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://dailyreporter.com/2016/01/09/us-supreme-court-case-could-weaken-government-workers-unions/', - 'body' => array( - '//div[contains(@class, "entry-content")]', - ), - 'strip' => array( - '//div[@class="dmcss_login_form"]', - '//*[contains(@class, "sharedaddy")]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/dailytech.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/dailytech.com.php deleted file mode 100644 index 5d1df4a..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/dailytech.com.php +++ /dev/null @@ -1,13 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.dailytech.com/Apples+First+Fixes+to+iOS+9+Land+w+iOS++901+Release/article37495.htm', - 'body' => array( - '//div[@class="NewsBodyImage"]', - '//span[@id="lblSummary"]', - '//span[@id="lblBody"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/degroupnews.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/degroupnews.com.php deleted file mode 100644 index 91f5c56..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/degroupnews.com.php +++ /dev/null @@ -1,14 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.degroupnews.com/medias/vodsvod/amazon-concurrence-la-chromecast-de-google-avec-fire-tv-stick', - 'body' => array( - '//div[@class="contenu"]', - ), - 'strip' => array( - '//div[contains(@class, "a2a")]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/derstandard.at.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/derstandard.at.php deleted file mode 100644 index 7e95a51..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/derstandard.at.php +++ /dev/null @@ -1,14 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://derstandard.at/2000010267354/The-Witcher-3-Hohe-Hardware-Anforderungen-fuer-PC-Spieler?ref=rss', - 'body' => array( - '//div[@class="copytext"]', - '//ul[@id="media-list"]', - ), - 'strip' => array( - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/dilbert.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/dilbert.com.php deleted file mode 100644 index b8e9b3d..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/dilbert.com.php +++ /dev/null @@ -1,11 +0,0 @@ - array( - '%.*%' => array( - 'body' => array( - '//img[@class="img-responsive img-comic"]', - ), - 'test_url' => 'http://dilbert.com/strip/2016-01-28', - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/discovermagazine.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/discovermagazine.com.php deleted file mode 100644 index ae0dfe7..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/discovermagazine.com.php +++ /dev/null @@ -1,26 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://blogs.discovermagazine.com/neuroskeptic/2017/01/25/publishers-jeffrey-beall/', - 'body' => array( - '//div[@class="contentWell"]', - ), - 'strip' => array( - '//h1', - '//div[@class="breadcrumbs"]', - '//div[@class="mobile"]', - '//div[@class="fromIssue"]', - '//div[contains(@class,"belowDeck")]', - '//div[@class="meta"]', - '//div[@class="shareIcons"]', - '//div[@class="categories"]', - '//div[@class="navigation"]', - '//div[@class="heading"]', - '//div[contains(@id,"-ad")]', - '//div[@class="relatedArticles"]', - '//div[@id="disqus_thread"]' - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/distrowatch.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/distrowatch.com.php deleted file mode 100644 index aefc8f8..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/distrowatch.com.php +++ /dev/null @@ -1,13 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://distrowatch.com/?newsid=08355', - 'body' => array( - '//td[@class="NewsText"][1]', - ), - 'strip' => array( - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/dozodomo.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/dozodomo.com.php deleted file mode 100644 index e116695..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/dozodomo.com.php +++ /dev/null @@ -1,15 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://dozodomo.com/bento/2014/03/04/lart-des-maki-de-takayo-kiyota/', - 'body' => array( - '//div[@class="joke"]', - '//div[@class="story-cover"]', - '//div[@class="story-content"]', - ), - 'strip' => array( - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/drawingboardcomic.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/drawingboardcomic.com.php deleted file mode 100644 index cd30f2e..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/drawingboardcomic.com.php +++ /dev/null @@ -1,15 +0,0 @@ - array( - '%.*%' => array( - 'body' => array('//img[@id="comicimage"]'), - 'strip' => array(), - 'test_url' => 'http://drawingboardcomic.com/index.php?comic=208', - ), - ), - 'filter' => array( - '%.*%' => array( - '%title="(.+)" */>%' => '/>
$1', - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/e-w-e.ru.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/e-w-e.ru.php deleted file mode 100644 index 8139cc9..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/e-w-e.ru.php +++ /dev/null @@ -1,22 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://e-w-e.ru/16-prekrasnyx-izobretenij-zhenshhin/', - 'body' => array( - '//div[contains(@class, "post_text")]', - ), - 'strip' => array( - '//script', - '//form', - '//style', - '//*[@class="views_post"]', - '//*[@class="adman_mobile"]', - '//*[@class="adman_desctop"]', - '//*[contains(@rel, "nofollow")]', - '//*[contains(@class, "wp-smiley")]', - '//*[contains(text(),"Источник:")]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/economist.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/economist.com.php deleted file mode 100644 index 522032f..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/economist.com.php +++ /dev/null @@ -1,25 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.economist.com/blogs/buttonwood/2017/02/mixed-signals?fsrc=rss', - 'body' => array( - '//article', - ), - 'strip' => array( - '//span[@class="blog-post__siblings-list-header "]', - '//h1', - '//aside', - '//div[@class="blog-post__asideable-wrapper"]', - '//div[@class="share_inline_header"]', - '//div[@id="column-right"]', - '//div[contains(@class,"blog-post__siblings-list-aside")]', - '//div[@class="video-player__wrapper"]', - '//div[@class="blog-post__bottom-panel"]', - '//div[contains(@class,"latest-updates-panel__container")]', - '//div[contains(@class,"blog-post__asideable-content")]', - '//div[@aria-label="Advertisement"]' - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/encyclopedie.naheulbeuk.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/encyclopedie.naheulbeuk.com.php deleted file mode 100644 index 19bcbde..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/encyclopedie.naheulbeuk.com.php +++ /dev/null @@ -1,13 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://encyclopedie.naheulbeuk.com/article.php3?id_article=352', - 'body' => array( - '//td//h1[@class="titre-texte"]', - '//td//div[@class="surtitre"]', - '//td//div[@class="texte"]', - ), - ) - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/endlessorigami.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/endlessorigami.com.php deleted file mode 100644 index d06ed12..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/endlessorigami.com.php +++ /dev/null @@ -1,8 +0,0 @@ - array( - '%.*%' => array( - '%-150x150%' => '', - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/engadget.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/engadget.com.php deleted file mode 100644 index cf9e448..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/engadget.com.php +++ /dev/null @@ -1,10 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.engadget.com/2015/04/20/dark-matter-discovery/?ncid=rss_truncated', - 'body' => array('//div[@id="page_body"]/div[@class="container@m-"]'), - 'strip' => array('//aside[@role="banner"]'), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/escapistmagazine.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/escapistmagazine.com.php deleted file mode 100644 index e86b59c..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/escapistmagazine.com.php +++ /dev/null @@ -1,45 +0,0 @@ - array( - '%/articles/view/comicsandcosplay/comics/critical-miss.*%' => array( - 'body' => array('//*[@class="body"]/span/img | //div[@class="folder_nav_links"]/following::p'), - 'test_url' => 'http://www.escapistmagazine.com/articles/view/comicsandcosplay/comics/critical-miss/13776-Critical-Miss-on-Framerates?utm_source=rss&utm_medium=rss&utm_campaign=articles', - 'strip' => array(), - ), - '%/articles/view/comicsandcosplay/comics/namegame.*%' => array( - 'body' => array('//*[@class="body"]/span/p/img[@height != "120"]'), - 'test_url' => 'http://www.escapistmagazine.com/articles/view/comicsandcosplay/comics/namegame/9759-Leaving-the-Nest?utm_source=rss&utm_medium=rss&utm_campaign=articles', - 'strip' => array(), - ), - '%/articles/view/comicsandcosplay/comics/stolen-pixels.*%' => array( - 'body' => array('//*[@class="body"]/span/p[2]/img'), - 'test_url' => 'http://www.escapistmagazine.com/articles/view/comicsandcosplay/comics/stolen-pixels/8866-Stolen-Pixels-258-Where-the-Boys-Are?utm_source=rss&utm_medium=rss&utm_campaign=articles', - 'strip' => array(), - ), - '%/articles/view/comicsandcosplay/comics/bumhugparade.*%' => array( - 'body' => array('//*[@class="body"]/span/p[2]/img'), - 'test_url' => 'http://www.escapistmagazine.com/articles/view/comicsandcosplay/comics/bumhugparade/8262-Bumhug-Parade-13?utm_source=rss&utm_medium=rss&utm_campaign=articles', - 'strip' => array(), - ), - '%/articles/view/comicsandcosplay.*/comics/escapistradiotheater%' => array( - 'body' => array('//*[@class="body"]/span/p[2]/img'), - 'test_url' => 'http://www.escapistmagazine.com/articles/view/comicsandcosplay/comics/escapistradiotheater/8265-The-Escapist-Radio-Theater-13?utm_source=rss&utm_medium=rss&utm_campaign=articles', - 'strip' => array(), - ), - '%/articles/view/comicsandcosplay/comics/paused.*%' => array( - 'body' => array('//*[@class="body"]/span/p[2]/img | //*[@class="body"]/span/div/img'), - 'test_url' => 'http://www.escapistmagazine.com/articles/view/comicsandcosplay/comics/paused/8263-Paused-16?utm_source=rss&utm_medium=rss&utm_campaign=articles', - 'strip' => array(), - ), - '%/articles/view/comicsandcosplay/comics/fraughtwithperil.*%' => array( - 'body' => array('//*[@class="body"]'), - 'test_url' => 'http://www.escapistmagazine.com/articles/view/comicsandcosplay/comics/fraughtwithperil/12166-The-Escapist-Presents-Escapist-Comics-Critical-Miss-B-lyeh-Fhlop?utm_source=rss&utm_medium=rss&utm_campaign=articles', - 'strip' => array(), - ), - '%/articles/view/video-games/columns/.*%' => array( - 'body' => array('//*[@id="article_content"]'), - 'test_url' => 'http://www.escapistmagazine.com/articles/view/video-games/columns/experienced-points/13971-What-50-Shades-and-Batman-Have-in-Common.2', - 'strip' => array(), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/espn.go.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/espn.go.com.php deleted file mode 100644 index 76a20f7..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/espn.go.com.php +++ /dev/null @@ -1,11 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://espn.go.com/nfl/story/_/id/13388208/jason-whitlock-chip-kelly-controversy', - 'body' => array( - '//p', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/exocomics.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/exocomics.com.php deleted file mode 100644 index 5adc59f..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/exocomics.com.php +++ /dev/null @@ -1,15 +0,0 @@ - array( - '%.*%' => array( - 'body' => array('//a[@class="comic"]/img'), - 'strip' => array(), - 'test_url' => 'http://www.exocomics.com/379', - ), - ), - 'filter' => array( - '%.*%' => array( - '%title="(.+)" */>%' => '/>
$1', - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/explosm.net.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/explosm.net.php deleted file mode 100644 index 3fdf02c..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/explosm.net.php +++ /dev/null @@ -1,13 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://explosm.net/comics/3803/', - 'body' => array( - '//div[@id="comic-container"]', - ), - 'strip' => array( - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/extrafabulouscomics.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/extrafabulouscomics.com.php deleted file mode 100644 index 12697cc..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/extrafabulouscomics.com.php +++ /dev/null @@ -1,8 +0,0 @@ - array( - '%.*%' => array( - '%-150x150%' => '', - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/factroom.ru.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/factroom.ru.php deleted file mode 100644 index a572061..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/factroom.ru.php +++ /dev/null @@ -1,27 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.factroom.ru/life/20-facts-about-oil', - 'body' => array( - '//div[@class="post"]', - ), - 'strip' => array( - '//script', - '//form', - '//style', - '//h1', - '//div[@id="yandex_ad2"]', - '//*[@class="jp-relatedposts"]', - '//div[contains(@class, "likely-desktop")]', - '//div[contains(@class, "likely-mobile")]', - '//p[last()]', - '//div[contains(@class, "facebook")]', - '//div[contains(@class, "desktop-underpost-direct")]', - '//div[contains(@class, "source-box")]', - '//div[contains(@class, "under-likely-desktop")]', - '//div[contains(@class, "mobile-down-post")]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/fastcodesign.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/fastcodesign.com.php deleted file mode 100644 index 74e70a8..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/fastcodesign.com.php +++ /dev/null @@ -1,13 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.fastcodesign.com/3026548/exposure/peek-inside-the-worlds-forbidden-subway-tunnels', - 'body' => array( - '//article[contains(@class, "body prose")]', - ), - 'strip' => array( - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/fastcoexist.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/fastcoexist.com.php deleted file mode 100644 index 6916f28..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/fastcoexist.com.php +++ /dev/null @@ -1,13 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.fastcoexist.com/3026114/take-a-seat-on-this-gates-funded-future-toilet-that-will-change-how-we-think-about-poop', - 'body' => array( - '//article[contains(@class, "body prose")]', - ), - 'strip' => array( - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/fastcompany.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/fastcompany.com.php deleted file mode 100644 index e0869a2..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/fastcompany.com.php +++ /dev/null @@ -1,13 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.fastcompany.com/3026712/fast-feed/elon-musk-an-apple-tesla-merger-is-very-unlikely', - 'body' => array( - '//article[contains(@class, "body prose")]', - ), - 'strip' => array( - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/ffworld.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/ffworld.com.php deleted file mode 100644 index 20a47b2..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/ffworld.com.php +++ /dev/null @@ -1,13 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.ffworld.com/?rub=news&page=voir&id=2709', - 'body' => array( - '//div[@class="news_body"]', - ), - 'strip' => array( - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/foreignpolicy.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/foreignpolicy.com.php deleted file mode 100644 index 3cbcddc..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/foreignpolicy.com.php +++ /dev/null @@ -1,21 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://foreignpolicy.com/2016/01/09/networking-giant-pulls-nsa-linked-code-exploited-by-hackers/', - 'body' => array( - '//article', - ), - 'strip' => array( - '//div[@id="post-category"]', - '//div[@id="desktop-right"]', - '//h1', - '//section[@class="article-meta"]', - '//div[@class="side-panel-wrapper"]', - '//*[contains(@class, "share-")]', - '//*[contains(@id, "taboola-")]', - '//div[@class="comments"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/fossbytes.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/fossbytes.com.php deleted file mode 100644 index 6ce4725..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/fossbytes.com.php +++ /dev/null @@ -1,18 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://fossbytes.com/fbi-hacked-1000-computers-to-shut-down-largest-child-pornography-site-on-the-dark-web/', - 'body' => array( - '//div[@class="entry-inner"]', - ), - 'strip' => array( - '//*[@class="at-above-post addthis_default_style addthis_toolbox at-wordpress-hide"]', - '//*[@class="at-below-post addthis_default_style addthis_toolbox at-wordpress-hide"]', - '//*[@class="at-below-post-recommended addthis_default_style addthis_toolbox at-wordpress-hide"]', - '//*[@class="code-block code-block-12 ai-desktop"]', - '//*[@class="code-block code-block-13 ai-tablet-phone"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/fototelegraf.ru.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/fototelegraf.ru.php deleted file mode 100644 index ca2f85a..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/fototelegraf.ru.php +++ /dev/null @@ -1,19 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://fototelegraf.ru/?p=348232', - 'body' => array( - '//div[@class="post-content"]', - ), - 'strip' => array( - '//script', - '//form', - '//style', - '//div[@class="imageButtonsBlock"]', - '//div[@class="adOnPostBtwImg"]', - '//div[contains(@class, "post-tags")]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/fowllanguagecomics.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/fowllanguagecomics.com.php deleted file mode 100644 index 3f62f07..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/fowllanguagecomics.com.php +++ /dev/null @@ -1,10 +0,0 @@ - array( - '%.*%' => array( - 'body' => array('//*[@id="comic"] | //*[@class="post-image"]'), - 'strip' => array(), - 'test_url' => 'http://www.fowllanguagecomics.com/comic/working-out/', - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/gamechannel.hu.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/gamechannel.hu.php deleted file mode 100644 index 8ab9c5c..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/gamechannel.hu.php +++ /dev/null @@ -1,15 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.gamechannel.hu/cikk/hirblock/a-legacy-of-kain-feltamasztasara-keszul-a-crystal-dynamics', - 'body' => array( - '//div[@class="post"]/div[@class="entry"]' - ), - 'strip' => array( - '//div[@class="valaszto"]', - '//center/blockquote' // as we can't grab iframe here - ) - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/gamestar.hu.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/gamestar.hu.php deleted file mode 100644 index 56a4c72..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/gamestar.hu.php +++ /dev/null @@ -1,17 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'https://www.gamestar.hu/hir/horizon-zero-dawn-the-frozen-wilds-vedjegy-239019.html', - 'body' => array( - '//article/header/h1', - '//div[@class="section section-2-3"]/div[@class="image"]/img', - '//article/p[@class="lead"]', - '//article/div[@class="content"]' - ), - 'strip' => array( - '//div[@class="ad ad-article-inside"]' - ) - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/geek.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/geek.com.php deleted file mode 100644 index d9ccecc..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/geek.com.php +++ /dev/null @@ -1,17 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.geek.com/news/the-11-best-ways-to-eat-eggs-1634076/', - 'body' => array( - '//div[@class="articleinfo"]/figure', - '//div[@class="articleinfo"]/article', - '//span[@class="by"]', - ), - 'strip' => array( - '//span[@class="red"]', - '//div[@class="on-target"]' - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/geektimes.ru.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/geektimes.ru.php deleted file mode 100644 index 1954138..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/geektimes.ru.php +++ /dev/null @@ -1,12 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'https://geektimes.ru/post/289151/', - 'body' => array( - "//div[contains(concat(' ',normalize-space(@class),' '),' content ')]" - ), - 'strip' => array(), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/gerbilwithajetpack.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/gerbilwithajetpack.com.php deleted file mode 100644 index 44013b3..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/gerbilwithajetpack.com.php +++ /dev/null @@ -1,12 +0,0 @@ - array( - '%.*%' => array( - 'body' => array( - '//div[@id="comic-1"]', - '//div[@class="entry"]', - ), - 'test_url' => 'http://gerbilwithajetpack.com/passing-the-digital-buck/', - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/giantitp.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/giantitp.com.php deleted file mode 100644 index d9c3ae5..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/giantitp.com.php +++ /dev/null @@ -1,12 +0,0 @@ - array( - '%/comics/oots.*%' => array( - 'test_url' => 'http://www.giantitp.com/comics/oots0989.html', - 'body' => array( - '//td[@align="center"]/img', - ), - 'strip' => array(), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/github.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/github.com.php deleted file mode 100644 index 726634f..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/github.com.php +++ /dev/null @@ -1,14 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'https://github.com/audreyr/favicon-cheat-sheet', - 'body' => array( - '//article[contains(@class, "entry-content")]', - ), - 'strip' => array( - '//h1', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/gocomics.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/gocomics.com.php deleted file mode 100644 index 32960f0..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/gocomics.com.php +++ /dev/null @@ -1,12 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.gocomics.com/pearlsbeforeswine/2015/05/30', - 'body' => array( - '//div[1]/p[1]/a[1]/img', - ), - 'strip' => array(), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/golem.de.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/golem.de.php deleted file mode 100644 index 8731285..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/golem.de.php +++ /dev/null @@ -1,21 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.golem.de/news/breko-telekom-verzoegert-gezielt-den-vectoring-ausbau-1311-102974.html', - 'body' => array( - '//header[@class="cluster-header"]', - '//header[@class="paged-cluster-header"]', - '//div[@class="formatted"]', - ), - 'next_page' => array( - '//a[@id="atoc_next"]' - ), - 'strip' => array( - '//header[@class="cluster-header"]/a', - '//header[@class="cluster-header"]/h1', - '//div[@id="iqadtile4"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/gondola.hu.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/gondola.hu.php deleted file mode 100644 index 62b1e3c..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/gondola.hu.php +++ /dev/null @@ -1,22 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'https://gondola.hu/hirek/213754-A_budapesti_fejlesztesek_kerdese_mar_nem_zsakbamacska.html', - 'body' => array( - '//div[@id="cikk"]/div[@class="cim"]', - '//br[1]', - '//div[@class="alcim"]', - '//div[@class="lead"]', - '//div[@class="szoveg"]' - ), - 'strip' => array( - '//div[@class="ikonok"]', - '//div[@class="linkekblokk"]', - '//div[@id="billboardbanner"]', - '//div[@class="szerzo"]', - '//div[@class="kulcsszavak"]' - ) - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/gorabbit.ru.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/gorabbit.ru.php deleted file mode 100644 index 4e43248..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/gorabbit.ru.php +++ /dev/null @@ -1,19 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://gorabbit.ru/article/10-oshchushcheniy-za-rulem-kogda-tolko-poluchil-voditelskie-prava', - 'body' => array( - '//div[@class="detail_text"]', - ), - 'strip' => array( - '//script', - '//form', - '//style', - '//div[@class="socials"]', - '//div[@id="cr_1"]', - '//div[@class="related_items"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/habrahabr.ru.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/habrahabr.ru.php deleted file mode 100644 index 3f1ec16..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/habrahabr.ru.php +++ /dev/null @@ -1,12 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'https://habrahabr.ru/company/pentestit/blog/328606/', - 'body' => array( - "//div[contains(concat(' ',normalize-space(@class),' '),' content ')]" - ), - 'strip' => array(), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/happletea.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/happletea.com.php deleted file mode 100644 index 75b0b83..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/happletea.com.php +++ /dev/null @@ -1,18 +0,0 @@ - array( - '%.*%' => array( - 'body' => array( - '//div[@id="comic"]', - '//div[@class="entry"]', - ), - 'strip' => array('//div[@class="ssba"]'), - 'test_url' => 'http://www.happletea.com/comic/mans-best-friend/', - ), - ), - 'filter' => array( - '%.*%' => array( - '%title="(.+)" */>%' => '/>
$1', - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/hardware.fr.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/hardware.fr.php deleted file mode 100644 index 56aec4f..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/hardware.fr.php +++ /dev/null @@ -1,11 +0,0 @@ - array( - '%^/news.*%' => array( - 'test_url' => 'http://www.hardware.fr/news/14760/intel-lance-nouveaux-ssd-nand-3d.html', - 'body' => array( - '//div[@class="content_actualite"]/div[@class="md"]', - ) - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/heise.de.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/heise.de.php deleted file mode 100644 index 0ee6915..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/heise.de.php +++ /dev/null @@ -1,79 +0,0 @@ - array( - '%^/tp.*%' => array( - 'test_url' => 'https://www.heise.de/tp/features/Macrons-Vermoegenssteuer-Der-Staat-verzichtet-auf-3-2-Milliarden-3863931.html', - 'body' => array( - '//main/article' - ), - 'strip' => array( - '//header', - '//aside', - '//nav[@class="pre-akwa-toc"]', - '//*[@class="seite_zurueck"]', - '//*[@class="pagination"]', - '//a[@class="kommentare_lesen_link"]', - '//div[contains(@class, "shariff")]', - '//a[@class="beitragsfooter_permalink"]', - '//a[@class="beitragsfooter_fehlermelden"]', - '//a[@class="beitragsfooter_printversion"]' - ), - 'next_page' => array( - '//a[@class="seite_weiter"]' - ), - ), - '%^/newsticker/meldung.*%' => array( - 'test_url' => 'https://www.heise.de/newsticker/meldung/DragonFly-BSD-5-0-mit-experimentellem-HAMMER2-veroeffentlicht-3864731.html', - 'body' => array( - '//div[@class="article-content"]', - ), - 'strip' => array( - '//*[contains(@class, "gallery")]', - '//*[contains(@class, "video")]', - ), - ), - '%^/autos/artikel.*%' => array( - 'test_url' => 'https://www.heise.de/autos/artikel/Bericht-Mazda-baut-Range-Extender-mit-Wankelmotor-3864760.html', - 'body' => array( - '//section[@id="artikel_text"]' - ), - 'strip' => array( - '//p[@id="content_foren"]', - '//div[contains(@class, "shariff")]', - '//p[@class="permalink"]', - '//p[@class="printversion"]' - ), - ), - '%^/foto/meldung.*%' => array( - 'test_url' => 'https://www.heise.de/foto/meldung/Wildlife-Fotograf-des-Jahres-Gewinnerbild-zeigt-getoetetes-Nashorn-3864311.html', - 'body' => array( - '//div[@class="article-content"]' - ), - ), - '%^/ct.*%' => array( - 'test_url' => 'https://www.heise.de/ct/artikel/Google-Pixel-2-und-Pixel-2-XL-im-Test-3863842.html', - 'body' => array( - '//main/div[1]/div[1]/section' - ), - 'strip' => array( - '//header' - ) - ), - '%^/developer.*%' => array( - 'test_url' => 'https://www.heise.de/developer/meldung/Container-Docker-unterstuetzt-Kubernetes-3863625.html', - 'body' => array( - '//div[@class="article-content"]' - ) - ), - '%.*%' => array( - 'test_url' => 'https://www.heise.de/mac-and-i/meldung/iOS-App-Nude-findet-mittels-ML-Nacktbilder-und-versteckt-sie-3864217.html', - 'body' => array( - '//article/div[@class="meldung_wrapper"]', - ), - 'strip' => array( - '//*[contains(@class, "gallery")]', - '//*[contains(@class, "video")]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/hirek.prim.hu.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/hirek.prim.hu.php deleted file mode 100644 index 1a38809..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/hirek.prim.hu.php +++ /dev/null @@ -1,14 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://hirek.prim.hu/cikk/2017/10/02/atadtak_a_6_fenntarthatosagi_sajtodijat', - 'body' => array( - '//div[@class="boxbody article_box"]/h2', - '//div[@class="text_body"]' - ), - 'strip' => array( - ) - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/hotshowlife.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/hotshowlife.com.php deleted file mode 100644 index faf01f3..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/hotshowlife.com.php +++ /dev/null @@ -1,23 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'https://hotshowlife.com/top-10-chempionov-produktov-po-szhiganiyu-kalorij/', - 'body' => array( - '//div[@class="entry-content"]', - ), - 'strip' => array( - '//script', - '//form', - '//style', - '//div[@class="ads2"]', - '//div[@class="mistape_caption"]', - '//div[contains(@class, "et_social_media_hidden")]', - '//div[contains(@class, "et_social_inline_bottom")]', - '//div[contains(@class, "avatar")]', - '//ul[contains(@class, "entry-tags")]', - '//div[contains(@class, "entry-meta")]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/huffingtonpost.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/huffingtonpost.com.php deleted file mode 100644 index b52b07b..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/huffingtonpost.com.php +++ /dev/null @@ -1,13 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.huffingtonpost.com/2014/02/20/centscere-social-media-syracuse_n_4823848.html', - 'body' => array( - '//article[@class="content")]', - ), - 'strip' => array( - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/hvg.hu.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/hvg.hu.php deleted file mode 100644 index efc9371..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/hvg.hu.php +++ /dev/null @@ -1,17 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://hvg.hu/brandchannel/mastercardbch_20171006_Egyetlen_mobillal_erintettuk_Budapest_legjobb_gasztrohelyeit', - 'body' => array( - '//div[@class="article-title article-title"]', - '//div[@class="article-cover-img"]', - '//div[@class="article-main"]' - ), - 'strip' => array( - '//figcaption', - '//div[@class="article-info byline"]' - ) - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/idokep.hu.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/idokep.hu.php deleted file mode 100644 index 06cae09..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/idokep.hu.php +++ /dev/null @@ -1,18 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'https://www.idokep.hu/hirek/4-es-erossegu-tajfun-tart-japan-fele', - 'body' => array( - '//div[@class="cikk-title"]/h3', - '//div[@class="lead"]', - '//div[@class="atvett_tartalom"]', - '//div[@class="cikk-tartalom"]' - ), - 'strip' => array( - '//div[@class="cimkes-doboz"]', - '//div[@class="komment-wrap"]' - ) - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/imogenquest.net.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/imogenquest.net.php deleted file mode 100644 index 3214c62..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/imogenquest.net.php +++ /dev/null @@ -1,8 +0,0 @@ - array( - '%.*%' => array( - '%title="(.+)" */>%' => '/>
$1', - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/index.hu.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/index.hu.php deleted file mode 100644 index 727d7b7..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/index.hu.php +++ /dev/null @@ -1,29 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://index.hu/mindekozben/poszt/2017/10/20/art_deco_budapest_varosnezo_zsebkonyv_bolla_zoltan/', - 'body' => array( - '//div[@class="mindenkozben_post_content content"]', - '//div[@id="content"]' - ), - 'strip' => array( - '//div[@class="topszponzor_wrapper"]', - '//ul[@class="cikk-cimkek"]', - '//div[@class="author-share-date-container"]', - '//div[@class="pp-list"]', - '//div[@class="social-stripe cikk-bottom-box"]', - '//div[@class="cikk-bottom-text-ad"]', - '//a[@name="hozzaszolasok"]', - '//div[@class="cikk-vegi-ajanlo-reklamok-container"]', - '//div[@id="comments"]', - '//div[@class="comments"]', - '//div[@class="linkpreview-box bekezdes_utan"]', - '//div[@class="lapozo"]', - '//div[@class="szelso-jobb"]', - '//div[@class="social cikk-bottom-box"]', - '//input' - ) - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/indiehaven.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/indiehaven.com.php deleted file mode 100644 index a40ce69..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/indiehaven.com.php +++ /dev/null @@ -1,11 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://indiehaven.com/no-mans-sky-is-a-solo-space-adventure-and-im-ok-with-that/', - 'body' => array( - '//section[contains(@class, "entry-content")]', - ) - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/inforadio.hu.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/inforadio.hu.php deleted file mode 100644 index 569013d..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/inforadio.hu.php +++ /dev/null @@ -1,25 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://inforadio.hu/belfold/2017/10/20/fontos_valtozas_vegleg_lezarnak_tobb_villamosatjarot_budapesten/', - 'body' => array( - '//div[@class="content-title"]', - '//div[@class="szelso-jobb-lead_container"]', - '//div[@class="cikk-torzs"]' - ), - 'strip' => array( - '//div[@id="microsite_microsite"]', - '//div[@class="cikk-bottom-text-ad"]', - '//div[@class="social-stripe_container"]', - '//div[@class="facebook-like-box"]', - '//div[@class="rovat sargabg rovatdobozcim"]', - '//div[@class="m-okosradio_magazin arenaMagazineItem"]', - '//header[@class="m-okosradio_header"]', - '//div[@class="m-okosradio_elo"]', - '//div[@class="m-okosradio_container"]', - '//form' - ) - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/ing.dk.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/ing.dk.php deleted file mode 100644 index 5a021a0..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/ing.dk.php +++ /dev/null @@ -1,12 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://ing.dk/artikel/smart-husisolering-og-styring-skal-mindske-japans-energikrise-164517', - 'body' => array( - '//section[contains(@class, "teaser")]', - '//section[contains(@class, "body")]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/invisiblebread.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/invisiblebread.com.php deleted file mode 100644 index 90f8759..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/invisiblebread.com.php +++ /dev/null @@ -1,8 +0,0 @@ - array( - '%.*%' => array( - '%()%' => '$1', - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/ir.amd.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/ir.amd.com.php deleted file mode 100644 index af99fe9..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/ir.amd.com.php +++ /dev/null @@ -1,10 +0,0 @@ - array( - '%.*%' => array( - 'body' => array('//span[@class="ccbnTxt"]'), - 'strip' => array(), - 'test_url' => 'http://ir.amd.com/phoenix.zhtml?c=74093&p=RssLanding&cat=news&id=2055819', - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/japantimes.co.jp.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/japantimes.co.jp.php deleted file mode 100644 index 9959441..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/japantimes.co.jp.php +++ /dev/null @@ -1,21 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.japantimes.co.jp/news/2015/09/27/world/social-issues-world/pope-meets-sex-abuse-victims-philadelphia-promises-accountability/', - 'body' => array( - '//article[@role="main"]', - ), - 'strip' => array( - '//script', - '//header', - '//div[contains(@class, "meta")]', - '//div[@class="clearfix"]', - '//div[@class="OUTBRAIN"]', - '//ul[@id="content_footer_menu"]', - '//div[@class="article_footer_ad"]', - '//div[@id="disqus_thread"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/japantoday.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/japantoday.com.php deleted file mode 100644 index 22485d6..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/japantoday.com.php +++ /dev/null @@ -1,15 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.japantoday.com/category/politics/view/japan-u-s-to-sign-new-base-environment-pact', - 'body' => array( - '//div[@id="article_container"]', - ), - 'strip' => array( - '//h2', - '//div[@id="article_info"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/journaldugeek.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/journaldugeek.com.php deleted file mode 100644 index 876b269..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/journaldugeek.com.php +++ /dev/null @@ -1,11 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www./2014/05/20/le-playstation-now-arrive-en-beta-fermee-aux-etats-unis/', - 'body' => array( - '//div[@class="post-content"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/jsonline.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/jsonline.com.php deleted file mode 100644 index 5895256..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/jsonline.com.php +++ /dev/null @@ -1,37 +0,0 @@ - array( - '%.%/picture-gallery/%' => array( - 'test_url' => 'http://www.jsonline.com/picture-gallery/news/local/milwaukee/2017/02/22/photos-aclu-sues-milwaukee-police-over-profiling-stop-and-frisk/98250836/', - 'body' => array( - '//div[@class="priority-asset-gallery galleries standalone hasendslate"]', - ), - 'strip' => array( - '//div[@class="buy-photo-btn"]', - '//div[@class="gallery-thumbs thumbs pag-thumbs")]', - ), - ), - '%.*%' => array( - 'test_url' => 'http://www.jsonline.com/news/usandworld/as-many-as-a-million-expected-for-popes-last-mass-in-us-b99585180z1-329688131.html', - 'body' => array( - '//div[@itemprop="articleBody"]', - ), - 'strip' => array( - '//h1', - '//iframe', - '//span[@class="mycapture-small-btn mycapture-btn-with-text mycapture-expandable-photo-btn-small js-mycapture-btn-small"]', - '//div[@class="close-wrap"]', - '//div[contains(@class,"ui-video-wrapper")]', - '//div[contains(@class,"media-mob")]', - '//div[contains(@class,"left-mob")]', - '//div[contains(@class,"nerdbox")]', - '//p/span', - '//div[contains(@class,"oembed-asset")]', - '//*[contains(@class,"share")]', - '//div[contains(@class,"gallery-asset")]', - '//div[contains(@class,"oembed-asset")]', - '//div[@class="article-print-url"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/justcoolidea.ru.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/justcoolidea.ru.php deleted file mode 100644 index 089ff29..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/justcoolidea.ru.php +++ /dev/null @@ -1,19 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://justcoolidea.ru/idealnyj-sad-samodelnye-proekty-dlya-berezhlivogo-domovladeltsa/', - 'body' => array( - '//section[@class="entry-content"]', - ), - 'strip' => array( - '//script', - '//form', - '//style', - '//*[contains(@class, "essb_links")]', - '//*[contains(@rel, "nofollow")]', - '//*[contains(@class, "ads")]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/kanpai.fr.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/kanpai.fr.php deleted file mode 100644 index c3a1abc..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/kanpai.fr.php +++ /dev/null @@ -1,13 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.kanpai.fr/japon/comment-donner-lheure-en-japonais.html', - 'body' => array( - '//div[@class="single-left"]', - ), - 'strip' => array( - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/karriere.jobfinder.dk.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/karriere.jobfinder.dk.php deleted file mode 100644 index 25d6dfa..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/karriere.jobfinder.dk.php +++ /dev/null @@ -1,12 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://karriere.jobfinder.dk/artikel/dansk-professor-skal-lede-smart-grid-forskning-20-millioner-dollars-763', - 'body' => array( - '//section[contains(@class, "teaser")]', - '//section[contains(@class, "body")]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/kisalfold.hu.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/kisalfold.hu.php deleted file mode 100644 index 7568901..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/kisalfold.hu.php +++ /dev/null @@ -1,17 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.kisalfold.hu/szorakozas/egy_15_eves_srac_szuntetheti_meg_a_wc-parat_budapesten/2536699/', - 'body' => array( - '//header[@class="single-article__header"]/h1', - '//header[@class="single-article__header"]/h2', - '//figure[@class="single-article__image"]/img', - '//div[@class="single-article__content"]/div[@id="single-article__lead"]', - '//div[@id="article_text"]' - ), - 'strip' => array( - ) - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/kiszamolo.hu.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/kiszamolo.hu.php deleted file mode 100644 index c44a08f..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/kiszamolo.hu.php +++ /dev/null @@ -1,14 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'https://kiszamolo.hu/30-eve-volt-a-fekete-hetfo/', - 'body' => array( - '//article/h2', - '//article/div[@class="entry clearfix"]/p' - ), - 'strip' => array( - ) - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/kodi.tv.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/kodi.tv.php deleted file mode 100644 index 439fc90..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/kodi.tv.php +++ /dev/null @@ -1,11 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'https://kodi.tv/article/andwere-baaaaack', - 'body' => array( - '//div[@class="l-region--content"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/koreaherald.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/koreaherald.com.php deleted file mode 100644 index 9651056..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/koreaherald.com.php +++ /dev/null @@ -1,11 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.koreaherald.com/view.php?ud=20150926000018', - 'body' => array( - '//div[@id="articleText"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/koreatimes.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/koreatimes.php deleted file mode 100644 index f274b4a..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/koreatimes.php +++ /dev/null @@ -1,14 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.koreatimes.co.kr/www/news/nation/2015/12/116_192409.html', - 'body' => array( - '//div[@id="p"]', - ), - 'strip' => array( - '//div[@id="webtalks_btn_listenDiv"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/lastplacecomics.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/lastplacecomics.com.php deleted file mode 100644 index 12697cc..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/lastplacecomics.com.php +++ /dev/null @@ -1,8 +0,0 @@ - array( - '%.*%' => array( - '%-150x150%' => '', - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/legorafi.fr.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/legorafi.fr.php deleted file mode 100644 index e6aae46..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/legorafi.fr.php +++ /dev/null @@ -1,22 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => array( - 'http://www.legorafi.fr/2016/12/16/gorafi-magazine-bravo-vous-avez-bientot-presque-survecu-a-2016/', - 'http://www.legorafi.fr/2016/12/15/manuel-valls-promet-quune-fois-elu-il-debarrassera-la-france-de-manuel-valls/', - ), - 'body' => array( - '//section[@id="banner_magazine"]', - '//figure[@class="main_picture"]', - '//div[@class="content"]', - ), - 'strip' => array( - '//figcaption', - '//div[@class="sharebox"]', - '//div[@class="tags"]', - '//section[@class="taboola_article"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/lejapon.fr.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/lejapon.fr.php deleted file mode 100644 index 8f2b293..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/lejapon.fr.php +++ /dev/null @@ -1,17 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://lejapon.fr/guide-voyage-japon/5223/tokyo-sous-la-neige.htm', - 'body' => array( - '//div[@class="entry"]', - ), - 'strip' => array( - '//*[contains(@class, "addthis_toolbox")]', - '//*[contains(@class, "addthis_default_style")]', - '//*[@class="navigation small"]', - '//*[@id="related"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/lesjoiesducode.fr.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/lesjoiesducode.fr.php deleted file mode 100644 index 369206a..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/lesjoiesducode.fr.php +++ /dev/null @@ -1,13 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://lesjoiesducode.fr/post/75576211207/quand-lappli-ne-fonctionne-plus-sans-aucune-raison', - 'body' => array( - '//div[@class="blog-post-content"]', - ), - 'strip' => array( - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/lfg.co.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/lfg.co.php deleted file mode 100644 index d978a5f..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/lfg.co.php +++ /dev/null @@ -1,12 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.lfg.co/page/871/?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+LookingForGroup+%28Looking+For+Group%29&utm_content=FeedBurner', - 'body' => array( - '//*[@id="comic"]/img | //*[@class="content"]', - ), - 'strip' => array(), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/lifehacker.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/lifehacker.com.php deleted file mode 100644 index b9a6933..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/lifehacker.com.php +++ /dev/null @@ -1,18 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://lifehacker.com/bring-water-bottle-caps-into-concerts-to-protect-your-d-1269334973', - 'body' => array( - '//div[contains(@class, "row")/img', - '//div[contains(@class, "content-column")]', - ), - 'strip' => array( - '//*[contains(@class, "meta")]', - '//span[contains(@class, "icon")]', - '//h1', - '//aside', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/lifehacker.ru.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/lifehacker.ru.php deleted file mode 100644 index bc140f6..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/lifehacker.ru.php +++ /dev/null @@ -1,22 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://lifehacker.ru/2016/03/03/polymail/', - 'body' => array( - '//div[@class="post-content"]', - ), - 'strip' => array( - '//script', - '//form', - '//style', - '//*[@class="wp-thumbnail-caption"]', - '//*[contains(@class, "social-likes")]', - '//*[@class="jp-relatedposts"]', - '//*[contains(@class, "wpappbox")]', - '//*[contains(@class, "icon__image")]', - '//div[@id="hypercomments_widget"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/linux-magazin.de.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/linux-magazin.de.php deleted file mode 100644 index f4bc07d..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/linux-magazin.de.php +++ /dev/null @@ -1,16 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.linux-magazin.de/Ausgaben/2017/09/AWS-Alternativen', - 'body' => array( - '//div[@class="attribute-content"]/div[@class="attribute-intro"]', - '(//div[@class="attribute-image"])[1]', - '//div[@itemprop="articleBody"]', - ), - 'strip' => array( - '//p[@class="attribute-advice"]', - ) - ) - ) -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/linux.org.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/linux.org.php deleted file mode 100644 index 2520d0d..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/linux.org.php +++ /dev/null @@ -1,14 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.linux.org/threads/lua-the-scripting-interpreter.8352/', - 'body' => array( - '//div[@class="messageContent"]', - ), - 'strip' => array( - '//aside', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/linux.org.ru.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/linux.org.ru.php deleted file mode 100644 index 7fa0249..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/linux.org.ru.php +++ /dev/null @@ -1,13 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.linux.org/threads/lua-the-scripting-interpreter.8352/', - 'body' => array( - '//div[@itemprop="articleBody"]', - ), - 'strip' => array( - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/linuxinsider.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/linuxinsider.com.php deleted file mode 100644 index 4e0a4cc..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/linuxinsider.com.php +++ /dev/null @@ -1,20 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.linuxinsider.com/story/82526.html?rss=1', - 'body' => array( - '//div[@id="story"]', - ), - 'strip' => array( - '//script', - '//h1', - '//div[@id="story-toolbox1"]', - '//div[@id="story-byline"]', - '//div[@id="story"]/p', - '//div[@class="story-advertisement"]', - '//iframe', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/lists.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/lists.php deleted file mode 100644 index c7051a2..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/lists.php +++ /dev/null @@ -1,13 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://lists.freebsd.org/pipermail/freebsd-announce/2013-September/001504.html', - 'body' => array( - '//pre', - ), - 'strip' => array( - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/loadingartist.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/loadingartist.com.php deleted file mode 100644 index d06ed12..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/loadingartist.com.php +++ /dev/null @@ -1,8 +0,0 @@ - array( - '%.*%' => array( - '%-150x150%' => '', - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/loldwell.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/loldwell.com.php deleted file mode 100644 index d358e15..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/loldwell.com.php +++ /dev/null @@ -1,10 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://loldwell.com/?comic=food-math-101', - 'body' => array('//*[@id="comic"]'), - 'strip' => array(), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/lukesurl.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/lukesurl.com.php deleted file mode 100644 index 816233d..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/lukesurl.com.php +++ /dev/null @@ -1,15 +0,0 @@ - array( - '%.*%' => array( - 'body' => array('//div[@id="comic"]//img'), - 'strip' => array(), - 'test_url' => 'http://www.lukesurl.com/archives/comic/665-3-of-clubs', - ), - ), - 'filter' => array( - '%.*%' => array( - '%title="(.+)" */>%' => '/>
$1', - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/macg.co.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/macg.co.php deleted file mode 100644 index bbe6dbc..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/macg.co.php +++ /dev/null @@ -1,13 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.macg.co//logiciels/2014/05/feedly-sameliore-un-petit-peu-sur-mac-82205', - 'body' => array( - '//div[contains(@class, "field-name-body")]', - ), - 'strip' => array( - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/maclife.de.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/maclife.de.php deleted file mode 100644 index bca347e..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/maclife.de.php +++ /dev/null @@ -1,11 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.maclife.de/news/neue-farbe-iphone-8-kommt-blush-gold-10094817.html', - 'body' => array( - '//div[contains(@class, "article_wrapper")]/p | //div[contains(@class, "article_wrapper")]/h2 | //div[@class="gallery"]//figure | //div[contains(@class, "gallery_single")]//figure', - ) - ) - ) -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/magyarkurir.hu.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/magyarkurir.hu.php deleted file mode 100644 index 32d78bc..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/magyarkurir.hu.php +++ /dev/null @@ -1,21 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.magyarkurir.hu/hirek/a-vilagszerte-ismert-dicsoito-csapat-hillsong-young-free-lep-fel-budapesten', - 'body' => array( - '//div[@class="behuzas"]' - ), - 'strip' => array( - '//div[@class="ikonsav"]', - '//p[@class="copyright"]', - '//div[@class="cimkek"]', - '//div[@id="footerbanner"]', - '//div[@class="rovat sargabg rovatdobozcim"]', - '//div[@class="rovatdoboz"]', - '//a[contains(., "Own")]', - '//a[@class="fblink"]' - ) - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/marc.info.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/marc.info.php deleted file mode 100644 index 5f582a6..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/marc.info.php +++ /dev/null @@ -1,13 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://marc.info/?l=openbsd-misc&m=141987113202061&w=2', - 'body' => array( - '//pre', - ), - 'strip' => array( - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/marriedtothesea.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/marriedtothesea.com.php deleted file mode 100644 index 469640d..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/marriedtothesea.com.php +++ /dev/null @@ -1,12 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.marriedtothesea.com/index.php?date=052915', - 'body' => array( - '//div[@align]/a/img', - ), - 'strip' => array(), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/marycagle.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/marycagle.com.php deleted file mode 100644 index b8665e3..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/marycagle.com.php +++ /dev/null @@ -1,13 +0,0 @@ - array( - '%.*%' => array( - 'body' => array( - '//img[@id="cc-comic"]', - '//div[@class="cc-newsbody"]', - ), - 'strip' => array(), - 'test_url' => 'http://www.marycagle.com/letsspeakenglish/74-grim-reality/', - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/maximumble.thebookofbiff.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/maximumble.thebookofbiff.com.php deleted file mode 100644 index 8880054..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/maximumble.thebookofbiff.com.php +++ /dev/null @@ -1,10 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://maximumble.thebookofbiff.com/2015/04/20/1084-change/', - 'body' => array('//div[@id="comic"]/div/a/img'), - 'strip' => array(), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/medium.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/medium.com.php deleted file mode 100644 index e20860e..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/medium.com.php +++ /dev/null @@ -1,19 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'https://medium.com/lessons-learned/917b8b63ae3e', - 'body' => array( - '//div[@class="section-content"]', - ), - 'strip' => array( - '//div[contains(@class,"metabar")]', - '//img[contains(@class,"thumbnail")]', - '//h1', - '//blockquote', - '//div[@class="aspectRatioPlaceholder-fill"]', - '//footer' - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/mercworks.net.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/mercworks.net.php deleted file mode 100644 index c7a27de..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/mercworks.net.php +++ /dev/null @@ -1,17 +0,0 @@ - array( - '%.*%' => array( - 'body' => array('//div[@id="comic"]', - '//div[contains(@class,"entry-content")]', - ), - 'strip' => array(), - 'test_url' => 'http://mercworks.net/comicland/healthy-choice/', - ), - ), - 'filter' => array( - '%.*%' => array( - '%title="(.+)" */>%' => '/>
$1', - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/metronieuws.nl.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/metronieuws.nl.php deleted file mode 100644 index 5011169..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/metronieuws.nl.php +++ /dev/null @@ -1,10 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.metronieuws.nl/sport/2015/04/broer-fellaini-zorgde-bijna-voor-paniek-bij-mourinho', - 'body' => array('//div[contains(@class,"article-top")]/div[contains(@class,"image-component")] | //div[@class="article-full-width"]/div[1]'), - 'strip' => array(), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/milwaukeenns.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/milwaukeenns.php deleted file mode 100644 index ddb29a5..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/milwaukeenns.php +++ /dev/null @@ -1,14 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://milwaukeenns.org/2016/01/08/united-way-grant-enables-sdc-to-restore-free-tax-assistance-program/', - 'body' => array( - '//div[@class="pf-content"]', - ), - 'strip' => array( - '//div[@class="printfriendly"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/mno.hu.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/mno.hu.php deleted file mode 100644 index a2799b8..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/mno.hu.php +++ /dev/null @@ -1,14 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'https://mno.hu/kulfold/elnokot-valasztanak-szloveniaban-2422840', - 'body' => array( - '//div[@class="header"]/h1', - '//div[@class="content hircikk clearfix"]/p' - ), - 'strip' => array( - ) - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/mokepon.smackjeeves.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/mokepon.smackjeeves.com.php deleted file mode 100644 index 1ddcd40..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/mokepon.smackjeeves.com.php +++ /dev/null @@ -1,10 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://mokepon.smackjeeves.com/comics/2120096/chapter-9-page-68/', - 'body' => array('//*[@id="comic_area_inner"]/img | //*[@id="comic_area_inner"]/a/img'), - 'strip' => array(), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/monandroid.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/monandroid.com.php deleted file mode 100644 index f87560e..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/monandroid.com.php +++ /dev/null @@ -1,13 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.monandroid.com/blog/tutoriel-avance-activer-le-stockage-fusionne-sur-android-6-marshamallow-t12.html', - 'body' => array( - '//div[@class="blog-post-body"]', - ), - 'strip' => array( - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/monwindows.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/monwindows.com.php deleted file mode 100644 index b2b24d7..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/monwindows.com.php +++ /dev/null @@ -1,13 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.monwindows.com/tout-savoir-sur-le-centre-d-action-de-windows-phone-8-1-t40574.html', - 'body' => array( - '//div[@class="blog-post-body"]', - ), - 'strip' => array( - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/moya-planeta.ru.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/moya-planeta.ru.php deleted file mode 100644 index dd84284..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/moya-planeta.ru.php +++ /dev/null @@ -1,21 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.moya-planeta.ru/travel/view/chto_yaponcu_horosho_russkomu_ne_ponyat_20432/', - 'body' => array( - '//div[@class="full_object"]', - ), - 'strip' => array( - '//div[@class="full_object_panel object_panel"]', - '//div[@class="full_object_panel_geo object_panel"]', - '//div[@class="full_object_title"]', - '//div[@class="full_object_social_likes"]', - '//div[@class="full_object_planeta_likes"]', - '//div[@class="full_object_go2comments"]', - '//div[@id="yandex_ad_R-163191-3"]', - '//div[@class="full_object_shop_article_recommend"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/mrlovenstein.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/mrlovenstein.com.php deleted file mode 100644 index b971091..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/mrlovenstein.com.php +++ /dev/null @@ -1,9 +0,0 @@ - array( - '%.*%' => array( - '%alt="(.+)" */>%' => '/>
$1', - '%\.png%' => '_rollover.png', - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/muckrock.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/muckrock.com.php deleted file mode 100644 index 9e354a3..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/muckrock.com.php +++ /dev/null @@ -1,20 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'https://www.muckrock.com/news/archives/2016/jan/13/5-concerns-private-prisons/', - 'body' => array( - '//div[@class="content"]', - ), - 'strip' => array( - '//div[@class="newsletter-widget"]', - '//div[@class="contributors"]', - '//time', - '//h1', - '//div[@class="secondary"]', - '//aside', - '//div[@class="articles__related"]' - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/mynorthshorenow.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/mynorthshorenow.com.php deleted file mode 100644 index b630915..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/mynorthshorenow.com.php +++ /dev/null @@ -1,27 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.mynorthshorenow.com/story/news/local/fox-point/2017/04/04/fox-point-building-board-approves-dunwood-commons-project/99875570/', - 'body' => array( - '//div[@itemprop="articleBody"]', - ), - 'strip' => array( - '//h1', - '//iframe', - '//span[@class="mycapture-small-btn mycapture-btn-with-text mycapture-expandable-photo-btn-small js-mycapture-btn-small"]', - '//div[@class="close-wrap"]', - '//div[contains(@class,"ui-video-wrapper")]', - '//div[contains(@class,"media-mob")]', - '//div[contains(@class,"left-mob")]', - '//div[contains(@class,"nerdbox")]', - '//p/span', - '//div[contains(@class,"oembed-asset")]', - '//*[contains(@class,"share")]', - '//div[contains(@class,"gallery-asset")]', - '//div[contains(@class,"oembed-asset")]', - '//div[@class="article-print-url"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/nakedCapitalism.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/nakedCapitalism.php deleted file mode 100644 index ec2d5fd..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/nakedCapitalism.php +++ /dev/null @@ -1,11 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://feedproxy.google.com/~r/NakedCapitalism/~3/JOBxEHxN8ZI/mark-blyth-liberalism-undermined-democracy-failure-democratic-party.html', - 'body' => array( - '//div[@class="pf-content"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/nasa.gov.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/nasa.gov.php deleted file mode 100644 index c6692d0..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/nasa.gov.php +++ /dev/null @@ -1,14 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'https://www.nasa.gov/image-feature/jpl/pia20514/coy-dione', - 'body' => array( - '//div[@class="article-body"]', - ), - 'strip' => array( - '//div[@class="title-bar"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/nat-geo.ru.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/nat-geo.ru.php deleted file mode 100644 index 1a42d99..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/nat-geo.ru.php +++ /dev/null @@ -1,11 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.nat-geo.ru/fact/868093-knidos-antichnyy-naukograd/', - 'body' => array( - '//div[@class="article-inner-text"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/nationaljournal.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/nationaljournal.com.php deleted file mode 100644 index 5e612be..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/nationaljournal.com.php +++ /dev/null @@ -1,15 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.nationaljournal.com/s/354962/south-carolina-evangelicals-outstrip-establishment?mref=home_top_main', - 'body' => array( - '//div[@class="section-body"]', - ), - 'strip' => array( - '//*[contains(@class, "-related")]', - '//*[contains(@class, "social")]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/nature.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/nature.com.php deleted file mode 100644 index 6b9e87f..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/nature.com.php +++ /dev/null @@ -1,13 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.nature.com/doifinder/10.1038/nature.2015.18340', - 'body' => array( - '//div[contains(@class,"main-content")]', - ), - 'strip' => array(), - ), - ), -); - diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/nba.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/nba.com.php deleted file mode 100644 index c8ea926..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/nba.com.php +++ /dev/null @@ -1,15 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.nba.com/2015/news/09/25/knicks-jackson-to-spend-more-time-around-coaching-staff.ap/index.html?rss=true', - 'body' => array( - '//div[@class="paragraphs"]', - ), - 'strip' => array( - '//div[@id="nbaArticleSocialWrapper_bot"]', - '//h5', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/nedroid.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/nedroid.com.php deleted file mode 100644 index 3214c62..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/nedroid.com.php +++ /dev/null @@ -1,8 +0,0 @@ - array( - '%.*%' => array( - '%title="(.+)" */>%' => '/>
$1', - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/networkworld.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/networkworld.com.php deleted file mode 100644 index 1852435..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/networkworld.com.php +++ /dev/null @@ -1,20 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.networkworld.com/article/3020585/security/the-incident-response-fab-five.html', - 'body' => array( - '//figure/img[@class="hero-img"]', - '//section[@class="deck"]', - '//div[@itemprop="articleBody"] | //div[@itemprop="reviewBody"]', - '//div[@class="carousel-inside-crop"]', - ), - 'strip' => array( - '//script', - '//aside', - '//div[@class="credit"]', - '//div[@class="view-large"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/neustadt-ticker.de.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/neustadt-ticker.de.php deleted file mode 100644 index e0c0d19..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/neustadt-ticker.de.php +++ /dev/null @@ -1,15 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.neustadt-ticker.de/41302/alltag/kultur/demo-auf-der-boehmischen', - 'body' => array( - '//div[@class="entry-content"]', - ), - 'strip' => array( - '//*[contains(@class, "sharedaddy")]', - '//*[contains(@class, "yarpp-related")]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/nextinpact.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/nextinpact.com.php deleted file mode 100644 index 29dd9d6..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/nextinpact.com.php +++ /dev/null @@ -1,18 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.nextinpact.com/news/101122-3d-nand-intel-lance-six-nouvelles-gammes-ssd-pour-tous-usages.htm', - 'body' => array( - '//div[@class="container_article"]', - ), - 'strip' => array( - '//div[@class="infos_article"]', - '//div[@id="actu_auteur"]', - '//div[@id="soutenir_journaliste"]', - '//section[@id="bandeau_abonnez_vous"]', - '//br' - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/niceteethcomic.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/niceteethcomic.com.php deleted file mode 100644 index f41e443..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/niceteethcomic.com.php +++ /dev/null @@ -1,10 +0,0 @@ - array( - '%/archives.*%' => array( - 'test_url' => 'http://niceteethcomic.com/archives/page119/', - 'body' => array('//*[@class="comicpane"]/a/img'), - 'strip' => array(), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/nichtlustig.de.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/nichtlustig.de.php deleted file mode 100644 index 4d083f9..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/nichtlustig.de.php +++ /dev/null @@ -1,8 +0,0 @@ - array( - '%.*%' => array( - '%.*static.nichtlustig.de/comics/full/(\\d+).*%s' => '', - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/nlcafe.hu.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/nlcafe.hu.php deleted file mode 100644 index b85e6b2..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/nlcafe.hu.php +++ /dev/null @@ -1,18 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.nlcafe.hu/ezvan/20171021/nyugdijas-drogdilert-fogtak-a-ferencvarosi-rendorok/', - 'body' => array( - '//div[@class="single-title"]', - '//div[@class="single-excerpt"]', - '//div[@class="single-post-container-content"]/p', - '//div[@class="single-post-container-content"]/div' - ), - 'strip' => array( - '//div[@class="widget-container related-articles bigdata-widget related-full"]', - '//div[@class="banner-container clear-banner-row clearfix"]' - ) - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/novo-argumente.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/novo-argumente.com.php deleted file mode 100644 index cef3595..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/novo-argumente.com.php +++ /dev/null @@ -1,16 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'https://www.novo-argumente.com/artikel/der_kampf_gegen_die_schlafkrankheit', - 'body' => array( - '//main/div/article', - ), - 'strip' => array( - '//*[@class="artikel-datum"]', - '//*[@class="artikel-titel"]', - '//*[@class="artikel-autor"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/oglaf.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/oglaf.com.php deleted file mode 100644 index 8b2b5b6..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/oglaf.com.php +++ /dev/null @@ -1,19 +0,0 @@ - array( - '%.*%' => array( - 'body' => array( - '//img[@id="strip"]', - '//a/div[@id="nx"]/..', - ), - 'strip' => array(), - 'test_url' => 'http://oglaf.com/slodging/', - ), - ), - 'filter' => array( - '%.*%' => array( - '%alt="(.+)" title="(.+)" */>%' => '/>
$1
$2
', - '%%' => 'Next page', - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/onhax.net.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/onhax.net.php deleted file mode 100644 index 213849d..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/onhax.net.php +++ /dev/null @@ -1,15 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://onhax.net/process-lasso-8-9-1-4-pro-key-portable-is-here-latest', - 'body' => array( - '//div[@class="postcontent"]', - ), - 'strip' => array( - '//*[@class="sharedaddy sd-sharing-enabled"]', - '//*[@class="yarpp-related"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/onlinekosten.de.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/onlinekosten.de.php deleted file mode 100644 index 7382612..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/onlinekosten.de.php +++ /dev/null @@ -1,13 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'https://www.onlinekosten.de/news/android-8-0-die-neuen-features-im-ueberblick_209619.html?utm_source=rss&utm_medium=feed&utm_campaign=android-8-0-die-neuen-features-im-ueberblick', - 'body' => array( - '//p[@class="cms-widget_article_lead"]', - '//img[@class="bec_img"]', - '//div[@class="cms-widget_article_body"]', - ), - ) - ) -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/onmilwaukee.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/onmilwaukee.php deleted file mode 100644 index f66ac4b..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/onmilwaukee.php +++ /dev/null @@ -1,24 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://onmilwaukee.com/movies/articles/downerspelunking.html', - 'body' => array( - '//article[contains(@class, "show")]', - ), - 'strip' => array( - '//h1', - '//div[contains(@class,"-ad")]', - '//div[contains(@class,"_ad")]', - '//div[@id="pub_wrapper"]', - '//div[contains(@class,"share_tools")]', - '//div[@class="clearfix"]', - '//div[contains(@class,"image_control")]', - '//section[@class="ribboned"]', - '//div[contains(@class,"sidebar")]', - '//aside[@class="article_tag_list"]', - '//section[contains(@id,"more_posts")]' - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/openculture.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/openculture.com.php deleted file mode 100644 index 84f2bee..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/openculture.com.php +++ /dev/null @@ -1,11 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.openculture.com/2017/03/are-we-living-inside-a-computer-simulation-watch-the-simulation-argument.html', - 'body' => array( - '//div[@class="entry"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/opennet.ru.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/opennet.ru.php deleted file mode 100644 index 1fb7722..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/opennet.ru.php +++ /dev/null @@ -1,13 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'https://www.opennet.ru/opennews/art.shtml?num=46549', - 'body' => array( - '//*[@id="r_memo"]', - ), - 'strip' => array( - ), - ) - ) -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/openrightsgroup.org.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/openrightsgroup.org.php deleted file mode 100644 index 94139a7..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/openrightsgroup.org.php +++ /dev/null @@ -1,20 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'https://www.openrightsgroup.org/blog/2014/3-days-to-go-till-orgcon2014', - 'body' => array( - '//div[contains(@class, "content")]/div', - ), - 'strip' => array( - '//h2[1]', - '//div[@class="info"]', - '//div[@class="tags"]', - '//div[@class="comments"]', - '//div[@class="breadcrumbs"]', - '//h1[@class="pageTitle"]', - '//p[@class="bookmarkThis"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/opensource.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/opensource.com.php deleted file mode 100644 index 60f3577..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/opensource.com.php +++ /dev/null @@ -1,22 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://opensource.com/life/15/10/how-internet-things-will-change-way-we-think', - 'body' => array( - '//div[@id="article-template"]', - ), - 'strip' => array( - '//div[contains(@class,"os-article__sidebar")]', - '//div[@class="panel-pane pane-node-title"]', - '//div[@class="panel-pane pane-os-article-byline"]', - '//ul', - '//div[contains(@class,"-license")]', - '//div[contains(@class,"-tags")]', - '//div[@class="panel-pane pane-os-article-byline"]', - '//div[@class="os-article__content-below"]', - '//div[@id="comments"]' - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/optipess.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/optipess.com.php deleted file mode 100644 index 3214c62..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/optipess.com.php +++ /dev/null @@ -1,8 +0,0 @@ - array( - '%.*%' => array( - '%title="(.+)" */>%' => '/>
$1', - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/origo.hu.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/origo.hu.php deleted file mode 100644 index 7bd9496..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/origo.hu.php +++ /dev/null @@ -1,14 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.origo.hu/itthon/20171019-hamisan-tanuskodott-az-ugyved-ezert-nem-praktizalhat.html', - 'body' => array( - '//header[@id="article-head"]/h1', - '//article[@id="article-center"]' - ), - 'strip' => array( - ) - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/osnews.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/osnews.com.php deleted file mode 100644 index 1d1396c..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/osnews.com.php +++ /dev/null @@ -1,11 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://osnews.com/story/28863/Google_said_to_be_under_US_antitrust_scrutiny_over_Android', - 'body' => array( - '//div[@class="newscontent1"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/pastebin.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/pastebin.com.php deleted file mode 100644 index b20bf41..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/pastebin.com.php +++ /dev/null @@ -1,13 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://pastebin.com/ed1pP9Ak', - 'body' => array( - '//div[@class="text"]', - ), - 'strip' => array( - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/pcgameshardware.de.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/pcgameshardware.de.php deleted file mode 100644 index f180aee..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/pcgameshardware.de.php +++ /dev/null @@ -1,16 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.pcgameshardware.de/Dragon-Age-Thema-259929/News/Plaene-fuer-Teil-4-und-5-der-Serie-1235682/', - 'body' => array( - '//p[@class="introText"]', - '//figure[contains(@class, "articleBigTeaser")]', - '//div[@id="articleTextBody"]//p | //div[@id="articleTextBody"]//h2[@class="anchorHeadline"]', - ), - 'strip' => array( - '//p[@class="introText"]//time', - ) - ) - ) -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/peebleslab.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/peebleslab.com.php deleted file mode 100644 index ce4891d..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/peebleslab.com.php +++ /dev/null @@ -1,9 +0,0 @@ - array( - '%.*%' => array( - // the extra space is required to strip the title cleanly - '%title="(.+) " */>%' => '/>
$1', - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/penny-arcade.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/penny-arcade.com.php deleted file mode 100644 index dd39983..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/penny-arcade.com.php +++ /dev/null @@ -1,21 +0,0 @@ - array( - '%/news/.*%' => array( - 'test_url' => 'http://penny-arcade.com/news/post/2015/04/15/101-part-two', - 'body' => array( - '//*[@class="postBody"]/*', - ), - 'strip' => array( - ), - ), - '%/comic/.*%' => array( - 'test_url' => 'http://penny-arcade.com/comic/2015/04/15', - 'body' => array( - '//*[@id="comicFrame"]/a/img', - ), - 'strip' => array( - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/pixelbeat.org.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/pixelbeat.org.php deleted file mode 100644 index fa9052e..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/pixelbeat.org.php +++ /dev/null @@ -1,12 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.pixelbeat.org/programming/sigpipe_handling.html#1425573246', - 'body' => array( - '//div[@class="contentText"]', - ), - 'strip' => array(), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/plus.google.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/plus.google.com.php deleted file mode 100644 index 5e48a6c..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/plus.google.com.php +++ /dev/null @@ -1,11 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'https://plus.google.com/+LarryPage/posts/Lh8SKC6sED1', - 'body' => array( - '//div[@role="article"]/div[contains(@class, "eE")]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/popstrip.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/popstrip.com.php deleted file mode 100644 index 801a281..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/popstrip.com.php +++ /dev/null @@ -1,8 +0,0 @@ - array( - '%.*%' => array( - '%( '$1$2$1bonus.png"/>', - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/portfolio.hu.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/portfolio.hu.php deleted file mode 100644 index ad01dad..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/portfolio.hu.php +++ /dev/null @@ -1,15 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.portfolio.hu/gazdasag/mennybe-vagy-pokolba-megy-ma-a-cseh-trump.265833.html', - 'body' => array( - '//div[@id="cikk"]/h1', - '//div[@class="smscontent"]' - ), - 'strip' => array( - '//div[@class="traderhirdetes ga_viewanalytics"]' - ) - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/pro-linux.de.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/pro-linux.de.php deleted file mode 100644 index bc76630..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/pro-linux.de.php +++ /dev/null @@ -1,16 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'https://www.pro-linux.de/news/1/25252/chrome-62-erschienen.html', - 'body' => array( - '//div[@id="news"]', - ), - 'strip' => array( - '//h3[@class="topic"]', - '//h2[@class="title"]', - '//div[@class="picto"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/publicpolicyforum.org.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/publicpolicyforum.org.php deleted file mode 100644 index 5dc8be8..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/publicpolicyforum.org.php +++ /dev/null @@ -1,15 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'https://publicpolicyforum.org/blog/going-extra-mile', - 'body' => array( - '//div[contains(@class,"field-name-post-date")]', - '//div[contains(@class,"field-name-body")]', - ), - 'strip' => array( - '//img[@src="http://publicpolicyforum.org/sites/default/files/logo3.jpg"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/publy.ru.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/publy.ru.php deleted file mode 100644 index bcfeeb9..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/publy.ru.php +++ /dev/null @@ -1,24 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.publy.ru/post/19988', - 'body' => array( - '//div[@class="singlepost"]', - ), - 'strip' => array( - '//script', - '//form', - '//style', - '//*[@class="featured"]', - '//*[@class="toc_white no_bullets"]', - '//*[@class="toc_title"]', - '//*[@class="pba"]', - '//*[@class="comments"]', - '//*[contains(@class, "g-single")]', - '//*[@class="ts-fab-wrapper"]', - '//*[contains(@class, "wp_rp_wrap")]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/putaindecode.fr.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/putaindecode.fr.php deleted file mode 100644 index 9fa5568..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/putaindecode.fr.php +++ /dev/null @@ -1,16 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://putaindecode.fr/posts/js/etat-lieux-js-modulaire-front/', - 'body' => array( - '//*[@class="putainde-Post-md"]', - ), - 'strip' => array( - '//*[contains(@class, "inlineimg")]', - '//*[contains(@class, "comment-respond")]', - '//header', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/recode.net.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/recode.net.php deleted file mode 100644 index 343cd12..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/recode.net.php +++ /dev/null @@ -1,20 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://recode.net/2015/09/26/big-tech-rolls-out-red-carpet-for-indian-prime-minister-lobbies-behind-closed-doors/', - 'body' => array( - '//img[contains(@class,"attachment-large")]', - '//div[contains(@class,"postarea")]', - '//li[@class,"author"]', - ), - 'strip' => array( - '//script', - '//div[contains(@class,"sharedaddy")]', - '//div[@class="post-send-off"]', - '//div[@class="large-12 columns"]', - '//div[contains(@class,"inner-related-article")]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/retractionwatch.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/retractionwatch.com.php deleted file mode 100644 index b97c73e..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/retractionwatch.com.php +++ /dev/null @@ -1,18 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://retractionwatch.com/2015/11/12/psychologist-jens-forster-settles-case-by-agreeing-to-2-retractions/', - 'body' => array( - '//*[@class="main"]', - '//*[@class="entry-content"]', - ), - 'strip' => array( - '//*[contains(@class, "sharedaddy")]', - '//*[contains(@class, "jp-relatedposts")]', - '//p[@class="p1"]', - ) - ) - ) -); - diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/rockpapershotgun.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/rockpapershotgun.com.php deleted file mode 100644 index 7111078..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/rockpapershotgun.com.php +++ /dev/null @@ -1,11 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'https://www.rockpapershotgun.com/2016/08/26/the-divisions-expansions-delayed-to-improve-the-game/', - 'body' => array( - '//div[@class="entry"]', - ) - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/rue89.nouvelobs.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/rue89.nouvelobs.com.php deleted file mode 100644 index cb9116a..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/rue89.nouvelobs.com.php +++ /dev/null @@ -1,13 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://rue89.feedsportal.com/c/33822/f/608948/s/30999fa0/sc/24/l/0L0Srue890N0C20A130C0A80C30A0Cfaisait0Eboris0Eboillon0Eex0Esarko0Eboy0E350A0E0A0A0A0Eeuros0Egare0Enord0E245315/story01.htm', - 'body' => array( - '//*[@id="article"]/div[contains(@class, "content")]', - ), - 'strip' => array( - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/rugbyrama.fr.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/rugbyrama.fr.php deleted file mode 100644 index 9915c23..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/rugbyrama.fr.php +++ /dev/null @@ -1,20 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.rugbyrama.fr/rugby/top-14/2015-2016/top-14-hayman-coupe-du-monde-finale-2012-lutte.-voici-levan-chilachava-toulon_sto5283863/story.shtml', - 'body' => array( - '//div[@class="storyfull__content"]', - ), - 'strip' => array( - '//script', - '//form', - '//style', - '//*[@class="share-buttons"]', - '//*[@class="ad"]', - '//*[@class="hide-desktop"]', - '//*[@id="tracking_img"]', - ) - ) - ) -); \ No newline at end of file diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/salonkolumnisten.com b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/salonkolumnisten.com deleted file mode 100644 index 37f43e9..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/salonkolumnisten.com +++ /dev/null @@ -1,17 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'https://www.salonkolumnisten.com/schulpolitik-niedersachsen/', - 'body' => array( - '//div[@id="main"]/div[contains(@class, "featimg")]', - '//div[@id="main"]/article/div[contains(@class, "entry-content")]', - ), - 'strip' => array( - '//div[@id="main"]/article/div[contains(@class, "entry-content")]/a[1]', - '//div[@id="main"]/article/div[contains(@class, "entry-content")]/a[1]', - ), - ), - ), -); - diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/satwcomic.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/satwcomic.com.php deleted file mode 100644 index d63fc11..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/satwcomic.com.php +++ /dev/null @@ -1,13 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://satwcomic.com/day-at-the-beach', - 'body' => array( - '//div[@class="container"]/center/a/img', - '//span[@itemprop="articleBody"]', - ), - 'strip' => array(), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/science-skeptical.de.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/science-skeptical.de.php deleted file mode 100644 index fcf045f..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/science-skeptical.de.php +++ /dev/null @@ -1,14 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.science-skeptical.de/politik/diesel-die-lueckenmedien-im-glashaus-6/0016080/', - 'body' => array( - '//div[@class="pf-content"]', - ), - 'strip' => array( - '//div[contains(@class, "printfriendly")]', - ) - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/scrumalliance.org.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/scrumalliance.org.php deleted file mode 100644 index 7835fd9..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/scrumalliance.org.php +++ /dev/null @@ -1,12 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'https://www.scrumalliance.org/community/articles/2015/march/an-introduction-to-agile-project-intake?feed=articles', - 'body' => array( - '//div[@class="article_content"]', - ), - 'strip' => array(), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/securityfocus.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/securityfocus.com.php deleted file mode 100644 index 0104514..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/securityfocus.com.php +++ /dev/null @@ -1,17 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.securityfocus.com/archive/1/540139', - 'body' => array( - '//div[@id="vulnerability"]', - '//div[@class="comments_reply"]', - ), - 'strip' => array( - '//span[@class="title"]', - '//div[@id="logo_new"]', - '//div[@id="bannerAd"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/sentfromthemoon.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/sentfromthemoon.com.php deleted file mode 100644 index f435417..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/sentfromthemoon.com.php +++ /dev/null @@ -1,18 +0,0 @@ - array( - '%.*%' => array( - 'body' => array( - '//div[@class="comicpane"]/a/img', - '//div[@class="entry"]', - ), - 'strip' => array(), - 'test_url' => 'http://sentfromthemoon.com/archives/1417', - ), - ), - 'filter' => array( - '%.*%' => array( - '%title="(.+)" */>%' => '/>
$1', - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/sitepoint.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/sitepoint.com.php deleted file mode 100644 index ab0eb7d..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/sitepoint.com.php +++ /dev/null @@ -1,13 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.sitepoint.com/creating-hello-world-app-swift/', - 'body' => array( - '//section[@class="article_body"]', - ), - 'strip' => array( - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/slashdot.org.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/slashdot.org.php deleted file mode 100644 index 89ced8b..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/slashdot.org.php +++ /dev/null @@ -1,11 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://science.slashdot.org/story/15/04/20/0528253/pull-top-can-tabs-at-50-reach-historic-archaeological-status', - 'body' => array( - '//article/div[@class="body"] | //article[@class="layout-article"]/div[@class="elips"]', ), - 'strip' => array(), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/smallhousebliss.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/smallhousebliss.com.php deleted file mode 100644 index 8c13c44..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/smallhousebliss.com.php +++ /dev/null @@ -1,19 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://smallhousebliss.com/2013/08/29/house-g-by-lode-architecture/', - 'body' => array( - '//div[@class="post-content"]', - ), - 'strip' => array( - '//*[contains(@class, "gallery")]', - '//*[contains(@class, "share")]', - '//*[contains(@class, "wpcnt")]', - '//*[contains(@class, "meta")]', - '//*[contains(@class, "postitle")]', - '//*[@id="nav-below"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/smarthomewelt.de.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/smarthomewelt.de.php deleted file mode 100644 index 7463abc..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/smarthomewelt.de.php +++ /dev/null @@ -1,10 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://smarthomewelt.de/apple-tv-amazon-echo-smart-home/', - 'body' => array('//div[@class="entry-inner"]/p | //div[@class="entry-inner"]/div[contains(@class,"wp-caption")]'), - 'strip' => array(), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/smashingmagazine.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/smashingmagazine.com.php deleted file mode 100644 index cbe1072..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/smashingmagazine.com.php +++ /dev/null @@ -1,10 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.smashingmagazine.com/2015/04/17/using-sketch-for-responsive-web-design-case-study/', - 'body' => array('//article[contains(@class,"post")]/p'), - 'strip' => array(), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/smbc-comics.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/smbc-comics.com.php deleted file mode 100644 index 42262dc..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/smbc-comics.com.php +++ /dev/null @@ -1,14 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.smbc-comics.com/comic/the-troll-toll', - 'body' => array( - '//div[@id="cc-comicbody"]', - '//div[@id="aftercomic"]', - ), - 'strip' => array( - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/snopes.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/snopes.com.php deleted file mode 100644 index b0fe655..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/snopes.com.php +++ /dev/null @@ -1,22 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.snopes.com/bacca-brides-on-tour/', - 'body' => array( - '//article', - ), - 'strip' => array( - '//span[@itemprop="author"]', - '//div[contains(@class,"author-")]', - '//h1', - '//style', - '//div[contains(@class,"socialShares")]', - '//div[contains(@class,"ad-unit")]', - '//aside', - '//div[contains(@class,"boomtrain")]', - '//footer' - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/soundandvision.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/soundandvision.com.php deleted file mode 100644 index 6448bb0..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/soundandvision.com.php +++ /dev/null @@ -1,21 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.soundandvision.com/content/james-guthrie-mixing-roger-waters-and-pink-floyd-51', - 'body' => array( - '//div[@id="left"]', - ), - 'strip' => array( - '//div[@class="meta"]', - '//div[@class="ratingsbox"]', - '//h1', - '//h2', - '//addthis', - '//comment-links', - '//div[@class="book-navigation"]', - '//div[@class="comment-links"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/spiegel.de.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/spiegel.de.php deleted file mode 100644 index b42c3aa..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/spiegel.de.php +++ /dev/null @@ -1,14 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.spiegel.de/politik/ausland/afrika-angola-geht-gegen-islam-vor-und-schliesst-moscheen-a-935788.html', - 'body' => array( - '//div[@class="spArticleContent"]/p | //div[@class="spArticleContent"]//img[@class="spResponsiveImage "]', - ), - 'strip' => array( - '//div[@class="author-details"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/stereophile.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/stereophile.com.php deleted file mode 100644 index 8e410be..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/stereophile.com.php +++ /dev/null @@ -1,11 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.stereophile.com/content/2015-rocky-mountain-audio-fest-starts-friday', - 'body' => array( - '//div[@class="content clear-block"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/stupidfox.net.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/stupidfox.net.php deleted file mode 100644 index 61182d7..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/stupidfox.net.php +++ /dev/null @@ -1,13 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://stupidfox.net/134-sleepy-time', - 'body' => array( - '//div[@class="comicmid"]/center/a/img', - '//div[@class="stand_high"]', - ), - 'strip' => array(), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/subtraction.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/subtraction.com.php deleted file mode 100644 index 6d74427..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/subtraction.com.php +++ /dev/null @@ -1,15 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.subtraction.com/2015/06/06/time-lapse-video-of-one-world-trade-center/', - 'body' => array('//article/div[@class="entry-content"]'), - 'strip' => array(), - ), - ), - 'filter' => array( - '%.*%' => array( - '%\+%' => '', - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/sz.de.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/sz.de.php deleted file mode 100644 index 90bde5a..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/sz.de.php +++ /dev/null @@ -1,10 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://sz.de/1.2443161', - 'body' => array('//article[@id="sitecontent"]/section[@class="topenrichment"]//img | //article[@id="sitecontent"]/section[@class="body"]/section[@class="authors"]/preceding-sibling::*[not(contains(@class, "ad"))]'), - 'strip' => array(), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/takprosto.cc.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/takprosto.cc.php deleted file mode 100644 index 624ef90..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/takprosto.cc.php +++ /dev/null @@ -1,21 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://takprosto.cc/kokteyl-dlya-pohudeniya-v-domashnih-usloviyah/', - 'body' => array( - '//div[contains(@class, "entry-contentt")]', - ), - 'strip' => array( - '//script', - '//form', - '//style', - '//*[@class="views_post"]', - '//*[contains(@class, "mailchimp-box")]', - '//*[contains(@class, "essb_links")]', - '//*[contains(@rel, "nofollow")]', - '//*[contains(@class, "ads")]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/techcrunch.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/techcrunch.com.php deleted file mode 100644 index 230b791..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/techcrunch.com.php +++ /dev/null @@ -1,15 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://techcrunch.com/2013/08/31/indias-visa-maze/', - 'body' => array( - '//div[contains(@class, "media-container")]', - '//div[contains(@class, "article-entry")]', - ), - 'strip' => array( - '//*[contains(@class, "module-crunchbase")]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/the-ebook-reader.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/the-ebook-reader.com.php deleted file mode 100644 index 3b01eb9..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/the-ebook-reader.com.php +++ /dev/null @@ -1,15 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://blog.the-ebook-reader.com/2015/09/25/kobo-glo-hd-and-kobo-touch-2-0-covers-and-cases-roundup/', - 'body' => array( - '//div[@class="entry"]', - ), - 'strip' => array( - '//div[@id="share"]', - '//div[contains(@class,"ItemCenter")]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theatlantic.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theatlantic.com.php deleted file mode 100644 index bfad4ab..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theatlantic.com.php +++ /dev/null @@ -1,23 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.theatlantic.com/politics/archive/2015/09/what-does-it-mean-to-lament-the-poor-inside-panem/407317/', - 'body' => array( - '//picture[@class="img"]', - '//figure/figcaption/span', - '//div/p[@itemprop="description"]', - '//div[@class="article-body"]', - '//ul[@class="photos"]', - ), - 'strip' => array( - '//aside[@class="callout"]', - '//span[@class="credit"]', - '//figcaption[@class="credit"]', - '//aside[contains(@class,"partner-box")]', - '//div[contains(@class,"ad")]', - '//a[contains(@class,"social-icon")]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theawkwardyeti.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theawkwardyeti.com.php deleted file mode 100644 index fd4f3d5..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theawkwardyeti.com.php +++ /dev/null @@ -1,12 +0,0 @@ - array( - '%/comic/.*%' => array( - 'test_url' => 'http://theawkwardyeti.com/comic/things-to-do/', - 'body' => array( - '//div[@id="comic"]' - ), - 'strip' => array() - ) - ) -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thecodinglove.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thecodinglove.com.php deleted file mode 100644 index c6ec5bf..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thecodinglove.com.php +++ /dev/null @@ -1,10 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://thecodinglove.com/post/116897934767', - 'body' => array('//div[@class="bodytype"]'), - 'strip' => array(), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thedoghousediaries.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thedoghousediaries.com.php deleted file mode 100644 index d2f840d..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thedoghousediaries.com.php +++ /dev/null @@ -1,18 +0,0 @@ - array( - '%.*%' => array( - 'body' => array( - '//div[@class="comicpane"]/a/img', - '//div[@class="entry"]', - ), - 'strip' => array(), - 'test_url' => 'http://thedoghousediaries.com/6023', - ), - ), - 'filter' => array( - '%.*%' => array( - '%title="(.+)" */>%' => '/>
$1', - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thegamercat.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thegamercat.com.php deleted file mode 100644 index f9b4637..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thegamercat.com.php +++ /dev/null @@ -1,10 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.thegamercat.com/comic/just-no/', - 'body' => array('//div[@id="comic"] | //div[@class="post-content"]/div[@class="entry"]/p'), - 'strip' => array(), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thehindu.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thehindu.com.php deleted file mode 100644 index 1e6735b..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thehindu.com.php +++ /dev/null @@ -1,19 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.thehindu.com/sci-tech/science/why-is-the-shape-of-cells-in-a-honeycomb-always-hexagonal/article7692306.ece?utm_source=RSS_Feed&utm_medium=RSS&utm_campaign=RSS_Syndication', - 'body' => array( - '//div/img[@class="main-image"]', - '//div[@class="photo-caption"]', - '//div[@class="articleLead"]', - '//p', - '//span[@class="upper"]', - ), - 'strip' => array( - '//div[@id="articleKeywords"]', - '//div[@class="photo-source"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thelocal.se.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thelocal.se.php deleted file mode 100644 index c3ec250..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thelocal.se.php +++ /dev/null @@ -1,17 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'www.thelocal.se/20161219/this-swede-can-memorize-hundreds-of-numbers-in-only-five-minutes', - 'body' => array( - '//div[@id="article-photo"]', - '//div[@id="article-description"]', - '//div[@id="article-body"]', - ), - 'strip' => array( - '//div[@id="article-info-middle"]', - ) - ) - ) -); - diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/themerepublic.net.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/themerepublic.net.php deleted file mode 100644 index bc47b27..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/themerepublic.net.php +++ /dev/null @@ -1,10 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.themerepublic.net/2015/04/david-lopez-pitoko.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+blogspot%2FDngUJ+%28Theme+Republic%29&utm_content=FeedBurner', - 'body' => array('//*[@class="post-body"]'), - 'strip' => array(), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/themoscowtimes.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/themoscowtimes.com.php deleted file mode 100644 index 0f5bf75..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/themoscowtimes.com.php +++ /dev/null @@ -1,18 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.themoscowtimes.com/business/article/535500.html', - 'body' => array( - '//div[@class="article_main_img"]', - '//div[@class="article_text"]', - ), - 'strip' => array( - '//div[@class="articlebottom"]', - '//p/b', - '//p/a[contains(@href, "/article.php?id=")]', - '//div[@class="disqus_wrap"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thenewslens.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thenewslens.com.php deleted file mode 100644 index 7538170..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thenewslens.com.php +++ /dev/null @@ -1,21 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://international.thenewslens.com/post/255032/', - 'body' => array( - '//div[@class="article-section"]', - ), - 'strip' => array( - '//div[contains(@class,"ad-")]', - '//div[@class="article-title-box"]', - '//div[@class="function-box"]', - '//p/span', - '//aside', - '//footer', - '//div[@class="article-infoBot-box"]', - '//div[contains(@class,"standard-container")]' - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theodd1sout.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theodd1sout.com.php deleted file mode 100644 index d06ed12..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theodd1sout.com.php +++ /dev/null @@ -1,8 +0,0 @@ - array( - '%.*%' => array( - '%-150x150%' => '', - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theonion.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theonion.com.php deleted file mode 100644 index acbfd36..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theonion.com.php +++ /dev/null @@ -1,12 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.theonion.com/article/wild-eyed-jim-harbaugh-informs-players-they-must-k-51397?utm_medium=RSS&utm_campaign=feeds', - 'body' => array( - '//div[@class="content-masthead"]/figure/div/noscript/img', - '//div[@class="content-text"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theregister.co.uk.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theregister.co.uk.php deleted file mode 100644 index 896365a..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theregister.co.uk.php +++ /dev/null @@ -1,18 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'https://www.theregister.co.uk/2017/10/21/purism_cleanses_laptops_of_intel_management_engine/', - 'body' => array( - '//div[@id="article"]', - ), - 'strip' => array( - '//div[@class="byline_and_share"]', - '//div[@class="social_btns alt_colour dcl"]', - '//div[@class="promo_article"]', - '//div[@id="article_body_btm"]', - '//p[@class="wptl btm"]' - ) - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thestandard.com.hk.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thestandard.com.hk.php deleted file mode 100644 index 1163b34..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/thestandard.com.hk.php +++ /dev/null @@ -1,22 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.thestandard.com.hk/breaking_news_detail.asp?id=67156', - 'body' => array( - '//table/tr/td/span[@class="bodyCopy"]', - ), - 'strip' => array( - '//script', - '//br', - '//map[@name="gif_bar"]', - '//img[contains(@usemap,"gif_bar")]', - '//a', - '//span[@class="bodyHeadline"]', - '//i', - '//b', - '//table', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theverge.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theverge.com.php deleted file mode 100644 index 09e876d..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/theverge.com.php +++ /dev/null @@ -1,16 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'https://www.theverge.com/2017/11/11/16624298/mindhunter-netflix-show-david-fincher-review', - 'body' => array( - '//figure[@class="e-image e-image--hero"]/span[@class="e-image__inner"]', - '//div[@class="c-entry-content"]', - ), - 'strip' => array( - '//div[@class="c-related-list"]', - '//div[@class="c-page-title"]', - ) - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/threepanelsoul.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/threepanelsoul.com.php deleted file mode 100644 index 4af6196..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/threepanelsoul.com.php +++ /dev/null @@ -1,11 +0,0 @@ - array( - '%.*%' => array( - 'body' => array( - '//img[@id="cc-comic"]', - ), - 'test_url' => 'http://www.threepanelsoul.com/comic/uncloaking', - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/tichyseinblick.de.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/tichyseinblick.de.php deleted file mode 100644 index 6fba3df..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/tichyseinblick.de.php +++ /dev/null @@ -1,22 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'https://www.tichyseinblick.de/daili-es-sentials/jamaika-reaktionen-der-enttaeuschten/', - 'body' => array( - '//article' - ), - 'strip' => array( - '//header', - '//footer', - '//div[@class="mod-cad2"]', - '//ul[contains(@class, "social")]', - '//div[@class="rty-pop-up"]', - '//div[@class="pagelink"]', - '//div[@id="reward"]', - '//div[@class="rty-block-plista"]' - ) - ), - ), -); - diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/timesofindia.indiatimes.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/timesofindia.indiatimes.com.php deleted file mode 100644 index 1924680..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/timesofindia.indiatimes.com.php +++ /dev/null @@ -1,14 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://timesofindia.indiatimes.com/city/mangaluru/Adani-UPCL-to-release-CSR-grant-of-Rs-3-74-crore-to-YellurGram-Panchayat/articleshow/50512116.cms', - 'body' => array( - '//div[@class="article_content clearfix"]', - '//section[@class="highlight clearfix"]', - ), - 'strip' => array( - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/totalcar.hu.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/totalcar.hu.php deleted file mode 100644 index f2e009d..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/totalcar.hu.php +++ /dev/null @@ -1,18 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://totalcar.hu/tesztek/2017/10/21/veteran_fiat-abarth_1000tc_1968/', - 'body' => array( - '//div[@class="content-title"]', - '//div[@class="lead-container"]/div[@class="lead"]', - '//div[@class="cikk-torzs"]' - ), - 'strip' => array( - '//span[@class="gallery_title newline"]', - '//div[@class="social-stripe cikk-bottom-box"]', - '//div[@class="cikk-bottom-text-ad"]' - ) - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/tozsdeforum.hu.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/tozsdeforum.hu.php deleted file mode 100644 index 97a0da0..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/tozsdeforum.hu.php +++ /dev/null @@ -1,15 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.tozsdeforum.hu/szemelyes-penzugyek/napi-penzugyek/ezek-a-legnepszerubb-turistacelpontok-voltal-mar-mindenhol-87181.html', - 'body' => array( - '//header/h1', - '//div[@class="title_img"]', - '//article/div[@class="tf-post"]/div[@class="p"]/p|//article/div[@class="tf-post"]/div[@class="p"]/h3|//article/div[@class="tf-post"]/div[@class="p"]/blockquote' - ), - 'strip' => array( - ) - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/travel-dealz.de.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/travel-dealz.de.php deleted file mode 100644 index 4ee4fcd..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/travel-dealz.de.php +++ /dev/null @@ -1,15 +0,0 @@ - array( - '%^/blog.*%' => array( - 'test_url' => 'http://travel-dealz.de/blog/venere-gutschein/', - 'body' => array('//div[@class="post-entry"]'), - 'strip' => array( - '//*[@id="jp-relatedposts"]', - '//*[@class="post-meta"]', - '//*[@class="post-data"]', - '//*[@id="author-meta"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/travelo.hu.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/travelo.hu.php deleted file mode 100644 index 3ab8ca4..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/travelo.hu.php +++ /dev/null @@ -1,17 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://travelo.hu/csaladbarat/2017/10/20/mar_csak_egy_het_es_kezdodik_az_oszi_szunet/', - 'body' => array( - '//div[@id="content"]/h1', - '//div[@id="kopf"]', - '//div[@id="szoveg"]' - ), - 'strip' => array( - '//div[@class="goAdverticum"]', - '//h1[@class="border"]' - ) - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/treehugger.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/treehugger.com.php deleted file mode 100644 index 55eb7e0..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/treehugger.com.php +++ /dev/null @@ -1,14 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.treehugger.com/uncategorized/top-ten-posts-week-bunnies-2.html', - 'body' => array( - '//div[contains(@class, "promo-image")]', - '//div[contains(@id, "entry-body")]', - ), - 'strip' => array( - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/treelobsters.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/treelobsters.com.php deleted file mode 100644 index 3214c62..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/treelobsters.com.php +++ /dev/null @@ -1,8 +0,0 @@ - array( - '%.*%' => array( - '%title="(.+)" */>%' => '/>
$1', - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/tutorialzine.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/tutorialzine.com.php deleted file mode 100644 index 7e39145..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/tutorialzine.com.php +++ /dev/null @@ -1,20 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'https://tutorialzine.com/2017/10/15-interesting-javascript-and-css-libraries-for-october-2017', - 'body' => array( - '//article' - ), - 'strip' => array( - '//div[@class="article__header"]', - '//div[@class="article__share"]', - '//div[@class="article__footer"]', - '//div[@id="article__related-articles"]', - '//div[@class="webappstudio-animation"]', - '//div[@class="ad-container adsbygoogle hidden-xs hidden-sm"]', - '//script' - ) - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/twogag.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/twogag.com.php deleted file mode 100644 index 79f4f62..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/twogag.com.php +++ /dev/null @@ -1,8 +0,0 @@ - array( - '%.*%' => array( - '%http://www.twogag.com/comics-rss/([^.]+)\\.jpg%' => 'http://www.twogag.com/comics/$1.jpg', - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/twokinds.keenspot.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/twokinds.keenspot.com.php deleted file mode 100644 index 3428fcb..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/twokinds.keenspot.com.php +++ /dev/null @@ -1,10 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://twokinds.keenspot.com/archive.php?p=0', - 'body' => array('//*[@class="comic"]/div/a/img | //*[@class="comic"]/div/img | //*[@id="cg_img"]/img | //*[@id="cg_img"]/a/img'), - 'strip' => array(), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/undeadly.org.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/undeadly.org.php deleted file mode 100644 index 8b15900..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/undeadly.org.php +++ /dev/null @@ -1,14 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://undeadly.org/cgi?action=article&sid=20141101181155', - 'body' => array( - '/html/body/table[3]/tbody/tr/td[1]/table[2]/tr/td[1]', - ), - 'strip' => array( - '//font', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/upi.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/upi.com.php deleted file mode 100644 index ec8d1a1..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/upi.com.php +++ /dev/null @@ -1,15 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.upi.com/Top_News/US/2015/09/26/Tech-giants-Hollywood-stars-among-guests-at-state-dinner-for-Chinas-Xi-Jinping/4541443281006/', - 'body' => array( - '//div[@class="img"]', - '//div/article[@itemprop="articleBody"]', - ), - 'strip' => array( - '//div[@align="center"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/usatoday.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/usatoday.com.php deleted file mode 100644 index edd6aa4..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/usatoday.com.php +++ /dev/null @@ -1,27 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.usatoday.com/story/life/music/2017/02/13/things-you-should-know-happened-grammy-awards-2017/97833734/', - 'body' => array( - '//div[@itemprop="articleBody"]', - ), - 'strip' => array( - '//script', - '//h1', - '//iframe', - '//span[@class="mycapture-small-btn mycapture-btn-with-text mycapture-expandable-photo-btn-small js-mycapture-btn-small"]', - '//div[@class="close-wrap"]', - '//div[contains(@class,"ui-video-wrapper")]', - '//div[contains(@class,"media-mob")]', - '//div[contains(@class,"left-mob")]', - '//div[contains(@class,"nerdbox")]', - '//div[contains(@class,"oembed-asset")]', - '//*[contains(@class,"share")]', - '//div[contains(@class,"gallery-asset")]', - '//div[contains(@class,"oembed-asset")]', - '//div[@class="article-print-url"]' - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/version2.dk.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/version2.dk.php deleted file mode 100644 index a6d49f2..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/version2.dk.php +++ /dev/null @@ -1,12 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.version2.dk/artikel/surface-pro-2-fungerer-bedre-til-arbejde-end-fornoejelse-55195', - 'body' => array( - '//section[contains(@class, "teaser")]', - '//section[contains(@class, "body")]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/vezess.hu.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/vezess.hu.php deleted file mode 100644 index acd68c0..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/vezess.hu.php +++ /dev/null @@ -1,20 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.vezess.hu/hirek/2017/10/20/audi-a7-2018-bemutato/', - 'body' => array( - '//article[@id="news"]/h1', - '//article[@id="news"]/h2', - '//article[@id="news"]/p[@class="lead"]', - '//article[@id="news"]/p[@class="main-pic responsive-img-container"]', - '//div[@class="article-body"]' - ), - 'strip' => array( - '//div[@class="info-bar"]', - '//ul[@class="breadcrumb"]', - '//div[@class="embed-link ce_widget"]' - ) - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/vgcats.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/vgcats.com.php deleted file mode 100644 index b2830a3..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/vgcats.com.php +++ /dev/null @@ -1,15 +0,0 @@ - array( - '%/comics.*%' => array( - 'test_url' => 'http://www.vgcats.com/comics/?strip_id=358', - 'body' => array('//*[@align="center"]/img'), - 'strip' => array(), - ), - '%/super.*%' => array( - 'test_url' => 'http://www.vgcats.com/super/?strip_id=84', - 'body' => array('//*[@align="center"]/p/img'), - 'strip' => array(), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/vuxml.org.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/vuxml.org.php deleted file mode 100644 index b9bef7a..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/vuxml.org.php +++ /dev/null @@ -1,17 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.vuxml.org/freebsd/a5f160fa-deee-11e4-99f8-080027ef73ec.html', - 'body' => array( - '//body', - ), - 'strip' => array( - '//h1', - '//div[@class="blurb"]', - '//hr', - '//p[@class="copyright"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/wausaudailyherald.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/wausaudailyherald.com.php deleted file mode 100644 index 58aceea..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/wausaudailyherald.com.php +++ /dev/null @@ -1,27 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.wausaudailyherald.com/story/news/2017/04/01/hundreds-gather-remember-attorney-killed-shooting-spree/99826062/?from=global&sessionKey=&autologin=', - 'body' => array( - '//div[@itemprop="articleBody"]', - ), - 'strip' => array( - '//h1', - '//iframe', - '//span[@class="mycapture-small-btn mycapture-btn-with-text mycapture-expandable-photo-btn-small js-mycapture-btn-small"]', - '//div[@class="close-wrap"]', - '//div[contains(@class,"ui-video-wrapper")]', - '//div[contains(@class,"media-mob")]', - '//div[contains(@class,"left-mob")]', - '//div[contains(@class,"nerdbox")]', - '//p/span', - '//div[contains(@class,"oembed-asset")]', - '//*[contains(@class,"share")]', - '//div[contains(@class,"gallery-asset")]', - '//div[contains(@class,"oembed-asset")]', - '//div[@class="article-print-url"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/welt.de.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/welt.de.php deleted file mode 100644 index 83a2ebe..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/welt.de.php +++ /dev/null @@ -1,20 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'https://www.welt.de/debatte/kommentare/article169740590/Bloss-keine-sozialdemokratische-Konsenssause.html', - 'body' => array( - '//main/article/header/div/div[contains(@class, "c-summary")]/div', - '//main/article/header/div[3]/div/figure/div/div/div/picture[1]', - '//main/article/header/div[3]/div/figure/figcaption/child::*', - '//main/article/div[contains(@class, "c-article-text")]' - ), - 'strip' => array( - '//*[contains(@class, "c-inline-element--has-commercials")]', - '//*[contains(@class, "c-inline-teaser")]', - '//figure[contains(@class, "c-video-element")]', - '//main/article/div[contains(@class, "c-article-text")]/div[@class="c-inline-element"]/div[contains(@class, "c-image-element")]' - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/westfalen-blatt.de.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/westfalen-blatt.de.php deleted file mode 100644 index adcf417..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/westfalen-blatt.de.php +++ /dev/null @@ -1,16 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.westfalen-blatt.de/OWL/Lokales/Kreis-Hoexter/Warburg/3024113-Polizei-in-Warburg-Hier-waren-keine-kriminellen-Profis-am-Werk-Wurstautomat-Sprengung-mit-Polen-Boellern', - 'body' => array( - '//div[contains(@class, "articleimage")]', - '//div[@class="attribute-short"]', - '//div[@class="attribute-long"]', - ), - 'strip' => array( - '//div[@class="fb-post"]' - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.bbc.co.uk.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.bbc.co.uk.php deleted file mode 100644 index 98fc368..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.bbc.co.uk.php +++ /dev/null @@ -1,33 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.bbc.co.uk/news/world-middle-east-23911833', - 'body' => array( - '//div[@class="story-body__inner"] | //div[@class="article"]', - '//div[@class="indPost"]', - ), - 'strip' => array( - '//form', - '//div[@id="headline"]', - '//*[@class="warning"]', - '//span[@class="off-screen"]', - '//span[@class="story-image-copyright"]', - '//ul[@class="story-body__unordered-list"]', - '//div[@class="ad_wrapper"]', - '//div[@id="article-sidebar"]', - '//div[@class="data-table-outer"]', - '//*[@class="story-date"]', - '//*[@class="story-header"]', - '//figure[contains(@class,"has-caption")]', - '//*[@class="story-related"]', - '//*[contains(@class, "byline")]', - '//p[contains(@class, "media-message")]', - '//*[contains(@class, "story-feature")]', - '//*[@id="video-carousel-container"]', - '//*[@id="also-related-links"]', - '//*[contains(@class, "share") or contains(@class, "hidden") or contains(@class, "hyper")]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.bdgest.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.bdgest.com.php deleted file mode 100644 index 41ef68d..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.bdgest.com.php +++ /dev/null @@ -1,15 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.bdgest.com/chronique-6027-BD-Adrastee-Tome-2.html', - 'body' => array( - '//*[contains(@class, "chronique")]', - ), - 'strip' => array( - '//*[contains(@class, "post-review")]', - '//*[contains(@class, "footer-review")]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.bgr.in.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.bgr.in.php deleted file mode 100644 index 63ca069..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.bgr.in.php +++ /dev/null @@ -1,23 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.bgr.in/news/xiaomi-redmi-3-with-13-megapixel-camera-snapdragon-616-launched-price-specifications-and-features/', - 'body' => array( - '//div[@class="article-content"]', - ), - 'strip' => array( - '//*[@class="article-meta"]', - '//*[@class="contentAdsense300"]', - '//*[@class="iwpl-social-hide"]', - '//iframe[@class="iframeads"]', - '//*[@class="disqus_thread"]', - '//*[@class="outb-mobile OUTBRAIN"]', - '//*[@class="wdt_smart_alerts"]', - '//*[@class="footnote"]', - '//*[@id="gadget-widget"]', - '//header[@class="article-title entry-header"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.businessweek.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.businessweek.com.php deleted file mode 100644 index 0acc44e..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.businessweek.com.php +++ /dev/null @@ -1,15 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.businessweek.com/articles/2013-09-18/elon-musks-hyperloop-will-work-says-some-very-smart-software', - 'body' => array( - '//div[@id="lead_graphic"]', - '//div[@id="article_body"]', - ), - 'strip' => array( - '//*[contains(@class, "related_item")]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.cnn.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.cnn.com.php deleted file mode 100644 index 31d03ed..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.cnn.com.php +++ /dev/null @@ -1,24 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.cnn.com/2013/08/31/world/meast/syria-civil-war/index.html?hpt=hp_t1', - 'body' => array( - '//div[@class="cnn_strycntntlft"]', - ), - 'strip' => array( - '//div[@class="cnn_stryshrwdgtbtm"]', - '//div[@class="cnn_strybtmcntnt"]', - '//div[@class="cnn_strylftcntnt"]', - '//div[contains(@class, "cnnGalleryContainer")]', - '//div[contains(@class, "cnn_strylftcexpbx")]', - '//div[contains(@class, "articleGalleryNavContainer")]', - '//div[contains(@class, "cnnArticleGalleryCaptionControl")]', - '//div[contains(@class, "cnnArticleGalleryNavPrevNextDisabled")]', - '//div[contains(@class, "cnnArticleGalleryNavPrevNext")]', - '//div[contains(@class, "cnn_html_media_title_new")]', - '//div[contains(@id, "disqus")]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.developpez.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.developpez.com.php deleted file mode 100644 index 1535e43..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.developpez.com.php +++ /dev/null @@ -1,21 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.developpez.com/actu/81757/Mozilla-annonce-la-disponibilite-de-Firefox-36-qui-passe-au-HTTP-2-et-permet-la-synchronisation-de-son-ecran-d-accueil/', - 'body' => array( - '//*[@itemprop="articleBody"]', - ), - 'strip' => array( - '//form', - '//div[@class="content"]/img', - '//a[last()]/following-sibling::*', - '//*[contains(@class,"actuTitle")]', - '//*[contains(@class,"date")]', - '//*[contains(@class,"inlineimg")]', - '//*[@id="signaler"]', - '//*[@id="signalerFrame"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.egscomics.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.egscomics.com.php deleted file mode 100644 index 263f075..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.egscomics.com.php +++ /dev/null @@ -1,12 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.egscomics.com/index.php?id=1690', - 'title' => '/html/head/title', - 'body' => array( - '//img[@id="comic"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.fakingnews.firstpost.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.fakingnews.firstpost.com.php deleted file mode 100644 index c948c77..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.fakingnews.firstpost.com.php +++ /dev/null @@ -1,17 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.fakingnews.firstpost.com/2016/01/engineering-student-creates-record-in-a-decade-becomes-the-first-to-completely-exhaust-ball-pen-refill/', - 'body' => array( - '//div[@class="entry"]', - ), - 'strip' => array( - '//*[@class="socialshare_bar"]', - '//*[@class="authorbox"]', - '//*[@class="cf5_rps"]', - '//*[@class="60563 fb-comments fb-social-plugin"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.forbes.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.forbes.com.php deleted file mode 100644 index fd16ed5..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.forbes.com.php +++ /dev/null @@ -1,20 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.forbes.com/sites/andygreenberg/2013/09/05/follow-the-bitcoins-how-we-got-busted-buying-drugs-on-silk-roads-black-market/', - 'body' => array( - '//div[@id="leftRail"]/div[contains(@class, body)]', - ), - 'strip' => array( - '//aside', - '//div[contains(@class, "entity_block")]', - '//div[contains(@class, "vestpocket") and not contains(@class, "body")]', - '//div[contains(@style, "display")]', - '//div[contains(@id, "comment")]', - '//div[contains(@class, "widget")]', - '//div[contains(@class, "pagination")]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.franceculture.fr.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.franceculture.fr.php deleted file mode 100644 index f7ec0d8..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.franceculture.fr.php +++ /dev/null @@ -1,14 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.franceculture.fr/emission-culture-eco-la-finance-aime-toujours-la-france-2016-01-08', - 'body' => array( - '//div[@class="text-zone"]', - ), - 'strip' => array( - '//ul[@class="tags"]', - ), - ) - ) -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.futura-sciences.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.futura-sciences.com.php deleted file mode 100644 index ea94a0f..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.futura-sciences.com.php +++ /dev/null @@ -1,19 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.futura-sciences.com/magazines/espace/infos/actu/d/astronautique-curiosity-franchi-succes-dune-dingo-gap-52289/#xtor=RSS-8', - 'body' => array( - '//div[contains(@class, "content fiche-")]', - ), - 'strip' => array( - '//h1', - '//*[contains(@class, "content-date")]', - '//*[contains(@class, "diaporama")]', - '//*[contains(@class, "slider")]', - '//*[contains(@class, "cartouche")]', - '//*[contains(@class, "noprint")]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.geekculture.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.geekculture.com.php deleted file mode 100644 index 3d0b6c7..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.geekculture.com.php +++ /dev/null @@ -1,13 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.geekculture.com/joyoftech/joyarchives/2180.html', - 'body' => array( - '//p[contains(@class,"Maintext")][2]/a/img[contains(@src,"joyimages")]', - ), - 'strip' => array(), - ), - ), -); - diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.howtogeek.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.howtogeek.com.php deleted file mode 100644 index 6879e76..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.howtogeek.com.php +++ /dev/null @@ -1,14 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.howtogeek.com/235283/what-is-a-wireless-hard-drive-and-should-i-get-one/', - 'body' => array( - '//div[@class="thecontent"]', - ), - 'strip' => array( - '//*[@class="relatedside"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.lepoint.fr.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.lepoint.fr.php deleted file mode 100644 index dcb7e48..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.lepoint.fr.php +++ /dev/null @@ -1,18 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.lepoint.fr/c-est-arrive-aujourd-hui/19-septembre-1783-pour-la-premiere-fois-un-mouton-un-canard-et-un-coq-s-envoient-en-l-air-devant-louis-xvi-18-09-2012-1507704_494.php', - 'body' => array( - '//article', - ), - 'strip' => array( - '//*[contains(@class, "info_article")]', - '//*[contains(@class, "fildariane_titre")]', - '//*[contains(@class, "entete2_article")]', - '//*[contains(@class, "signature_article")]', - '//*[contains(@id, "share")]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.lesnumeriques.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.lesnumeriques.com.php deleted file mode 100644 index 0137e20..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.lesnumeriques.com.php +++ /dev/null @@ -1,25 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.lesnumeriques.com/blender/kitchenaid-diamond-5ksb1585-p27473/test.html', - 'body' => array( - '//*[@id="product-content"]', - '//*[@id="news-content"]', - '//*[@id="article-content"]', - ), - 'strip' => array( - '//form', - '//div[contains(@class, "price-v4"])', - '//div[contains(@class, "authors-and-date")]', - '//div[contains(@class, "mini-product")]', - '//div[@id="articles-related-authors"]', - '//div[@id="tags-socials"]', - '//div[@id="user-reviews"]', - '//div[@id="product-reviews"]', - '//div[@id="publication-breadcrumbs-and-date"]', - '//div[@id="publication-breadcrumbs-and-date"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.mac4ever.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.mac4ever.com.php deleted file mode 100644 index 60bc1bd..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.mac4ever.com.php +++ /dev/null @@ -1,13 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.mac4ever.com/actu/87392_video-quand-steve-jobs-et-bill-gates-jouaient-au-bachelor-avec-le-mac', - 'body' => array( - '//div[contains(@class, "news-news-content")]', - ), - 'strip' => array( - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.makeuseof.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.makeuseof.com.php deleted file mode 100644 index a274564..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.makeuseof.com.php +++ /dev/null @@ -1,18 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.makeuseof.com/tag/having-problems-with-audio-in-windows-10-heres-a-likely-fix/', - 'body' => array( - '//div[@class="entry"]', - ), - 'strip' => array( - '//*[@class="new_sharebar"]', - '//*[@class="author"]', - '//*[@class="wdt_grouvi"]', - '//*[@class="wdt_smart_alerts"]', - '//*[@class="modal fade grouvi"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.monsieur-le-chien.fr.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.monsieur-le-chien.fr.php deleted file mode 100644 index 5f5e987..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.monsieur-le-chien.fr.php +++ /dev/null @@ -1,11 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.monsieur-le-chien.fr/index.php?planche=672', - 'body' => array( - '//img[starts-with(@src, "i/planches/")]', - ), - ) - ) -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.npr.org.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.npr.org.php deleted file mode 100644 index ecc0213..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.npr.org.php +++ /dev/null @@ -1,28 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.npr.org/blogs/thesalt/2013/09/17/223345977/auto-brewery-syndrome-apparently-you-can-make-beer-in-your-gut', - 'body' => array( - '//article[contains(@class,"story")]', - ), - 'strip' => array( - '//div[@class="story-tools"]', - '//h3[@class="slug"]', - '//div[@class="storytitle"]', - '//div[@id="story-meta"]', - '//a[@id="mainContent"]', - '//div[@class="credit-caption"]', - '//div[@class="enlarge_html"]', - '//button', - '//div[contains(@id,"pullquote")]', - '//div[contains(@class,"internallink")]', - '//div[contains(@class,"video")]', - '//div[@class="simplenodate"]', - '//div[contains(@class,"share-")]', - '//div[@class="tags"]', - '//aside' - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.numerama.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.numerama.com.php deleted file mode 100644 index fe4971c..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.numerama.com.php +++ /dev/null @@ -1,15 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.numerama.com/sciences/125959-recherches-ladn-recompensees-nobel-de-chimie.html', - 'body' => array( - '//article', - ), - 'strip' => array( - '//footer', - '//section[@class="related-article"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.oneindia.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.oneindia.com.php deleted file mode 100644 index 320c214..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.oneindia.com.php +++ /dev/null @@ -1,14 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.oneindia.com/india/b-luru-govt-likely-remove-word-eunuch-from-sec-36-a-karnataka-police-act-1981173.html', - 'body' => array( - '//div[@class="ecom-ad-content"]', - ), - 'strip' => array( - '//*[@id="view_cmtns"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.pseudo-sciences.org.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.pseudo-sciences.org.php deleted file mode 100644 index 9e467ed..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.pseudo-sciences.org.php +++ /dev/null @@ -1,16 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.pseudo-sciences.org/spip.php?article2275', - 'body' => array( - '//div[@id="art_main"]', - ), - 'strip' => array( - '//div[@id="art_print"]', - '//div[@id="art_chapo"]', - '//img[@class="puce"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.sciencemag.org.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.sciencemag.org.php deleted file mode 100644 index ae7a93a..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.sciencemag.org.php +++ /dev/null @@ -1,16 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.sciencemag.org/news/2016/01/could-bright-foamy-wak$', - 'body' => array( - '//div[@class="row--hero"]', - '//article[contains(@class,"primary")]', - ), - 'strip' => array( - '//header[@class="article__header"]', - '//footer[@class="article__foot"]', - ), - ), - ) -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.slate.fr.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.slate.fr.php deleted file mode 100644 index 8c8dc89..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.slate.fr.php +++ /dev/null @@ -1,19 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.slate.fr/monde/77034/allemagne-2013-couacs-campagne', - 'body' => array( - '//div[@class="article_content"]', - ), - 'strip' => array( - '//*[@id="slate_associated_bn"]', - '//*[@id="ligatus-article"]', - '//*[@id="article_sidebar"]', - '//div[contains(@id, "reseaux")]', - '//*[contains(@class, "smart") or contains(@class, "article_tags") or contains(@class, "article_reactions")]', - '//*[contains(@class, "OUTBRAIN") or contains(@class, "related_item") or contains(@class, "share")]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.universfreebox.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.universfreebox.com.php deleted file mode 100644 index 0747d0f..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.universfreebox.com.php +++ /dev/null @@ -1,15 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://www.universfreebox.com/article/24305/4G-Bouygues-Telecom-lance-une-vente-flash-sur-son-forfait-Sensation-3Go', - 'body' => array( - '//div[@id="corps_corps"]', - ), - 'strip' => array( - '//*[@id="formulaire"]', - '//*[@id="commentaire"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.zeit.de.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.zeit.de.php deleted file mode 100644 index 316c265..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/www.zeit.de.php +++ /dev/null @@ -1,41 +0,0 @@ - array( - '%^/zeit-magazin.*%' => array( - 'test_url' => 'http://www.zeit.de/zeit-magazin/2015/15/pegida-kathrin-oertel-lutz-bachmann', - 'body' => array( - '//article[@class="article"]', - ), - 'strip' => array( - '//header/div/h1', - '//header/div/div[@class="article__head__subtitle"]', - '//header/div/div[@class="article__column__author"]', - '//header/div/div[@class="article__column__author"]', - '//header/div/span[@class="article__head__meta-wrap"]', - '//form', - '//style', - '//div[contains(@class, "ad-tile")]', - '//div[@class="iqd-mobile-adplace"]', - '//div[@id="iq-artikelanker"]', - '//div[@id="js-social-services"]', - '//section[@id="js-comments"]', - '//aside', - ), - ), - '%.*%' => array( - 'test_url' => 'http://www.zeit.de/politik/ausland/2015-04/thessaloniki-krise-griechenland-yannis-boutaris/', - 'body' => array( - '//div[@class="article-body"]', - ), - 'strip' => array( - '//*[@class="articleheader"]', - '//*[@class="excerpt"]', - '//div[contains(@class, "ad")]', - '//div[@itemprop="video"]', - '//*[@class="articlemeta"]', - '//*[@class="articlemeta-clear"]', - '//*[@class="zol_inarticletools"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/xkcd.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/xkcd.com.php deleted file mode 100644 index 8495726..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/xkcd.com.php +++ /dev/null @@ -1,8 +0,0 @@ - array( - '%.*%' => array( - '%alt="(.+)" */>%' => '/>
$1', - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/ymatuhin.ru.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/ymatuhin.ru.php deleted file mode 100644 index 9fd83f1..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/ymatuhin.ru.php +++ /dev/null @@ -1,21 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'https://ymatuhin.ru/tools/git-default-editor/', - 'body' => array( - '//section', - ), - 'strip' => array( - "//script", - "//style", - "//h1", - "//time", - "//aside", - "/html/body/section/ul", - "//amp-iframe", - "/html/body/section/h4" - ), - ) - ) -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/zarojel.hu.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/zarojel.hu.php deleted file mode 100644 index 36d3bdf..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/zarojel.hu.php +++ /dev/null @@ -1,19 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'https://zarojel.hu/meg-egyszer-a-foldi-ugyrol-is/', - 'body' => array( - '//div[@class="entry-category"]/h1', - '//div[@class="entry-content"]/div[@class="vc_row wpb_row vc_row-fluid"]' - ), - 'strip' => array( - '//ins[@class="adsbygoogle"]', - '//script', - '//figcaption', - '//p[contains(text(),"Kapcsolódó")]', - '//div[@class="wpb_wrapper"]/p[@class="entry-title"]' - ) - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/zdnet.com.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/zdnet.com.php deleted file mode 100644 index 79b35dd..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/zdnet.com.php +++ /dev/null @@ -1,23 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'http://zdnet.com.feedsportal.com/c/35462/f/675637/s/4a33c93e/sc/11/l/0L0Szdnet0N0Carticle0Cchina0Eus0Eagree0Eon0Ecybercrime0Ecooperation0Eamid0Econtinued0Etension0C0Tftag0FRSSbaffb68/story01.htm', - 'body' => array( - '//p[@class="summary"]', - '//div[contains(@class,"storyBody")]', - ), - 'strip' => array( - '//*[contains(@class,"ad-")]', - '//p/span', - '//script', - '//p[@class="summary"]', - '//div[contains(@class,"relatedContent")]', - '//div[contains(@class,"loader")]', - '//p[@class="photoDetails"]', - '//div[@class="thumbnailSlider"]', - '//div[@class="shortcodeGalleryWrapper"]', - ), - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/zoom.hu.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/zoom.hu.php deleted file mode 100644 index 3e38781..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Rules/zoom.hu.php +++ /dev/null @@ -1,17 +0,0 @@ - array( - '%.*%' => array( - 'test_url' => 'https://zoom.hu/2017/10/20/mar-nem-nyomoznak-a-vegrehajtok-botranyai-miatt', - 'body' => array( - '//div[@class="title-wrapper"]/h1', - '//div[@class="entry-excerpt"]', - '//div[@class="thumbnail-wrapper"]', - '//div[@id="entry-content-id"]' - ), - 'strip' => array( - '//div[@class="place first normal"]' - ) - ), - ), -); diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Scraper/CandidateParser.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Scraper/CandidateParser.php deleted file mode 100644 index 0f74b3d..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Scraper/CandidateParser.php +++ /dev/null @@ -1,281 +0,0 @@ -dom = XmlParser::getHtmlDocument(''.$html); - $this->xpath = new DOMXPath($this->dom); - } - - /** - * Get the relevant content with the list of potential attributes. - * - * @return string - */ - public function execute() - { - $content = $this->findContentWithCandidates(); - - if (strlen($content) < 200) { - $content = $this->findContentWithArticle(); - } - - if (strlen($content) < 50) { - $content = $this->findContentWithBody(); - } - - return $this->stripGarbage($content); - } - - /** - * Find content based on the list of tag candidates. - * - * @return string - */ - public function findContentWithCandidates() - { - foreach ($this->candidatesAttributes as $candidate) { - Logger::setMessage(get_called_class().': Try this candidate: "'.$candidate.'"'); - - $nodes = $this->xpath->query('//*[(contains(@class, "'.$candidate.'") or @id="'.$candidate.'") and not (contains(@class, "nav") or contains(@class, "page"))]'); - - if ($nodes !== false && $nodes->length > 0) { - Logger::setMessage(get_called_class().': Find candidate "'.$candidate.'"'); - - return $this->dom->saveXML($nodes->item(0)); - } - } - - return ''; - } - - /** - * Find
tag. - * - * @return string - */ - public function findContentWithArticle() - { - $nodes = $this->xpath->query('//article'); - - if ($nodes !== false && $nodes->length > 0) { - Logger::setMessage(get_called_class().': Find
tag'); - - return $this->dom->saveXML($nodes->item(0)); - } - - return ''; - } - - /** - * Find tag. - * - * @return string - */ - public function findContentWithBody() - { - $nodes = $this->xpath->query('//body'); - - if ($nodes !== false && $nodes->length > 0) { - Logger::setMessage(get_called_class().' Find '); - - return $this->dom->saveXML($nodes->item(0)); - } - - return ''; - } - - /** - * Strip useless tags. - * - * @param string $content - * @return string - */ - public function stripGarbage($content) - { - $dom = XmlParser::getDomDocument($content); - - if ($dom !== false) { - $xpath = new DOMXPath($dom); - - $this->stripTags($xpath); - $this->stripAttributes($dom, $xpath); - - $content = $dom->saveXML($dom->documentElement); - } - - return $content; - } - - /** - * Remove blacklisted tags. - * - * @param DOMXPath $xpath - */ - public function stripTags(DOMXPath $xpath) - { - foreach ($this->stripTags as $tag) { - $nodes = $xpath->query('//'.$tag); - - if ($nodes !== false && $nodes->length > 0) { - Logger::setMessage(get_called_class().': Strip tag: "'.$tag.'"'); - - foreach ($nodes as $node) { - $node->parentNode->removeChild($node); - } - } - } - } - - /** - * Remove blacklisted attributes. - * - * @param DomDocument $dom - * @param DOMXPath $xpath - */ - public function stripAttributes(DomDocument $dom, DOMXPath $xpath) - { - foreach ($this->stripAttributes as $attribute) { - $nodes = $xpath->query('//*[contains(@class, "'.$attribute.'") or contains(@id, "'.$attribute.'")]'); - - if ($nodes !== false && $nodes->length > 0) { - Logger::setMessage(get_called_class().': Strip attribute: "'.$attribute.'"'); - - foreach ($nodes as $node) { - if ($this->shouldRemove($dom, $node)) { - $node->parentNode->removeChild($node); - } - } - } - } - } - - /** - * Find link for next page of the article. - * - * @return string - */ - public function findNextLink() - { - return null; - } - - /** - * Return false if the node should not be removed. - * - * @param DomDocument $dom - * @param \DomNode $node - * @return bool - */ - public function shouldRemove(DomDocument $dom, $node) - { - $document_length = strlen($dom->textContent); - $node_length = strlen($node->textContent); - - if ($document_length === 0) { - return true; - } - - $ratio = $node_length * 100 / $document_length; - - if ($ratio >= 90) { - Logger::setMessage(get_called_class().': Should not remove this node ('.$node->nodeName.') ratio: '.$ratio.'%'); - - return false; - } - - return true; - } -} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Scraper/ParserInterface.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Scraper/ParserInterface.php deleted file mode 100644 index 3ded4b1..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Scraper/ParserInterface.php +++ /dev/null @@ -1,20 +0,0 @@ -getRulesFileList($hostname); - - foreach ($this->getRulesFolders() as $folder) { - $rule = $this->loadRuleFile($folder, $files); - - if (!empty($rule)) { - return $rule; - } - } - } - - return array(); - } - - /** - * Get the list of possible rules file names for a given hostname. - * - * @param string $hostname Hostname - * @return array - */ - public function getRulesFileList($hostname) - { - $files = array($hostname); // subdomain.domain.tld - $parts = explode('.', $hostname); - $len = count($parts); - - if ($len > 2) { - $subdomain = array_shift($parts); - $files[] = implode('.', $parts); // domain.tld - $files[] = '.'.implode('.', $parts); // .domain.tld - $files[] = $subdomain; // subdomain - } elseif ($len === 2) { - $files[] = '.'.implode('.', $parts); // .domain.tld - $files[] = $parts[0]; // domain - } - - return $files; - } - - /** - * Load a rule file from the defined folder. - * - * @param string $folder Rule directory - * @param array $files List of possible file names - * @return array - */ - public function loadRuleFile($folder, array $files) - { - foreach ($files as $file) { - $filename = $folder.'/'.$file.'.php'; - if (file_exists($filename)) { - Logger::setMessage(get_called_class().' Load rule: '.$file); - - return include $filename; - } - } - - return array(); - } - - /** - * Get the list of folders that contains rules. - * - * @return array - */ - public function getRulesFolders() - { - $folders = array(); - - if ($this->config !== null && $this->config->getGrabberRulesFolder() !== null) { - $folders[] = $this->config->getGrabberRulesFolder(); - } - - $folders[] = __DIR__ . '/../Rules'; - - return $folders; - } -} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Scraper/RuleParser.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Scraper/RuleParser.php deleted file mode 100644 index 9beb59c..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Scraper/RuleParser.php +++ /dev/null @@ -1,102 +0,0 @@ -rules = $rules; - $this->dom = XmlParser::getHtmlDocument(''.$html); - $this->xpath = new DOMXPath($this->dom); - } - - /** - * Get the relevant content with predefined rules. - * - * @return string - */ - public function execute() - { - $this->stripTags(); - - return $this->findContent(); - } - - /** - * Remove HTML tags. - */ - public function stripTags() - { - if (isset($this->rules['strip']) && is_array($this->rules['strip'])) { - foreach ($this->rules['strip'] as $pattern) { - $nodes = $this->xpath->query($pattern); - - if ($nodes !== false && $nodes->length > 0) { - foreach ($nodes as $node) { - $node->parentNode->removeChild($node); - } - } - } - } - } - - /** - * Fetch content based on Xpath rules. - */ - public function findContent() - { - $content = ''; - if (isset($this->rules['body']) && is_array($this->rules['body'])) { - foreach ($this->rules['body'] as $pattern) { - $nodes = $this->xpath->query($pattern); - - if ($nodes !== false && $nodes->length > 0) { - foreach ($nodes as $node) { - $content .= $this->dom->saveXML($node); - } - } - } - } - - return $content; - } - - /** - * Fetch next link based on Xpath rules. - * - * @return string - */ - public function findNextLink() - { - if (isset($this->rules['next_page']) && is_array($this->rules['next_page'])) { - foreach ($this->rules['next_page'] as $pattern) { - $nodes = $this->xpath->query($pattern); - if ($nodes !== false && $nodes->length > 0) { - foreach ($nodes as $node) { - return $node->getAttribute('href'); - } - } - } - } - return null; - } -} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Scraper/Scraper.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Scraper/Scraper.php deleted file mode 100644 index 29383b2..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Scraper/Scraper.php +++ /dev/null @@ -1,282 +0,0 @@ -enableCandidateParser = false; - return $this; - } - - /** - * Get encoding. - * - * @return string - */ - public function getEncoding() - { - return $this->encoding; - } - - /** - * Set encoding. - * - * @param string $encoding - * - * @return Scraper - */ - public function setEncoding($encoding) - { - $this->encoding = $encoding; - - return $this; - } - - /** - * Get URL to download. - * - * @return string - */ - public function getUrl() - { - return $this->url; - } - - /** - * Set URL to download. - * - * @param string $url URL - * - * @return Scraper - */ - public function setUrl($url) - { - $this->url = $url; - - return $this; - } - - /** - * Return true if the scraper found relevant content. - * - * @return bool - */ - public function hasRelevantContent() - { - return !empty($this->content); - } - - /** - * Get relevant content. - * - * @return string - */ - public function getRelevantContent() - { - return $this->content; - } - - /** - * Get raw content (unfiltered). - * - * @return string - */ - public function getRawContent() - { - return $this->html; - } - - /** - * Set raw content (unfiltered). - * - * @param string $html - * - * @return Scraper - */ - public function setRawContent($html) - { - $this->html = $html; - - return $this; - } - - /** - * Get filtered relevant content. - * - * @return string - */ - public function getFilteredContent() - { - $filter = Filter::html($this->content, $this->url); - $filter->setConfig($this->config); - - return $filter->execute(); - } - - /** - * Download the HTML content. - * - * @return bool - */ - public function download() - { - if (!empty($this->url)) { - - // Clear everything - $this->html = ''; - $this->content = ''; - $this->encoding = ''; - - try { - $client = Client::getInstance(); - $client->setConfig($this->config); - $client->setTimeout($this->config->getGrabberTimeout()); - $client->setUserAgent($this->config->getGrabberUserAgent()); - $client->execute($this->url); - - $this->url = $client->getUrl(); - $this->html = $client->getContent(); - $this->encoding = $client->getEncoding(); - - return true; - } catch (ClientException $e) { - Logger::setMessage(get_called_class().': '.$e->getMessage()); - } - } - - return false; - } - - /** - * Execute the scraper. - * - * @param string $pageContent - * @param int $recursionDepth - */ - public function execute($pageContent = '', $recursionDepth = 0) - { - $this->html = ''; - $this->encoding = ''; - $this->content = ''; - $this->download(); - $this->prepareHtml(); - - $parser = $this->getParser(); - - if ($parser !== null) { - $maxRecursions = $this->config->getMaxRecursions(); - if(!isset($maxRecursions)){ - $maxRecursions = 25; - } - $pageContent .= $parser->execute(); - // check if there is a link to next page and recursively get content (max 25 pages) - if((($nextLink = $parser->findNextLink()) !== null) && $recursionDepth < $maxRecursions){ - $nextLink = Url::resolve($nextLink,$this->url); - $this->setUrl($nextLink); - $this->execute($pageContent,$recursionDepth+1); - } - else{ - $this->content = $pageContent; - } - Logger::setMessage(get_called_class().': Content length: '.strlen($this->content).' bytes'); - } - } - - /** - * Get the parser. - * - * @return ParserInterface - */ - public function getParser() - { - $ruleLoader = new RuleLoader($this->config); - $rules = $ruleLoader->getRules($this->url); - - if (!empty($rules['grabber'])) { - Logger::setMessage(get_called_class().': Parse content with rules'); - - foreach ($rules['grabber'] as $pattern => $rule) { - $url = new Url($this->url); - $sub_url = $url->getFullPath(); - - if (preg_match($pattern, $sub_url)) { - Logger::setMessage(get_called_class().': Matched url '.$sub_url); - return new RuleParser($this->html, $rule); - } - } - } elseif ($this->enableCandidateParser) { - Logger::setMessage(get_called_class().': Parse content with candidates'); - } - - return new CandidateParser($this->html); - } - - /** - * Normalize encoding and strip head tag. - */ - public function prepareHtml() - { - $html_encoding = XmlParser::getEncodingFromMetaTag($this->html); - - $this->html = Encoding::convert($this->html, $html_encoding ?: $this->encoding); - $this->html = Filter::stripHeadTags($this->html); - - Logger::setMessage(get_called_class().': HTTP Encoding "'.$this->encoding.'" ; HTML Encoding "'.$html_encoding.'"'); - } -} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Serialization/Subscription.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Serialization/Subscription.php deleted file mode 100644 index 12eccfd..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Serialization/Subscription.php +++ /dev/null @@ -1,175 +0,0 @@ -title = $title; - return $this; - } - - /** - * Get title - * - * @access public - * @return string - */ - public function getTitle() - { - return $this->title; - } - - /** - * Set feed URL - * - * @access public - * @param string $feedUrl - * @return Subscription - */ - public function setFeedUrl($feedUrl) - { - $this->feedUrl = $feedUrl; - return $this; - } - - /** - * Get feed URL - * - * @access public - * @return string - */ - public function getFeedUrl() - { - return $this->feedUrl; - } - - /** - * Set site URL - * - * @access public - * @param string $siteUrl - * @return Subscription - */ - public function setSiteUrl($siteUrl) - { - $this->siteUrl = $siteUrl; - return $this; - } - - /** - * Get site URL - * - * @access public - * @return string - */ - public function getSiteUrl() - { - return $this->siteUrl; - } - - /** - * Set category - * - * @access public - * @param string $category - * @return Subscription - */ - public function setCategory($category) - { - $this->category = $category; - return $this; - } - - /** - * Get category - * - * @access public - * @return string - */ - public function getCategory() - { - return $this->category; - } - - /** - * Set description - * - * @access public - * @param string $description - * @return Subscription - */ - public function setDescription($description) - { - $this->description = $description; - return $this; - } - - /** - * Get description - * - * @access public - * @return string - */ - public function getDescription() - { - return $this->description; - } - - /** - * Set type - * - * @access public - * @param string $type - * @return Subscription - */ - public function setType($type) - { - $this->type = $type; - return $this; - } - - /** - * Get type - * - * @access public - * @return string - */ - public function getType() - { - return $this->type; - } -} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Serialization/SubscriptionList.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Serialization/SubscriptionList.php deleted file mode 100644 index b173f89..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Serialization/SubscriptionList.php +++ /dev/null @@ -1,75 +0,0 @@ -title = $title; - return $this; - } - - /** - * Get title - * - * @access public - * @return string - */ - public function getTitle() - { - return $this->title; - } - - /** - * Add subscription - * - * @access public - * @param Subscription $subscription - * @return SubscriptionList - */ - public function addSubscription(Subscription $subscription) - { - $this->subscriptions[] = $subscription; - return $this; - } -} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Serialization/SubscriptionListBuilder.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Serialization/SubscriptionListBuilder.php deleted file mode 100644 index 838e4cb..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Serialization/SubscriptionListBuilder.php +++ /dev/null @@ -1,204 +0,0 @@ -subscriptionList = $subscriptionList; - } - - /** - * Get object instance - * - * @static - * @access public - * @param SubscriptionList $subscriptionList - * @return SubscriptionListBuilder - */ - public static function create(SubscriptionList $subscriptionList) - { - return new static($subscriptionList); - } - - /** - * Build OPML feed - * - * @access public - * @param string $filename - * @return string - */ - public function build($filename = '') - { - $this->document = new DomDocument('1.0', 'UTF-8'); - $this->document->formatOutput = true; - - $opmlElement = $this->document->createElement('opml'); - $opmlElement->setAttribute('version', '1.0'); - - $headElement = $this->document->createElement('head'); - - if ($this->subscriptionList->getTitle() !== '') { - $titleElement = $this->document->createElement('title'); - $titleElement->appendChild($this->document->createTextNode($this->subscriptionList->getTitle())); - $headElement->appendChild($titleElement); - } - - $opmlElement->appendChild($headElement); - $opmlElement->appendChild($this->buildBody()); - $this->document->appendChild($opmlElement); - - if ($filename !== '') { - $this->document->save($filename); - return ''; - } - - return $this->document->saveXML(); - } - - /** - * Return true if the list has categories - * - * @access public - * @return bool - */ - public function hasCategories() - { - foreach ($this->subscriptionList->subscriptions as $subscription) { - if ($subscription->getCategory() !== '') { - return true; - } - } - - return false; - } - - /** - * Build OPML body - * - * @access protected - * @return DOMElement - */ - protected function buildBody() - { - $bodyElement = $this->document->createElement('body'); - - if ($this->hasCategories()) { - $this->buildCategories($bodyElement); - return $bodyElement; - } - - foreach ($this->subscriptionList->subscriptions as $subscription) { - $bodyElement->appendChild($this->buildSubscription($subscription)); - } - - return $bodyElement; - } - - /** - * Build categories section - * - * @access protected - * @param DOMElement $bodyElement - */ - protected function buildCategories(DOMElement $bodyElement) - { - $categories = $this->groupByCategories(); - - foreach ($categories as $category => $subscriptions) { - $bodyElement->appendChild($this->buildCategory($category, $subscriptions)); - } - } - - /** - * Build category tag - * - * @access protected - * @param string $category - * @param array $subscriptions - * @return DOMElement - */ - protected function buildCategory($category, array $subscriptions) - { - $outlineElement = $this->document->createElement('outline'); - $outlineElement->setAttribute('text', $category); - - foreach ($subscriptions as $subscription) { - $outlineElement->appendChild($this->buildSubscription($subscription)); - } - - return $outlineElement; - } - - /** - * Build subscription entry - * - * @access public - * @param Subscription $subscription - * @return DOMElement - */ - protected function buildSubscription(Subscription $subscription) - { - $outlineElement = $this->document->createElement('outline'); - $outlineElement->setAttribute('type', $subscription->getType() ?: 'rss'); - $outlineElement->setAttribute('text', $subscription->getTitle() ?: $subscription->getFeedUrl()); - $outlineElement->setAttribute('xmlUrl', $subscription->getFeedUrl()); - - if ($subscription->getTitle() !== '') { - $outlineElement->setAttribute('title', $subscription->getTitle()); - } - - if ($subscription->getDescription() !== '') { - $outlineElement->setAttribute('description', $subscription->getDescription()); - } - - if ($subscription->getSiteUrl() !== '') { - $outlineElement->setAttribute('htmlUrl', $subscription->getSiteUrl()); - } - - return $outlineElement; - } - - /** - * Group subscriptions by category - * - * @access private - * @return array - */ - private function groupByCategories() - { - $categories = array(); - - foreach ($this->subscriptionList->subscriptions as $subscription) { - $categories[$subscription->getCategory()][] = $subscription; - } - - return $categories; - } -} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Serialization/SubscriptionListParser.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Serialization/SubscriptionListParser.php deleted file mode 100644 index 9085588..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Serialization/SubscriptionListParser.php +++ /dev/null @@ -1,100 +0,0 @@ -subscriptionList = new SubscriptionList(); - $this->data = trim($data); - } - - /** - * Get object instance - * - * @static - * @access public - * @param string $data - * @return SubscriptionListParser - */ - public static function create($data) - { - return new static($data); - } - - /** - * Parse a subscription list entry - * - * @access public - * @throws MalformedXmlException - * @return SubscriptionList - */ - public function parse() - { - $xml = XmlParser::getSimpleXml($this->data); - - if (! $xml || !isset($xml->head) || !isset($xml->body)) { - throw new MalformedXmlException('Unable to parse OPML file: invalid XML'); - } - - $this->parseTitle($xml->head); - $this->parseEntries($xml->body); - - return $this->subscriptionList; - } - - /** - * Parse title - * - * @access protected - * @param SimpleXMLElement $xml - */ - protected function parseTitle(SimpleXMLElement $xml) - { - $this->subscriptionList->setTitle((string) $xml->title); - } - - /** - * Parse entries - * - * @access protected - * @param SimpleXMLElement $body - */ - private function parseEntries(SimpleXMLElement $body) - { - foreach ($body->outline as $outlineElement) { - if (isset($outlineElement->outline)) { - $this->parseEntries($outlineElement); - } else { - $this->subscriptionList->subscriptions[] = SubscriptionParser::create($body, $outlineElement)->parse(); - } - } - } -} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Serialization/SubscriptionParser.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Serialization/SubscriptionParser.php deleted file mode 100644 index caff07c..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Serialization/SubscriptionParser.php +++ /dev/null @@ -1,142 +0,0 @@ -parentElement = $parentElement; - $this->outlineElement = $outlineElement; - $this->subscription = new Subscription(); - } - - /** - * Get object instance - * - * @static - * @access public - * @param SimpleXMLElement $parentElement - * @param SimpleXMLElement $outlineElement - * @return SubscriptionParser - */ - public static function create(SimpleXMLElement $parentElement, SimpleXMLElement $outlineElement) - { - return new static($parentElement, $outlineElement); - } - - /** - * Parse subscription entry - * - * @access public - * @return Subscription - */ - public function parse() - { - $this->subscription->setCategory($this->findCategory()); - $this->subscription->setTitle($this->findTitle()); - $this->subscription->setFeedUrl($this->findFeedUrl()); - $this->subscription->setSiteUrl($this->findSiteUrl()); - $this->subscription->setType($this->findType()); - $this->subscription->setDescription($this->findDescription()); - - return $this->subscription; - } - - /** - * Find category. - * - * @access protected - * @return string - */ - protected function findCategory() - { - return isset($this->parentElement['text']) ? (string) $this->parentElement['text'] : ''; - } - - /** - * Find title. - * - * @access protected - * @return string - */ - protected function findTitle() - { - return isset($this->outlineElement['title']) ? (string) $this->outlineElement['title'] : (string) $this->outlineElement['text']; - } - - /** - * Find feed url. - * - * @access protected - * @return string - */ - protected function findFeedUrl() - { - return (string) $this->outlineElement['xmlUrl']; - } - - /** - * Find site url. - * - * @access protected - * @return string - */ - protected function findSiteUrl() - { - return isset($this->outlineElement['htmlUrl']) ? (string) $this->outlineElement['htmlUrl'] : $this->findFeedUrl(); - } - - /** - * Find type. - * - * @access protected - * @return string - */ - protected function findType() - { - return isset($this->outlineElement['version']) ? (string) $this->outlineElement['version'] : - isset($this->outlineElement['type']) ? (string) $this->outlineElement['type'] : 'rss'; - } - - /** - * Find description. - * - * @access protected - * @return string - */ - protected function findDescription() - { - return isset($this->outlineElement['description']) ? (string) $this->outlineElement['description'] : $this->findTitle(); - } -} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/AtomFeedBuilder.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/AtomFeedBuilder.php deleted file mode 100644 index 34f3780..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/AtomFeedBuilder.php +++ /dev/null @@ -1,65 +0,0 @@ -helper = new AtomHelper($this->getDocument()); - - $this->feedElement = $this->getDocument()->createElement('feed'); - $this->feedElement->setAttributeNodeNS(new DomAttr('xmlns', 'http://www.w3.org/2005/Atom')); - - $generator = $this->getDocument()->createElement('generator', 'PicoFeed'); - $generator->setAttribute('uri', 'https://github.com/miniflux/picoFeed'); - $this->feedElement->appendChild($generator); - - $this->helper - ->buildTitle($this->feedElement, $this->feedTitle) - ->buildId($this->feedElement, $this->feedUrl) - ->buildDate($this->feedElement, $this->feedDate) - ->buildLink($this->feedElement, $this->siteUrl) - ->buildLink($this->feedElement, $this->feedUrl, 'self', 'application/atom+xml') - ->buildAuthor($this->feedElement, $this->authorName, $this->authorEmail, $this->authorUrl) - ; - - foreach ($this->items as $item) { - $this->feedElement->appendChild($item->build()); - } - - $this->getDocument()->appendChild($this->feedElement); - - if ($filename !== '') { - $this->getDocument()->save($filename); - } - - return $this->getDocument()->saveXML(); - } -} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/AtomHelper.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/AtomHelper.php deleted file mode 100644 index def6b0b..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/AtomHelper.php +++ /dev/null @@ -1,139 +0,0 @@ -document = $document; - } - - /** - * Build node - * - * @access public - * @param DOMElement $element - * @param string $tag - * @param string $value - * @return AtomHelper - */ - public function buildNode(DOMElement $element, $tag, $value) - { - $node = $this->document->createElement($tag); - $node->appendChild($this->document->createTextNode($value)); - $element->appendChild($node); - return $this; - } - - /** - * Build title - * - * @access public - * @param DOMElement $element - * @param string $title - * @return AtomHelper - */ - public function buildTitle(DOMElement $element, $title) - { - return $this->buildNode($element, 'title', $title); - } - - /** - * Build id - * - * @access public - * @param DOMElement $element - * @param string $id - * @return AtomHelper - */ - public function buildId(DOMElement $element, $id) - { - return $this->buildNode($element, 'id', $id); - } - - /** - * Build date element - * - * @access public - * @param DOMElement $element - * @param DateTime $date - * @param string $type - * @return AtomHelper - */ - public function buildDate(DOMElement $element, DateTime $date, $type = 'updated') - { - return $this->buildNode($element, $type, $date->format(DateTime::ATOM)); - } - - /** - * Build link element - * - * @access public - * @param DOMElement $element - * @param string $url - * @param string $rel - * @param string $type - * @return AtomHelper - */ - public function buildLink(DOMElement $element, $url, $rel = 'alternate', $type = 'text/html') - { - $node = $this->document->createElement('link'); - $node->setAttribute('rel', $rel); - $node->setAttribute('type', $type); - $node->setAttribute('href', $url); - $element->appendChild($node); - - return $this; - } - - /** - * Build author element - * - * @access public - * @param DOMElement $element - * @param string $authorName - * @param string $authorEmail - * @param string $authorUrl - * @return AtomHelper - */ - public function buildAuthor(DOMElement $element, $authorName, $authorEmail, $authorUrl) - { - if (!empty($authorName)) { - $author = $this->document->createElement('author'); - $this->buildNode($author, 'name', $authorName); - - if (!empty($authorEmail)) { - $this->buildNode($author, 'email', $authorEmail); - } - - if (!empty($authorUrl)) { - $this->buildNode($author, 'uri', $authorUrl); - } - - $element->appendChild($author); - } - - return $this; - } -} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/AtomItemBuilder.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/AtomItemBuilder.php deleted file mode 100644 index dfdfe68..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/AtomItemBuilder.php +++ /dev/null @@ -1,63 +0,0 @@ -itemElement = $this->feedBuilder->getDocument()->createElement('entry'); - $this->helper = new AtomHelper($this->feedBuilder->getDocument()); - - if (!empty($this->itemId)) { - $this->helper->buildId($this->itemElement, $this->itemId); - } else { - $this->helper->buildId($this->itemElement, $this->itemUrl); - } - - $this->helper - ->buildTitle($this->itemElement, $this->itemTitle) - ->buildLink($this->itemElement, $this->itemUrl) - ->buildDate($this->itemElement, $this->itemUpdatedDate, 'updated') - ->buildDate($this->itemElement, $this->itemPublishedDate, 'published') - ->buildAuthor($this->itemElement, $this->authorName, $this->authorEmail, $this->authorUrl) - ; - - if (!empty($this->itemSummary)) { - $this->helper->buildNode($this->itemElement, 'summary', $this->itemSummary); - } - - if (!empty($this->itemContent)) { - $node = $this->feedBuilder->getDocument()->createElement('content'); - $node->setAttribute('type', 'html'); - $node->appendChild($this->feedBuilder->getDocument()->createCDATASection($this->itemContent)); - $this->itemElement->appendChild($node); - } - - return $this->itemElement; - } -} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/FeedBuilder.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/FeedBuilder.php deleted file mode 100644 index cf9d024..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/FeedBuilder.php +++ /dev/null @@ -1,185 +0,0 @@ -document = new DomDocument('1.0', 'UTF-8'); - $this->document->formatOutput = true; - } - - /** - * Get new object instance - * - * @access public - * @return static - */ - public static function create() - { - return new static(); - } - - /** - * Add feed title - * - * @access public - * @param string $title - * @return $this - */ - public function withTitle($title) - { - $this->feedTitle = $title; - return $this; - } - - /** - * Add feed url - * - * @access public - * @param string $url - * @return $this - */ - public function withFeedUrl($url) - { - $this->feedUrl = $url; - return $this; - } - - /** - * Add website url - * - * @access public - * @param string $url - * @return $this - */ - public function withSiteUrl($url) - { - $this->siteUrl = $url; - return $this; - } - - /** - * Add feed date - * - * @access public - * @param DateTime $date - * @return $this - */ - public function withDate(DateTime $date) - { - $this->feedDate = $date; - return $this; - } - - /** - * Add feed author - * - * @access public - * @param string $name - * @param string $email - * @param string $url - * @return $this - */ - public function withAuthor($name, $email = '', $url ='') - { - $this->authorName = $name; - $this->authorEmail = $email; - $this->authorUrl = $url; - return $this; - } - - /** - * Add feed item - * - * @access public - * @param ItemBuilder $item - * @return $this - */ - public function withItem(ItemBuilder $item) - { - $this->items[] = $item; - return $this; - } - - /** - * Get DOM document - * - * @access public - * @return DOMDocument - */ - public function getDocument() - { - return $this->document; - } - - /** - * Build feed - * - * @abstract - * @access public - * @param string $filename - * @return string - */ - abstract public function build($filename = ''); -} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/ItemBuilder.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/ItemBuilder.php deleted file mode 100644 index 86985bc..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/ItemBuilder.php +++ /dev/null @@ -1,209 +0,0 @@ -feedBuilder = $feedBuilder; - } - - /** - * Get new object instance - * - * @access public - * @param FeedBuilder $feedBuilder - * @return static - */ - public static function create(FeedBuilder $feedBuilder) - { - return new static($feedBuilder); - } - - /** - * Add item title - * - * @access public - * @param string $title - * @return $this - */ - public function withTitle($title) - { - $this->itemTitle = $title; - return $this; - } - - /** - * Add item id - * - * @access public - * @param string $id - * @return $this - */ - public function withId($id) - { - $this->itemId = $id; - return $this; - } - - /** - * Add item url - * - * @access public - * @param string $url - * @return $this - */ - public function withUrl($url) - { - $this->itemUrl = $url; - return $this; - } - - /** - * Add item summary - * - * @access public - * @param string $summary - * @return $this - */ - public function withSummary($summary) - { - $this->itemSummary = $summary; - return $this; - } - - /** - * Add item content - * - * @access public - * @param string $content - * @return $this - */ - public function withContent($content) - { - $this->itemContent = $content; - return $this; - } - - /** - * Add item updated date - * - * @access public - * @param DateTime $date - * @return $this - */ - public function withUpdatedDate(DateTime $date) - { - $this->itemUpdatedDate = $date; - return $this; - } - - /** - * Add item published date - * - * @access public - * @param DateTime $date - * @return $this - */ - public function withPublishedDate(DateTime $date) - { - $this->itemPublishedDate = $date; - return $this; - } - - /** - * Add item author - * - * @access public - * @param string $name - * @param string $email - * @param string $url - * @return $this - */ - public function withAuthor($name, $email = '', $url ='') - { - $this->authorName = $name; - $this->authorEmail = $email; - $this->authorUrl = $url; - return $this; - } - - /** - * Build item - * - * @abstract - * @access public - * @return DOMElement - */ - abstract public function build(); -} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/Rss20FeedBuilder.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/Rss20FeedBuilder.php deleted file mode 100644 index bc3f513..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/Rss20FeedBuilder.php +++ /dev/null @@ -1,76 +0,0 @@ -helper = new Rss20Helper($this->getDocument()); - - $this->rssElement = $this->getDocument()->createElement('rss'); - $this->rssElement->setAttribute('version', '2.0'); - $this->rssElement->setAttributeNodeNS(new DomAttr('xmlns:content', 'http://purl.org/rss/1.0/modules/content/')); - $this->rssElement->setAttributeNodeNS(new DomAttr('xmlns:atom', 'http://www.w3.org/2005/Atom')); - - $this->channelElement = $this->getDocument()->createElement('channel'); - $this->helper - ->buildNode($this->channelElement, 'generator', 'PicoFeed (https://github.com/miniflux/picoFeed)') - ->buildTitle($this->channelElement, $this->feedTitle) - ->buildNode($this->channelElement, 'description', $this->feedTitle) - ->buildDate($this->channelElement, $this->feedDate) - ->buildAuthor($this->channelElement, 'webMaster', $this->authorName, $this->authorEmail) - ->buildLink($this->channelElement, $this->siteUrl) - ; - - $link = $this->getDocument()->createElement('atom:link'); - $link->setAttribute('href', $this->feedUrl); - $link->setAttribute('rel', 'self'); - $link->setAttribute('type', 'application/rss+xml'); - $this->channelElement->appendChild($link); - - foreach ($this->items as $item) { - $this->channelElement->appendChild($item->build()); - } - - $this->rssElement->appendChild($this->channelElement); - $this->getDocument()->appendChild($this->rssElement); - - if ($filename !== '') { - $this->getDocument()->save($filename); - } - - return $this->getDocument()->saveXML(); - } -} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/Rss20Helper.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/Rss20Helper.php deleted file mode 100644 index 72a19e5..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/Rss20Helper.php +++ /dev/null @@ -1,115 +0,0 @@ -document = $document; - } - - /** - * Build node - * - * @access public - * @param DOMElement $element - * @param string $tag - * @param string $value - * @return $this - */ - public function buildNode(DOMElement $element, $tag, $value) - { - $node = $this->document->createElement($tag); - $node->appendChild($this->document->createTextNode($value)); - $element->appendChild($node); - return $this; - } - - /** - * Build title - * - * @access public - * @param DOMElement $element - * @param string $title - * @return $this - */ - public function buildTitle(DOMElement $element, $title) - { - return $this->buildNode($element, 'title', $title); - } - - /** - * Build date element - * - * @access public - * @param DOMElement $element - * @param DateTime $date - * @param string $type - * @return $this - */ - public function buildDate(DOMElement $element, DateTime $date, $type = 'pubDate') - { - return $this->buildNode($element, $type, $date->format(DateTime::RSS)); - } - - /** - * Build link element - * - * @access public - * @param DOMElement $element - * @param string $url - * @return $this - */ - public function buildLink(DOMElement $element, $url) - { - return $this->buildNode($element, 'link', $url); - } - - /** - * Build author element - * - * @access public - * @param DOMElement $element - * @param string $tag - * @param string $authorName - * @param string $authorEmail - * @return $this - */ - public function buildAuthor(DOMElement $element, $tag, $authorName, $authorEmail) - { - if (!empty($authorName)) { - $value = ''; - - if (!empty($authorEmail)) { - $value .= $authorEmail.' ('.$authorName.')'; - } else { - $value = $authorName; - } - - $this->buildNode($element, $tag, $value); - } - - return $this; - } -} diff --git a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/Rss20ItemBuilder.php b/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/Rss20ItemBuilder.php deleted file mode 100644 index 125dc6a..0000000 --- a/plugins/admin/vendor/p3k/picofeed/lib/PicoFeed/Syndication/Rss20ItemBuilder.php +++ /dev/null @@ -1,67 +0,0 @@ -itemElement = $this->feedBuilder->getDocument()->createElement('item'); - $this->helper = new Rss20Helper($this->feedBuilder->getDocument()); - - if (!empty($this->itemId)) { - $guid = $this->feedBuilder->getDocument()->createElement('guid'); - $guid->setAttribute('isPermaLink', 'false'); - $guid->appendChild($this->feedBuilder->getDocument()->createTextNode($this->itemId)); - $this->itemElement->appendChild($guid); - } else { - $guid = $this->feedBuilder->getDocument()->createElement('guid'); - $guid->setAttribute('isPermaLink', 'true'); - $guid->appendChild($this->feedBuilder->getDocument()->createTextNode($this->itemUrl)); - $this->itemElement->appendChild($guid); - } - - $this->helper - ->buildTitle($this->itemElement, $this->itemTitle) - ->buildLink($this->itemElement, $this->itemUrl) - ->buildDate($this->itemElement, $this->itemPublishedDate) - ->buildAuthor($this->itemElement, 'author', $this->authorName, $this->authorEmail) - ; - - if (!empty($this->itemSummary)) { - $this->helper->buildNode($this->itemElement, 'description', $this->itemSummary); - } - - if (!empty($this->itemContent)) { - $node = $this->feedBuilder->getDocument()->createElement('content:encoded'); - $node->appendChild($this->feedBuilder->getDocument()->createCDATASection($this->itemContent)); - $this->itemElement->appendChild($node); - } - - return $this->itemElement; - } -} diff --git a/plugins/admin/vendor/p3k/picofeed/picofeed b/plugins/admin/vendor/p3k/picofeed/picofeed deleted file mode 100644 index 8f35737..0000000 --- a/plugins/admin/vendor/p3k/picofeed/picofeed +++ /dev/null @@ -1,135 +0,0 @@ -#!/usr/bin/env php -discover($url); - - $parser = $reader->getParser( - $resource->getUrl(), - $resource->getContent(), - $resource->getEncoding() - ); - - if ($disable_filtering) { - $parser->disableContentFiltering(); - } - - return $parser->execute(); - } - catch (PicoFeedException $e) { - echo 'Exception thrown ===> "'.$e->getMessage().'"'.PHP_EOL; - return false; - } -} - -function get_item($feed, $item_id) -{ - foreach ($feed->items as $item) { - if ($item->getId() === $item_id) { - echo $item; - echo "============= CONTENT ================\n"; - echo $item->getContent(); - echo "\n============= CONTENT ================\n"; - break; - } - } -} - -function dump_feed($url) -{ - $feed = get_feed($url); - echo $feed; -} - -function debug_feed($url) -{ - get_feed($url); - print_r(Logger::getMessages()); -} - -function dump_item($url, $item_id) -{ - $feed = get_feed($url); - - if ($feed !== false) { - get_item($feed, $item_id); - } -} - -function nofilter_item($url, $item_id) -{ - $feed = get_feed($url, true); - - if ($feed !== false) { - get_item($feed, $item_id); - } -} - -function grabber($url) -{ - $grabber = new Scraper(new Config); - $grabber->setUrl($url); - $grabber->execute(); - - print_r(Logger::getMessages()); - echo "============= CONTENT ================\n"; - echo $grabber->getRelevantContent().PHP_EOL; - echo "============= FILTERED ================\n"; - echo $grabber->getFilteredContent().PHP_EOL; -} - -function fetch_favicon($url) -{ - $favicon = new Favicon(); - echo $favicon->find($url) . PHP_EOL; -} - -// Parse command line arguments -if ($argc === 4) { - switch ($argv[1]) { - case 'item': - dump_item($argv[2], $argv[3]); - die; - case 'nofilter': - nofilter_item($argv[2], $argv[3]); - die; - } -} else if ($argc === 3) { - switch ($argv[1]) { - case 'feed': - dump_feed($argv[2]); - die; - case 'debug': - debug_feed($argv[2]); - die; - case 'grabber': - grabber($argv[2]); - die; - case 'favicon': - fetch_favicon($argv[2]); - die; - } -} - -printf("Usage:\n"); -printf("%s feed \n", $argv[0]); -printf("%s debug \n", $argv[0]); -printf("%s item \n", $argv[0]); -printf("%s nofilter \n", $argv[0]); -printf("%s grabber \n", $argv[0]); -printf("%s favicon \n", $argv[0]); diff --git a/plugins/admin/vendor/scssphp/scssphp/LICENSE.md b/plugins/admin/vendor/scssphp/scssphp/LICENSE.md deleted file mode 100644 index afcfdfb..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/LICENSE.md +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2015 Leaf Corcoran, http://scssphp.github.io/scssphp - -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/plugins/admin/vendor/scssphp/scssphp/README.md b/plugins/admin/vendor/scssphp/scssphp/README.md deleted file mode 100644 index 65bb93e..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/README.md +++ /dev/null @@ -1,71 +0,0 @@ -# scssphp -### - -![Build](https://github.com/scssphp/scssphp/workflows/CI/badge.svg) -[![License](https://poser.pugx.org/scssphp/scssphp/license)](https://packagist.org/packages/scssphp/scssphp) - -`scssphp` is a compiler for SCSS written in PHP. - -Checkout the homepage, , for directions on how to use. - -## Running Tests - -`scssphp` uses [PHPUnit](https://github.com/sebastianbergmann/phpunit) for testing. - -Run the following command from the root directory to run every test: - - vendor/bin/phpunit tests - -There are several tests in the `tests/` directory: - -* `ApiTest.php` contains various unit tests that test the PHP interface. -* `ExceptionTest.php` contains unit tests that test for exceptions thrown by the parser and compiler. -* `FailingTest.php` contains tests reported in Github issues that demonstrate compatibility bugs. -* `InputTest.php` compiles every `.scss` file in the `tests/inputs` directory - then compares to the respective `.css` file in the `tests/outputs` directory. -* `SassSpecTest.php` extracts tests from the `sass/sass-spec` repository. - -When changing any of the tests in `tests/inputs`, the tests will most likely -fail because the output has changed. Once you verify that the output is correct -you can run the following command to rebuild all the tests: - - BUILD=1 vendor/bin/phpunit tests - -This will compile all the tests, and save results into `tests/outputs`. It also -updates the list of excluded specs from sass-spec. - -To enable the full `sass-spec` compatibility tests: - - TEST_SASS_SPEC=1 vendor/bin/phpunit tests - -## Coding Standard - -`scssphp` source conforms to [PSR12](https://www.php-fig.org/psr/psr-12/). - -Run the following command from the root directory to check the code for "sniffs". - - vendor/bin/phpcs --standard=PSR12 --extensions=php bin src tests *.php - -## Static Analysis - -`scssphp` uses [phpstan](https://phpstan.org/) for static analysis. - -Run the following command from the root directory to analyse the codebase: - - make phpstan - -As most of the codebase is composed of legacy code which cannot be type-checked -fully, the setup contains a baseline file with all errors we want to ignore. In -particular, we ignore all errors related to not specifying the types inside arrays -when these arrays correspond to the representation of Sass values and Sass AST nodes -in the parser and compiler. -When contributing, the proper process to deal with static analysis is the following: - -1. Make your change in the codebase -2. Run `make phpstan` -3. Fix errors reported by phpstan when possible -4. Repeat step 2 and 3 until nothing gets fixed anymore at step 3 -5. Run `make phpstan-baseline` to regenerate the phpstan baseline - -Additions to the baseline will be reviewed to avoid ignoring errors that should have -been fixed. diff --git a/plugins/admin/vendor/scssphp/scssphp/bin/pscss b/plugins/admin/vendor/scssphp/scssphp/bin/pscss deleted file mode 100644 index 0f009d6..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/bin/pscss +++ /dev/null @@ -1,244 +0,0 @@ -#!/usr/bin/env php -parse($data)), true)); - - fwrite(STDERR, 'Warning: the --dump-tree option is deprecated. Use proper debugging tools instead.'); - - exit(); -} - -$scss = new Compiler(); - -if ($loadPaths) { - $scss->setImportPaths($loadPaths); -} - -if ($style) { - if ($style === OutputStyle::COMPRESSED || $style === OutputStyle::EXPANDED) { - $scss->setOutputStyle($style); - } else { - fwrite(STDERR, "WARNING: the $style style is deprecated.\n"); - $scss->setFormatter('ScssPhp\\ScssPhp\\Formatter\\' . ucfirst($style)); - } -} - -$outputFile = isset($arguments[1]) ? $arguments[1] : null; -$sourceMapFile = null; - -if ($sourceMap) { - $sourceMapOptions = array( - 'outputSourceFiles' => $embedSources, - ); - if ($embedSourceMap || $outputFile === null) { - $scss->setSourceMap(Compiler::SOURCE_MAP_INLINE); - } else { - $sourceMapFile = $outputFile . '.map'; - $sourceMapOptions['sourceMapWriteTo'] = $sourceMapFile; - $sourceMapOptions['sourceMapURL'] = basename($sourceMapFile); - $sourceMapOptions['sourceMapBasepath'] = getcwd(); - $sourceMapOptions['sourceMapFilename'] = basename($outputFile); - - $scss->setSourceMap(Compiler::SOURCE_MAP_FILE); - } - - $scss->setSourceMapOptions($sourceMapOptions); -} - -if ($encoding) { - $scss->setEncoding($encoding); -} - -try { - $result = $scss->compileString($data, $inputFile); -} catch (SassException $e) { - fwrite(STDERR, 'Error: '.$e->getMessage()."\n"); - exit(1); -} - -if ($outputFile) { - file_put_contents($outputFile, $result->getCss()); - - if ($sourceMapFile !== null && $result->getSourceMap() !== null) { - file_put_contents($sourceMapFile, $result->getSourceMap()); - } -} else { - echo $result->getCss(); -} diff --git a/plugins/admin/vendor/scssphp/scssphp/composer.json b/plugins/admin/vendor/scssphp/scssphp/composer.json deleted file mode 100644 index d17ffb9..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/composer.json +++ /dev/null @@ -1,117 +0,0 @@ -{ - "name": "scssphp/scssphp", - "type": "library", - "description": "scssphp is a compiler for SCSS written in PHP.", - "keywords": ["css", "stylesheet", "scss", "sass", "less"], - "homepage": "http://scssphp.github.io/scssphp/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Anthon Pang", - "email": "apang@softwaredevelopment.ca", - "homepage": "https://github.com/robocoder" - }, - { - "name": "Cédric Morin", - "email": "cedric@yterium.com", - "homepage": "https://github.com/Cerdic" - } - ], - "autoload": { - "psr-4": { "ScssPhp\\ScssPhp\\": "src/" } - }, - "autoload-dev": { - "psr-4": { "ScssPhp\\ScssPhp\\Tests\\": "tests/" } - }, - "require": { - "php": ">=5.6.0", - "ext-json": "*", - "ext-ctype": "*" - }, - "suggest": { - "ext-mbstring": "For best performance, mbstring should be installed as it is faster than ext-iconv", - "ext-iconv": "Can be used as fallback when ext-mbstring is not available" - }, - "require-dev": { - "bamarni/composer-bin-plugin": "^1.4", - "phpunit/phpunit": "^5.7 || ^6.5 || ^7.5 || ^8.3 || ^9.4", - "sass/sass-spec": "*", - "squizlabs/php_codesniffer": "~3.5", - "symfony/phpunit-bridge": "^5.1", - "thoughtbot/bourbon": "^7.0", - "twbs/bootstrap": "~5.0", - "twbs/bootstrap4": "4.6.1", - "zurb/foundation": "~6.7.0" - }, - "repositories": [ - { - "type": "package", - "package": { - "name": "sass/sass-spec", - "version": "2022.08.19", - "source": { - "type": "git", - "url": "https://github.com/sass/sass-spec.git", - "reference": "2bdc199723a3445d5badac3ac774105698f08861" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sass/sass-spec/zipball/2bdc199723a3445d5badac3ac774105698f08861", - "reference": "2bdc199723a3445d5badac3ac774105698f08861", - "shasum": "" - } - } - }, - { - "type": "package", - "package": { - "name": "thoughtbot/bourbon", - "version": "v7.0.0", - "source": { - "type": "git", - "url": "https://github.com/thoughtbot/bourbon.git", - "reference": "fbe338ee6807e7f7aa996d82c8a16f248bb149b3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thoughtbot/bourbon/zipball/fbe338ee6807e7f7aa996d82c8a16f248bb149b3", - "reference": "fbe338ee6807e7f7aa996d82c8a16f248bb149b3", - "shasum": "" - } - } - }, - { - "type": "package", - "package": { - "name": "twbs/bootstrap4", - "version": "v4.6.1", - "source": { - "type": "git", - "url": "https://github.com/twbs/bootstrap.git", - "reference": "043a03c95a2ad6738f85b65e53b9dbdfb03b8d10" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/twbs/bootstrap/zipball/043a03c95a2ad6738f85b65e53b9dbdfb03b8d10", - "reference": "043a03c95a2ad6738f85b65e53b9dbdfb03b8d10", - "shasum": "" - } - } - } - ], - "bin": ["bin/pscss"], - "config": { - "sort-packages": true, - "allow-plugins": { - "bamarni/composer-bin-plugin": true - } - }, - "extra": { - "bamarni-bin": { - "forward-command": false, - "bin-links": false - } - } -} diff --git a/plugins/admin/vendor/scssphp/scssphp/scss.inc.php b/plugins/admin/vendor/scssphp/scssphp/scss.inc.php deleted file mode 100644 index 4598378..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/scss.inc.php +++ /dev/null @@ -1,21 +0,0 @@ - - * - * @internal - */ -class Range -{ - /** - * @var float|int - */ - public $first; - - /** - * @var float|int - */ - public $last; - - /** - * Initialize range - * - * @param int|float $first - * @param int|float $last - */ - public function __construct($first, $last) - { - $this->first = $first; - $this->last = $last; - } - - /** - * Test for inclusion in range - * - * @param int|float $value - * - * @return bool - */ - public function includes($value) - { - return $value >= $this->first && $value <= $this->last; - } -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Block.php b/plugins/admin/vendor/scssphp/scssphp/src/Block.php deleted file mode 100644 index 96668dc..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/Block.php +++ /dev/null @@ -1,73 +0,0 @@ - - * - * @internal - */ -class Block -{ - /** - * @var string|null - */ - public $type; - - /** - * @var Block|null - */ - public $parent; - - /** - * @var string - */ - public $sourceName; - - /** - * @var int - */ - public $sourceIndex; - - /** - * @var int - */ - public $sourceLine; - - /** - * @var int - */ - public $sourceColumn; - - /** - * @var array|null - */ - public $selectors; - - /** - * @var array - */ - public $comments; - - /** - * @var array - */ - public $children; - - /** - * @var Block|null - */ - public $selfParent; -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Block/AtRootBlock.php b/plugins/admin/vendor/scssphp/scssphp/src/Block/AtRootBlock.php deleted file mode 100644 index 41842c2..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/Block/AtRootBlock.php +++ /dev/null @@ -1,37 +0,0 @@ -type = Type::T_AT_ROOT; - } -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Block/CallableBlock.php b/plugins/admin/vendor/scssphp/scssphp/src/Block/CallableBlock.php deleted file mode 100644 index 9b32d8c..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/Block/CallableBlock.php +++ /dev/null @@ -1,46 +0,0 @@ -|null - */ - public $args; - - /** - * @var Environment|null - */ - public $parentEnv; - - /** - * @param string $type - */ - public function __construct($type) - { - $this->type = $type; - } -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Block/ContentBlock.php b/plugins/admin/vendor/scssphp/scssphp/src/Block/ContentBlock.php deleted file mode 100644 index 8708498..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/Block/ContentBlock.php +++ /dev/null @@ -1,38 +0,0 @@ -type = Type::T_INCLUDE; - } -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Block/DirectiveBlock.php b/plugins/admin/vendor/scssphp/scssphp/src/Block/DirectiveBlock.php deleted file mode 100644 index 22b346e..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/Block/DirectiveBlock.php +++ /dev/null @@ -1,38 +0,0 @@ -type = Type::T_DIRECTIVE; - } -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Block/EachBlock.php b/plugins/admin/vendor/scssphp/scssphp/src/Block/EachBlock.php deleted file mode 100644 index 1217994..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/Block/EachBlock.php +++ /dev/null @@ -1,38 +0,0 @@ -type = Type::T_EACH; - } -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Block/ElseBlock.php b/plugins/admin/vendor/scssphp/scssphp/src/Block/ElseBlock.php deleted file mode 100644 index 6abb4d7..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/Block/ElseBlock.php +++ /dev/null @@ -1,27 +0,0 @@ -type = Type::T_ELSE; - } -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Block/ElseifBlock.php b/plugins/admin/vendor/scssphp/scssphp/src/Block/ElseifBlock.php deleted file mode 100644 index f732c2d..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/Block/ElseifBlock.php +++ /dev/null @@ -1,33 +0,0 @@ -type = Type::T_ELSEIF; - } -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Block/ForBlock.php b/plugins/admin/vendor/scssphp/scssphp/src/Block/ForBlock.php deleted file mode 100644 index 9629441..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/Block/ForBlock.php +++ /dev/null @@ -1,48 +0,0 @@ -type = Type::T_FOR; - } -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Block/IfBlock.php b/plugins/admin/vendor/scssphp/scssphp/src/Block/IfBlock.php deleted file mode 100644 index 659c7c2..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/Block/IfBlock.php +++ /dev/null @@ -1,38 +0,0 @@ - - */ - public $cases = []; - - public function __construct() - { - $this->type = Type::T_IF; - } -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Block/MediaBlock.php b/plugins/admin/vendor/scssphp/scssphp/src/Block/MediaBlock.php deleted file mode 100644 index ab975c7..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/Block/MediaBlock.php +++ /dev/null @@ -1,38 +0,0 @@ -type = Type::T_MEDIA; - } -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Block/NestedPropertyBlock.php b/plugins/admin/vendor/scssphp/scssphp/src/Block/NestedPropertyBlock.php deleted file mode 100644 index 1ea4a6c..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/Block/NestedPropertyBlock.php +++ /dev/null @@ -1,37 +0,0 @@ -type = Type::T_NESTED_PROPERTY; - } -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Block/WhileBlock.php b/plugins/admin/vendor/scssphp/scssphp/src/Block/WhileBlock.php deleted file mode 100644 index ac18d4e..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/Block/WhileBlock.php +++ /dev/null @@ -1,32 +0,0 @@ -type = Type::T_WHILE; - } -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Cache.php b/plugins/admin/vendor/scssphp/scssphp/src/Cache.php deleted file mode 100644 index 9731c60..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/Cache.php +++ /dev/null @@ -1,272 +0,0 @@ - - * - * @internal - */ -class Cache -{ - const CACHE_VERSION = 1; - - /** - * directory used for storing data - * - * @var string|false - */ - public static $cacheDir = false; - - /** - * prefix for the storing data - * - * @var string - */ - public static $prefix = 'scssphp_'; - - /** - * force a refresh : 'once' for refreshing the first hit on a cache only, true to never use the cache in this hit - * - * @var bool|string - */ - public static $forceRefresh = false; - - /** - * specifies the number of seconds after which data cached will be seen as 'garbage' and potentially cleaned up - * - * @var int - */ - public static $gcLifetime = 604800; - - /** - * array of already refreshed cache if $forceRefresh==='once' - * - * @var array - */ - protected static $refreshed = []; - - /** - * Constructor - * - * @param array $options - * - * @phpstan-param array{cacheDir?: string, prefix?: string, forceRefresh?: string} $options - */ - public function __construct($options) - { - // check $cacheDir - if (isset($options['cacheDir'])) { - self::$cacheDir = $options['cacheDir']; - } - - if (empty(self::$cacheDir)) { - throw new Exception('cacheDir not set'); - } - - if (isset($options['prefix'])) { - self::$prefix = $options['prefix']; - } - - if (empty(self::$prefix)) { - throw new Exception('prefix not set'); - } - - if (isset($options['forceRefresh'])) { - self::$forceRefresh = $options['forceRefresh']; - } - - self::checkCacheDir(); - } - - /** - * Get the cached result of $operation on $what, - * which is known as dependant from the content of $options - * - * @param string $operation parse, compile... - * @param mixed $what content key (e.g., filename to be treated) - * @param array $options any option that affect the operation result on the content - * @param int|null $lastModified last modified timestamp - * - * @return mixed - * - * @throws \Exception - */ - public function getCache($operation, $what, $options = [], $lastModified = null) - { - $fileCache = self::$cacheDir . self::cacheName($operation, $what, $options); - - if ( - ((self::$forceRefresh === false) || (self::$forceRefresh === 'once' && - isset(self::$refreshed[$fileCache]))) && file_exists($fileCache) - ) { - $cacheTime = filemtime($fileCache); - - if ( - (\is_null($lastModified) || $cacheTime > $lastModified) && - $cacheTime + self::$gcLifetime > time() - ) { - $c = file_get_contents($fileCache); - $c = unserialize($c); - - if (\is_array($c) && isset($c['value'])) { - return $c['value']; - } - } - } - - return null; - } - - /** - * Put in cache the result of $operation on $what, - * which is known as dependant from the content of $options - * - * @param string $operation - * @param mixed $what - * @param mixed $value - * @param array $options - * - * @return void - */ - public function setCache($operation, $what, $value, $options = []) - { - $fileCache = self::$cacheDir . self::cacheName($operation, $what, $options); - - $c = ['value' => $value]; - $c = serialize($c); - - file_put_contents($fileCache, $c); - - if (self::$forceRefresh === 'once') { - self::$refreshed[$fileCache] = true; - } - } - - /** - * Get the cache name for the caching of $operation on $what, - * which is known as dependant from the content of $options - * - * @param string $operation - * @param mixed $what - * @param array $options - * - * @return string - */ - private static function cacheName($operation, $what, $options = []) - { - $t = [ - 'version' => self::CACHE_VERSION, - 'scssphpVersion' => Version::VERSION, - 'operation' => $operation, - 'what' => $what, - 'options' => $options - ]; - - $t = self::$prefix - . sha1(json_encode($t)) - . ".$operation" - . ".scsscache"; - - return $t; - } - - /** - * Check that the cache dir exists and is writeable - * - * @return void - * - * @throws \Exception - */ - public static function checkCacheDir() - { - self::$cacheDir = str_replace('\\', '/', self::$cacheDir); - self::$cacheDir = rtrim(self::$cacheDir, '/') . '/'; - - if (! is_dir(self::$cacheDir)) { - throw new Exception('Cache directory doesn\'t exist: ' . self::$cacheDir); - } - - if (! is_writable(self::$cacheDir)) { - throw new Exception('Cache directory isn\'t writable: ' . self::$cacheDir); - } - } - - /** - * Delete unused cached files - * - * @return void - */ - public static function cleanCache() - { - static $clean = false; - - if ($clean || empty(self::$cacheDir)) { - return; - } - - $clean = true; - - // only remove files with extensions created by SCSSPHP Cache - // css files removed based on the list files - $removeTypes = ['scsscache' => 1]; - - $files = scandir(self::$cacheDir); - - if (! $files) { - return; - } - - $checkTime = time() - self::$gcLifetime; - - foreach ($files as $file) { - // don't delete if the file wasn't created with SCSSPHP Cache - if (strpos($file, self::$prefix) !== 0) { - continue; - } - - $parts = explode('.', $file); - $type = array_pop($parts); - - if (! isset($removeTypes[$type])) { - continue; - } - - $fullPath = self::$cacheDir . $file; - $mtime = filemtime($fullPath); - - // don't delete if it's a relatively new file - if ($mtime > $checkTime) { - continue; - } - - unlink($fullPath); - } - } -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Colors.php b/plugins/admin/vendor/scssphp/scssphp/src/Colors.php deleted file mode 100644 index 2df3999..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/Colors.php +++ /dev/null @@ -1,247 +0,0 @@ - - * - * @internal - */ -class Colors -{ - /** - * CSS Colors - * - * @see http://www.w3.org/TR/css3-color - * - * @var array - */ - protected static $cssColors = [ - 'aliceblue' => '240,248,255', - 'antiquewhite' => '250,235,215', - 'aqua' => '0,255,255', - 'cyan' => '0,255,255', - 'aquamarine' => '127,255,212', - 'azure' => '240,255,255', - 'beige' => '245,245,220', - 'bisque' => '255,228,196', - 'black' => '0,0,0', - 'blanchedalmond' => '255,235,205', - 'blue' => '0,0,255', - 'blueviolet' => '138,43,226', - 'brown' => '165,42,42', - 'burlywood' => '222,184,135', - 'cadetblue' => '95,158,160', - 'chartreuse' => '127,255,0', - 'chocolate' => '210,105,30', - 'coral' => '255,127,80', - 'cornflowerblue' => '100,149,237', - 'cornsilk' => '255,248,220', - 'crimson' => '220,20,60', - 'darkblue' => '0,0,139', - 'darkcyan' => '0,139,139', - 'darkgoldenrod' => '184,134,11', - 'darkgray' => '169,169,169', - 'darkgrey' => '169,169,169', - 'darkgreen' => '0,100,0', - 'darkkhaki' => '189,183,107', - 'darkmagenta' => '139,0,139', - 'darkolivegreen' => '85,107,47', - 'darkorange' => '255,140,0', - 'darkorchid' => '153,50,204', - 'darkred' => '139,0,0', - 'darksalmon' => '233,150,122', - 'darkseagreen' => '143,188,143', - 'darkslateblue' => '72,61,139', - 'darkslategray' => '47,79,79', - 'darkslategrey' => '47,79,79', - 'darkturquoise' => '0,206,209', - 'darkviolet' => '148,0,211', - 'deeppink' => '255,20,147', - 'deepskyblue' => '0,191,255', - 'dimgray' => '105,105,105', - 'dimgrey' => '105,105,105', - 'dodgerblue' => '30,144,255', - 'firebrick' => '178,34,34', - 'floralwhite' => '255,250,240', - 'forestgreen' => '34,139,34', - 'fuchsia' => '255,0,255', - 'magenta' => '255,0,255', - 'gainsboro' => '220,220,220', - 'ghostwhite' => '248,248,255', - 'gold' => '255,215,0', - 'goldenrod' => '218,165,32', - 'gray' => '128,128,128', - 'grey' => '128,128,128', - 'green' => '0,128,0', - 'greenyellow' => '173,255,47', - 'honeydew' => '240,255,240', - 'hotpink' => '255,105,180', - 'indianred' => '205,92,92', - 'indigo' => '75,0,130', - 'ivory' => '255,255,240', - 'khaki' => '240,230,140', - 'lavender' => '230,230,250', - 'lavenderblush' => '255,240,245', - 'lawngreen' => '124,252,0', - 'lemonchiffon' => '255,250,205', - 'lightblue' => '173,216,230', - 'lightcoral' => '240,128,128', - 'lightcyan' => '224,255,255', - 'lightgoldenrodyellow' => '250,250,210', - 'lightgray' => '211,211,211', - 'lightgrey' => '211,211,211', - 'lightgreen' => '144,238,144', - 'lightpink' => '255,182,193', - 'lightsalmon' => '255,160,122', - 'lightseagreen' => '32,178,170', - 'lightskyblue' => '135,206,250', - 'lightslategray' => '119,136,153', - 'lightslategrey' => '119,136,153', - 'lightsteelblue' => '176,196,222', - 'lightyellow' => '255,255,224', - 'lime' => '0,255,0', - 'limegreen' => '50,205,50', - 'linen' => '250,240,230', - 'maroon' => '128,0,0', - 'mediumaquamarine' => '102,205,170', - 'mediumblue' => '0,0,205', - 'mediumorchid' => '186,85,211', - 'mediumpurple' => '147,112,219', - 'mediumseagreen' => '60,179,113', - 'mediumslateblue' => '123,104,238', - 'mediumspringgreen' => '0,250,154', - 'mediumturquoise' => '72,209,204', - 'mediumvioletred' => '199,21,133', - 'midnightblue' => '25,25,112', - 'mintcream' => '245,255,250', - 'mistyrose' => '255,228,225', - 'moccasin' => '255,228,181', - 'navajowhite' => '255,222,173', - 'navy' => '0,0,128', - 'oldlace' => '253,245,230', - 'olive' => '128,128,0', - 'olivedrab' => '107,142,35', - 'orange' => '255,165,0', - 'orangered' => '255,69,0', - 'orchid' => '218,112,214', - 'palegoldenrod' => '238,232,170', - 'palegreen' => '152,251,152', - 'paleturquoise' => '175,238,238', - 'palevioletred' => '219,112,147', - 'papayawhip' => '255,239,213', - 'peachpuff' => '255,218,185', - 'peru' => '205,133,63', - 'pink' => '255,192,203', - 'plum' => '221,160,221', - 'powderblue' => '176,224,230', - 'purple' => '128,0,128', - 'red' => '255,0,0', - 'rosybrown' => '188,143,143', - 'royalblue' => '65,105,225', - 'saddlebrown' => '139,69,19', - 'salmon' => '250,128,114', - 'sandybrown' => '244,164,96', - 'seagreen' => '46,139,87', - 'seashell' => '255,245,238', - 'sienna' => '160,82,45', - 'silver' => '192,192,192', - 'skyblue' => '135,206,235', - 'slateblue' => '106,90,205', - 'slategray' => '112,128,144', - 'slategrey' => '112,128,144', - 'snow' => '255,250,250', - 'springgreen' => '0,255,127', - 'steelblue' => '70,130,180', - 'tan' => '210,180,140', - 'teal' => '0,128,128', - 'thistle' => '216,191,216', - 'tomato' => '255,99,71', - 'turquoise' => '64,224,208', - 'violet' => '238,130,238', - 'wheat' => '245,222,179', - 'white' => '255,255,255', - 'whitesmoke' => '245,245,245', - 'yellow' => '255,255,0', - 'yellowgreen' => '154,205,50', - 'rebeccapurple' => '102,51,153', - 'transparent' => '0,0,0,0', - ]; - - /** - * Convert named color in a [r,g,b[,a]] array - * - * @param string $colorName - * - * @return int[]|null - */ - public static function colorNameToRGBa($colorName) - { - if (\is_string($colorName) && isset(static::$cssColors[$colorName])) { - $rgba = explode(',', static::$cssColors[$colorName]); - - // only case with opacity is transparent, with opacity=0, so we can intval on opacity also - $rgba = array_map('intval', $rgba); - - return $rgba; - } - - return null; - } - - /** - * Reverse conversion : from RGBA to a color name if possible - * - * @param int $r - * @param int $g - * @param int $b - * @param int|float $a - * - * @return string|null - */ - public static function RGBaToColorName($r, $g, $b, $a = 1) - { - static $reverseColorTable = null; - - if (! is_numeric($r) || ! is_numeric($g) || ! is_numeric($b) || ! is_numeric($a)) { - return null; - } - - if ($a < 1) { - return null; - } - - if (\is_null($reverseColorTable)) { - $reverseColorTable = []; - - foreach (static::$cssColors as $name => $rgb_str) { - $rgb_str = explode(',', $rgb_str); - - if ( - \count($rgb_str) == 3 && - ! isset($reverseColorTable[\intval($rgb_str[0])][\intval($rgb_str[1])][\intval($rgb_str[2])]) - ) { - $reverseColorTable[\intval($rgb_str[0])][\intval($rgb_str[1])][\intval($rgb_str[2])] = $name; - } - } - } - - if (isset($reverseColorTable[\intval($r)][\intval($g)][\intval($b)])) { - return $reverseColorTable[\intval($r)][\intval($g)][\intval($b)]; - } - - return null; - } -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/CompilationResult.php b/plugins/admin/vendor/scssphp/scssphp/src/CompilationResult.php deleted file mode 100644 index 36adb0d..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/CompilationResult.php +++ /dev/null @@ -1,69 +0,0 @@ -css = $css; - $this->sourceMap = $sourceMap; - $this->includedFiles = $includedFiles; - } - - /** - * @return string - */ - public function getCss() - { - return $this->css; - } - - /** - * @return string[] - */ - public function getIncludedFiles() - { - return $this->includedFiles; - } - - /** - * The sourceMap content, if it was generated - * - * @return null|string - */ - public function getSourceMap() - { - return $this->sourceMap; - } -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Compiler.php b/plugins/admin/vendor/scssphp/scssphp/src/Compiler.php deleted file mode 100644 index d654ee6..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/Compiler.php +++ /dev/null @@ -1,10514 +0,0 @@ - - * - * @final Extending the Compiler is deprecated - */ -class Compiler -{ - /** - * @deprecated - */ - const LINE_COMMENTS = 1; - /** - * @deprecated - */ - const DEBUG_INFO = 2; - - /** - * @deprecated - */ - const WITH_RULE = 1; - /** - * @deprecated - */ - const WITH_MEDIA = 2; - /** - * @deprecated - */ - const WITH_SUPPORTS = 4; - /** - * @deprecated - */ - const WITH_ALL = 7; - - const SOURCE_MAP_NONE = 0; - const SOURCE_MAP_INLINE = 1; - const SOURCE_MAP_FILE = 2; - - /** - * @var array - */ - protected static $operatorNames = [ - '+' => 'add', - '-' => 'sub', - '*' => 'mul', - '/' => 'div', - '%' => 'mod', - - '==' => 'eq', - '!=' => 'neq', - '<' => 'lt', - '>' => 'gt', - - '<=' => 'lte', - '>=' => 'gte', - ]; - - /** - * @var array - */ - protected static $namespaces = [ - 'special' => '%', - 'mixin' => '@', - 'function' => '^', - ]; - - public static $true = [Type::T_KEYWORD, 'true']; - public static $false = [Type::T_KEYWORD, 'false']; - /** @deprecated */ - public static $NaN = [Type::T_KEYWORD, 'NaN']; - /** @deprecated */ - public static $Infinity = [Type::T_KEYWORD, 'Infinity']; - public static $null = [Type::T_NULL]; - /** - * @internal - */ - public static $nullString = [Type::T_STRING, '', []]; - /** - * @internal - */ - public static $defaultValue = [Type::T_KEYWORD, '']; - /** - * @internal - */ - public static $selfSelector = [Type::T_SELF]; - public static $emptyList = [Type::T_LIST, '', []]; - public static $emptyMap = [Type::T_MAP, [], []]; - public static $emptyString = [Type::T_STRING, '"', []]; - /** - * @internal - */ - public static $with = [Type::T_KEYWORD, 'with']; - /** - * @internal - */ - public static $without = [Type::T_KEYWORD, 'without']; - private static $emptyArgumentList = [Type::T_LIST, '', [], []]; - - /** - * @var array - */ - protected $importPaths = []; - /** - * @var array - */ - protected $importCache = []; - - /** - * @var string[] - */ - protected $importedFiles = []; - - /** - * @var array - * @phpstan-var array - */ - protected $userFunctions = []; - /** - * @var array - */ - protected $registeredVars = []; - /** - * @var array - */ - protected $registeredFeatures = [ - 'extend-selector-pseudoclass' => false, - 'at-error' => true, - 'units-level-3' => true, - 'global-variable-shadowing' => false, - ]; - - /** - * @var string|null - */ - protected $encoding = null; - /** - * @var null - * @deprecated - */ - protected $lineNumberStyle = null; - - /** - * @var int|SourceMapGenerator - * @phpstan-var self::SOURCE_MAP_*|SourceMapGenerator - */ - protected $sourceMap = self::SOURCE_MAP_NONE; - - /** - * @var array - * @phpstan-var array{sourceRoot?: string, sourceMapFilename?: string|null, sourceMapURL?: string|null, sourceMapWriteTo?: string|null, outputSourceFiles?: bool, sourceMapRootpath?: string, sourceMapBasepath?: string} - */ - protected $sourceMapOptions = []; - - /** - * @var bool - */ - private $charset = true; - - /** - * @var Formatter - */ - protected $formatter; - - /** - * @var string - * @phpstan-var class-string - */ - private $configuredFormatter = Expanded::class; - - /** - * @var Environment - */ - protected $rootEnv; - /** - * @var OutputBlock|null - */ - protected $rootBlock; - - /** - * @var \ScssPhp\ScssPhp\Compiler\Environment - */ - protected $env; - /** - * @var OutputBlock|null - */ - protected $scope; - /** - * @var Environment|null - */ - protected $storeEnv; - /** - * @var bool|null - * - * @deprecated - */ - protected $charsetSeen; - /** - * @var array - */ - protected $sourceNames; - - /** - * @var Cache|null - */ - protected $cache; - - /** - * @var bool - */ - protected $cacheCheckImportResolutions = false; - - /** - * @var int - */ - protected $indentLevel; - /** - * @var array[] - */ - protected $extends; - /** - * @var array - */ - protected $extendsMap; - - /** - * @var array - */ - protected $parsedFiles = []; - - /** - * @var Parser|null - */ - protected $parser; - /** - * @var int|null - */ - protected $sourceIndex; - /** - * @var int|null - */ - protected $sourceLine; - /** - * @var int|null - */ - protected $sourceColumn; - /** - * @var bool|null - */ - protected $shouldEvaluate; - /** - * @var null - * @deprecated - */ - protected $ignoreErrors; - /** - * @var bool - */ - protected $ignoreCallStackMessage = false; - - /** - * @var array[] - */ - protected $callStack = []; - - /** - * @var array - * @phpstan-var list - */ - private $resolvedImports = []; - - /** - * The directory of the currently processed file - * - * @var string|null - */ - private $currentDirectory; - - /** - * The directory of the input file - * - * @var string - */ - private $rootDirectory; - - /** - * @var bool - */ - private $legacyCwdImportPath = true; - - /** - * @var LoggerInterface - */ - private $logger; - - /** - * @var array - */ - private $warnedChildFunctions = []; - - /** - * Constructor - * - * @param array|null $cacheOptions - * @phpstan-param array{cacheDir?: string, prefix?: string, forceRefresh?: string, checkImportResolutions?: bool}|null $cacheOptions - */ - public function __construct($cacheOptions = null) - { - $this->sourceNames = []; - - if ($cacheOptions) { - $this->cache = new Cache($cacheOptions); - if (!empty($cacheOptions['checkImportResolutions'])) { - $this->cacheCheckImportResolutions = true; - } - } - - $this->logger = new StreamLogger(fopen('php://stderr', 'w'), true); - } - - /** - * Get compiler options - * - * @return array - * - * @internal - */ - public function getCompileOptions() - { - $options = [ - 'importPaths' => $this->importPaths, - 'registeredVars' => $this->registeredVars, - 'registeredFeatures' => $this->registeredFeatures, - 'encoding' => $this->encoding, - 'sourceMap' => serialize($this->sourceMap), - 'sourceMapOptions' => $this->sourceMapOptions, - 'formatter' => $this->configuredFormatter, - 'legacyImportPath' => $this->legacyCwdImportPath, - ]; - - return $options; - } - - /** - * Sets an alternative logger. - * - * Changing the logger in the middle of the compilation is not - * supported and will result in an undefined behavior. - * - * @param LoggerInterface $logger - * - * @return void - */ - public function setLogger(LoggerInterface $logger) - { - $this->logger = $logger; - } - - /** - * Set an alternative error output stream, for testing purpose only - * - * @param resource $handle - * - * @return void - * - * @deprecated Use {@see setLogger} instead - */ - public function setErrorOuput($handle) - { - @trigger_error('The method "setErrorOuput" is deprecated. Use "setLogger" instead.', E_USER_DEPRECATED); - - $this->logger = new StreamLogger($handle); - } - - /** - * Compile scss - * - * @param string $code - * @param string|null $path - * - * @return string - * - * @throws SassException when the source fails to compile - * - * @deprecated Use {@see compileString} instead. - */ - public function compile($code, $path = null) - { - @trigger_error(sprintf('The "%s" method is deprecated. Use "compileString" instead.', __METHOD__), E_USER_DEPRECATED); - - $result = $this->compileString($code, $path); - - $sourceMap = $result->getSourceMap(); - - if ($sourceMap !== null) { - if ($this->sourceMap instanceof SourceMapGenerator) { - $this->sourceMap->saveMap($sourceMap); - } elseif ($this->sourceMap === self::SOURCE_MAP_FILE) { - $sourceMapGenerator = new SourceMapGenerator($this->sourceMapOptions); - $sourceMapGenerator->saveMap($sourceMap); - } - } - - return $result->getCss(); - } - - /** - * Compiles the provided scss file into CSS. - * - * @param string $path - * - * @return CompilationResult - * - * @throws SassException when the source fails to compile - */ - public function compileFile($path) - { - $source = file_get_contents($path); - - if ($source === false) { - throw new \RuntimeException('Could not read the file content'); - } - - return $this->compileString($source, $path); - } - - /** - * Compiles the provided scss source code into CSS. - * - * If provided, the path is considered to be the path from which the source code comes - * from, which will be used to resolve relative imports. - * - * @param string $source - * @param string|null $path The path for the source, used to resolve relative imports - * - * @return CompilationResult - * - * @throws SassException when the source fails to compile - */ - public function compileString($source, $path = null) - { - if ($this->cache) { - $cacheKey = ($path ? $path : '(stdin)') . ':' . md5($source); - $compileOptions = $this->getCompileOptions(); - $cachedResult = $this->cache->getCache('compile', $cacheKey, $compileOptions); - - if ($cachedResult instanceof CachedResult && $this->isFreshCachedResult($cachedResult)) { - return $cachedResult->getResult(); - } - } - - $this->indentLevel = -1; - $this->extends = []; - $this->extendsMap = []; - $this->sourceIndex = null; - $this->sourceLine = null; - $this->sourceColumn = null; - $this->env = null; - $this->scope = null; - $this->storeEnv = null; - $this->shouldEvaluate = null; - $this->ignoreCallStackMessage = false; - $this->parsedFiles = []; - $this->importedFiles = []; - $this->resolvedImports = []; - - if (!\is_null($path) && is_file($path)) { - $path = realpath($path) ?: $path; - $this->currentDirectory = dirname($path); - $this->rootDirectory = $this->currentDirectory; - } else { - $this->currentDirectory = null; - $this->rootDirectory = getcwd(); - } - - try { - $this->parser = $this->parserFactory($path); - $tree = $this->parser->parse($source); - $this->parser = null; - - $this->formatter = new $this->configuredFormatter(); - $this->rootBlock = null; - $this->rootEnv = $this->pushEnv($tree); - - $warnCallback = function ($message, $deprecation) { - $this->logger->warn($message, $deprecation); - }; - $previousWarnCallback = Warn::setCallback($warnCallback); - - try { - $this->injectVariables($this->registeredVars); - $this->compileRoot($tree); - $this->popEnv(); - } finally { - Warn::setCallback($previousWarnCallback); - } - - $sourceMapGenerator = null; - - if ($this->sourceMap) { - if (\is_object($this->sourceMap) && $this->sourceMap instanceof SourceMapGenerator) { - $sourceMapGenerator = $this->sourceMap; - $this->sourceMap = self::SOURCE_MAP_FILE; - } elseif ($this->sourceMap !== self::SOURCE_MAP_NONE) { - $sourceMapGenerator = new SourceMapGenerator($this->sourceMapOptions); - } - } - assert($this->scope !== null); - - $out = $this->formatter->format($this->scope, $sourceMapGenerator); - - $prefix = ''; - - if ($this->charset && strlen($out) !== Util::mbStrlen($out)) { - $prefix = '@charset "UTF-8";' . "\n"; - $out = $prefix . $out; - } - - $sourceMap = null; - - if (! empty($out) && $this->sourceMap !== self::SOURCE_MAP_NONE && $this->sourceMap) { - assert($sourceMapGenerator !== null); - $sourceMap = $sourceMapGenerator->generateJson($prefix); - $sourceMapUrl = null; - - switch ($this->sourceMap) { - case self::SOURCE_MAP_INLINE: - $sourceMapUrl = sprintf('data:application/json,%s', Util::encodeURIComponent($sourceMap)); - break; - - case self::SOURCE_MAP_FILE: - if (isset($this->sourceMapOptions['sourceMapURL'])) { - $sourceMapUrl = $this->sourceMapOptions['sourceMapURL']; - } - break; - } - - if ($sourceMapUrl !== null) { - $out .= sprintf('/*# sourceMappingURL=%s */', $sourceMapUrl); - } - } - } catch (SassScriptException $e) { - throw new CompilerException($this->addLocationToMessage($e->getMessage()), 0, $e); - } - - $includedFiles = []; - - foreach ($this->resolvedImports as $resolvedImport) { - $includedFiles[$resolvedImport['filePath']] = $resolvedImport['filePath']; - } - - $result = new CompilationResult($out, $sourceMap, array_values($includedFiles)); - - if ($this->cache && isset($cacheKey) && isset($compileOptions)) { - $this->cache->setCache('compile', $cacheKey, new CachedResult($result, $this->parsedFiles, $this->resolvedImports), $compileOptions); - } - - // Reset state to free memory - // TODO in 2.0, reset parsedFiles as well when the getter is removed. - $this->resolvedImports = []; - $this->importedFiles = []; - - return $result; - } - - /** - * @param CachedResult $result - * - * @return bool - */ - private function isFreshCachedResult(CachedResult $result) - { - // check if any dependency file changed since the result was compiled - foreach ($result->getParsedFiles() as $file => $mtime) { - if (! is_file($file) || filemtime($file) !== $mtime) { - return false; - } - } - - if ($this->cacheCheckImportResolutions) { - $resolvedImports = []; - - foreach ($result->getResolvedImports() as $import) { - $currentDir = $import['currentDir']; - $path = $import['path']; - // store the check across all the results in memory to avoid multiple findImport() on the same path - // with same context. - // this is happening in a same hit with multiple compilations (especially with big frameworks) - if (empty($resolvedImports[$currentDir][$path])) { - $resolvedImports[$currentDir][$path] = $this->findImport($path, $currentDir); - } - - if ($resolvedImports[$currentDir][$path] !== $import['filePath']) { - return false; - } - } - } - - return true; - } - - /** - * Instantiate parser - * - * @param string|null $path - * - * @return \ScssPhp\ScssPhp\Parser - */ - protected function parserFactory($path) - { - // https://sass-lang.com/documentation/at-rules/import - // CSS files imported by Sass don’t allow any special Sass features. - // In order to make sure authors don’t accidentally write Sass in their CSS, - // all Sass features that aren’t also valid CSS will produce errors. - // Otherwise, the CSS will be rendered as-is. It can even be extended! - $cssOnly = false; - - if ($path !== null && substr($path, -4) === '.css') { - $cssOnly = true; - } - - $parser = new Parser($path, \count($this->sourceNames), $this->encoding, $this->cache, $cssOnly, $this->logger); - - $this->sourceNames[] = $path; - $this->addParsedFile($path); - - return $parser; - } - - /** - * Is self extend? - * - * @param array $target - * @param array $origin - * - * @return bool - */ - protected function isSelfExtend($target, $origin) - { - foreach ($origin as $sel) { - if (\in_array($target, $sel)) { - return true; - } - } - - return false; - } - - /** - * Push extends - * - * @param string[] $target - * @param array $origin - * @param array|null $block - * - * @return void - */ - protected function pushExtends($target, $origin, $block) - { - $i = \count($this->extends); - $this->extends[] = [$target, $origin, $block]; - - foreach ($target as $part) { - if (isset($this->extendsMap[$part])) { - $this->extendsMap[$part][] = $i; - } else { - $this->extendsMap[$part] = [$i]; - } - } - } - - /** - * Make output block - * - * @param string|null $type - * @param string[]|null $selectors - * - * @return \ScssPhp\ScssPhp\Formatter\OutputBlock - */ - protected function makeOutputBlock($type, $selectors = null) - { - $out = new OutputBlock(); - $out->type = $type; - $out->lines = []; - $out->children = []; - $out->parent = $this->scope; - $out->selectors = $selectors; - $out->depth = $this->env->depth; - - if ($this->env->block instanceof Block) { - $out->sourceName = $this->env->block->sourceName; - $out->sourceLine = $this->env->block->sourceLine; - $out->sourceColumn = $this->env->block->sourceColumn; - } else { - $out->sourceName = isset($this->sourceNames[$this->sourceIndex]) ? $this->sourceNames[$this->sourceIndex] : '(stdin)'; - $out->sourceLine = $this->sourceLine; - $out->sourceColumn = $this->sourceColumn; - } - - return $out; - } - - /** - * Compile root - * - * @param \ScssPhp\ScssPhp\Block $rootBlock - * - * @return void - */ - protected function compileRoot(Block $rootBlock) - { - $this->rootBlock = $this->scope = $this->makeOutputBlock(Type::T_ROOT); - - $this->compileChildrenNoReturn($rootBlock->children, $this->scope); - assert($this->scope !== null); - $this->flattenSelectors($this->scope); - $this->missingSelectors(); - } - - /** - * Report missing selectors - * - * @return void - */ - protected function missingSelectors() - { - foreach ($this->extends as $extend) { - if (isset($extend[3])) { - continue; - } - - list($target, $origin, $block) = $extend; - - // ignore if !optional - if ($block[2]) { - continue; - } - - $target = implode(' ', $target); - $origin = $this->collapseSelectors($origin); - - $this->sourceLine = $block[Parser::SOURCE_LINE]; - throw $this->error("\"$origin\" failed to @extend \"$target\". The selector \"$target\" was not found."); - } - } - - /** - * Flatten selectors - * - * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block - * @param string $parentKey - * - * @return void - */ - protected function flattenSelectors(OutputBlock $block, $parentKey = null) - { - if ($block->selectors) { - $selectors = []; - - foreach ($block->selectors as $s) { - $selectors[] = $s; - - if (! \is_array($s)) { - continue; - } - - // check extends - if (! empty($this->extendsMap)) { - $this->matchExtends($s, $selectors); - - // remove duplicates - array_walk($selectors, function (&$value) { - $value = serialize($value); - }); - - $selectors = array_unique($selectors); - - array_walk($selectors, function (&$value) { - $value = unserialize($value); - }); - } - } - - $block->selectors = []; - $placeholderSelector = false; - - foreach ($selectors as $selector) { - if ($this->hasSelectorPlaceholder($selector)) { - $placeholderSelector = true; - continue; - } - - $block->selectors[] = $this->compileSelector($selector); - } - - if ($placeholderSelector && 0 === \count($block->selectors) && null !== $parentKey) { - assert($block->parent !== null); - unset($block->parent->children[$parentKey]); - - return; - } - } - - foreach ($block->children as $key => $child) { - $this->flattenSelectors($child, $key); - } - } - - /** - * Glue parts of :not( or :nth-child( ... that are in general split in selectors parts - * - * @param array $parts - * - * @return array - */ - protected function glueFunctionSelectors($parts) - { - $new = []; - - foreach ($parts as $part) { - if (\is_array($part)) { - $part = $this->glueFunctionSelectors($part); - $new[] = $part; - } else { - // a selector part finishing with a ) is the last part of a :not( or :nth-child( - // and need to be joined to this - if ( - \count($new) && \is_string($new[\count($new) - 1]) && - \strlen($part) && substr($part, -1) === ')' && strpos($part, '(') === false - ) { - while (\count($new) > 1 && substr($new[\count($new) - 1], -1) !== '(') { - $part = array_pop($new) . $part; - } - $new[\count($new) - 1] .= $part; - } else { - $new[] = $part; - } - } - } - - return $new; - } - - /** - * Match extends - * - * @param array $selector - * @param array $out - * @param int $from - * @param bool $initial - * - * @return void - */ - protected function matchExtends($selector, &$out, $from = 0, $initial = true) - { - static $partsPile = []; - $selector = $this->glueFunctionSelectors($selector); - - if (\count($selector) == 1 && \in_array(reset($selector), $partsPile)) { - return; - } - - $outRecurs = []; - - foreach ($selector as $i => $part) { - if ($i < $from) { - continue; - } - - // check that we are not building an infinite loop of extensions - // if the new part is just including a previous part don't try to extend anymore - if (\count($part) > 1) { - foreach ($partsPile as $previousPart) { - if (! \count(array_diff($previousPart, $part))) { - continue 2; - } - } - } - - $partsPile[] = $part; - - if ($this->matchExtendsSingle($part, $origin, $initial)) { - $after = \array_slice($selector, $i + 1); - $before = \array_slice($selector, 0, $i); - list($before, $nonBreakableBefore) = $this->extractRelationshipFromFragment($before); - - foreach ($origin as $new) { - $k = 0; - - // remove shared parts - if (\count($new) > 1) { - while ($k < $i && isset($new[$k]) && $selector[$k] === $new[$k]) { - $k++; - } - } - - if (\count($nonBreakableBefore) && $k === \count($new)) { - $k--; - } - - $replacement = []; - $tempReplacement = $k > 0 ? \array_slice($new, $k) : $new; - - for ($l = \count($tempReplacement) - 1; $l >= 0; $l--) { - $slice = []; - - foreach ($tempReplacement[$l] as $chunk) { - if (! \in_array($chunk, $slice)) { - $slice[] = $chunk; - } - } - - array_unshift($replacement, $slice); - - if (! $this->isImmediateRelationshipCombinator(end($slice))) { - break; - } - } - - $afterBefore = $l != 0 ? \array_slice($tempReplacement, 0, $l) : []; - - // Merge shared direct relationships. - $mergedBefore = $this->mergeDirectRelationships($afterBefore, $nonBreakableBefore); - - $result = array_merge( - $before, - $mergedBefore, - $replacement, - $after - ); - - if ($result === $selector) { - continue; - } - - $this->pushOrMergeExtentedSelector($out, $result); - - // recursively check for more matches - $startRecurseFrom = \count($before) + min(\count($nonBreakableBefore), \count($mergedBefore)); - - if (\count($origin) > 1) { - $this->matchExtends($result, $out, $startRecurseFrom, false); - } else { - $this->matchExtends($result, $outRecurs, $startRecurseFrom, false); - } - - // selector sequence merging - if (! empty($before) && \count($new) > 1) { - $preSharedParts = $k > 0 ? \array_slice($before, 0, $k) : []; - $postSharedParts = $k > 0 ? \array_slice($before, $k) : $before; - - list($betweenSharedParts, $nonBreakabl2) = $this->extractRelationshipFromFragment($afterBefore); - - $result2 = array_merge( - $preSharedParts, - $betweenSharedParts, - $postSharedParts, - $nonBreakabl2, - $nonBreakableBefore, - $replacement, - $after - ); - - $this->pushOrMergeExtentedSelector($out, $result2); - } - } - } - array_pop($partsPile); - } - - while (\count($outRecurs)) { - $result = array_shift($outRecurs); - $this->pushOrMergeExtentedSelector($out, $result); - } - } - - /** - * Test a part for being a pseudo selector - * - * @param string $part - * @param array $matches - * - * @return bool - */ - protected function isPseudoSelector($part, &$matches) - { - if ( - strpos($part, ':') === 0 && - preg_match(",^::?([\w-]+)\((.+)\)$,", $part, $matches) - ) { - return true; - } - - return false; - } - - /** - * Push extended selector except if - * - this is a pseudo selector - * - same as previous - * - in a white list - * in this case we merge the pseudo selector content - * - * @param array $out - * @param array $extended - * - * @return void - */ - protected function pushOrMergeExtentedSelector(&$out, $extended) - { - if (\count($out) && \count($extended) === 1 && \count(reset($extended)) === 1) { - $single = reset($extended); - $part = reset($single); - - if ( - $this->isPseudoSelector($part, $matchesExtended) && - \in_array($matchesExtended[1], [ 'slotted' ]) - ) { - $prev = end($out); - $prev = $this->glueFunctionSelectors($prev); - - if (\count($prev) === 1 && \count(reset($prev)) === 1) { - $single = reset($prev); - $part = reset($single); - - if ( - $this->isPseudoSelector($part, $matchesPrev) && - $matchesPrev[1] === $matchesExtended[1] - ) { - $extended = explode($matchesExtended[1] . '(', $matchesExtended[0], 2); - $extended[1] = $matchesPrev[2] . ', ' . $extended[1]; - $extended = implode($matchesExtended[1] . '(', $extended); - $extended = [ [ $extended ]]; - array_pop($out); - } - } - } - } - $out[] = $extended; - } - - /** - * Match extends single - * - * @param array $rawSingle - * @param array $outOrigin - * @param bool $initial - * - * @return bool - */ - protected function matchExtendsSingle($rawSingle, &$outOrigin, $initial = true) - { - $counts = []; - $single = []; - - // simple usual cases, no need to do the whole trick - if (\in_array($rawSingle, [['>'],['+'],['~']])) { - return false; - } - - foreach ($rawSingle as $part) { - // matches Number - if (! \is_string($part)) { - return false; - } - - if (! preg_match('/^[\[.:#%]/', $part) && \count($single)) { - $single[\count($single) - 1] .= $part; - } else { - $single[] = $part; - } - } - - $extendingDecoratedTag = false; - - if (\count($single) > 1) { - $matches = null; - $extendingDecoratedTag = preg_match('/^[a-z0-9]+$/i', $single[0], $matches) ? $matches[0] : false; - } - - $outOrigin = []; - $found = false; - - foreach ($single as $k => $part) { - if (isset($this->extendsMap[$part])) { - foreach ($this->extendsMap[$part] as $idx) { - $counts[$idx] = isset($counts[$idx]) ? $counts[$idx] + 1 : 1; - } - } - - if ( - $initial && - $this->isPseudoSelector($part, $matches) && - ! \in_array($matches[1], [ 'not' ]) - ) { - $buffer = $matches[2]; - $parser = $this->parserFactory(__METHOD__); - - if ($parser->parseSelector($buffer, $subSelectors, false)) { - foreach ($subSelectors as $ksub => $subSelector) { - $subExtended = []; - $this->matchExtends($subSelector, $subExtended, 0, false); - - if ($subExtended) { - $subSelectorsExtended = $subSelectors; - $subSelectorsExtended[$ksub] = $subExtended; - - foreach ($subSelectorsExtended as $ksse => $sse) { - $subSelectorsExtended[$ksse] = $this->collapseSelectors($sse); - } - - $subSelectorsExtended = implode(', ', $subSelectorsExtended); - $singleExtended = $single; - $singleExtended[$k] = str_replace('(' . $buffer . ')', "($subSelectorsExtended)", $part); - $outOrigin[] = [ $singleExtended ]; - $found = true; - } - } - } - } - } - - foreach ($counts as $idx => $count) { - list($target, $origin, /* $block */) = $this->extends[$idx]; - - $origin = $this->glueFunctionSelectors($origin); - - // check count - if ($count !== \count($target)) { - continue; - } - - $this->extends[$idx][3] = true; - - $rem = array_diff($single, $target); - - foreach ($origin as $j => $new) { - // prevent infinite loop when target extends itself - if ($this->isSelfExtend($single, $origin) && ! $initial) { - return false; - } - - $replacement = end($new); - - // Extending a decorated tag with another tag is not possible. - if ( - $extendingDecoratedTag && $replacement[0] != $extendingDecoratedTag && - preg_match('/^[a-z0-9]+$/i', $replacement[0]) - ) { - unset($origin[$j]); - continue; - } - - $combined = $this->combineSelectorSingle($replacement, $rem); - - if (\count(array_diff($combined, $origin[$j][\count($origin[$j]) - 1]))) { - $origin[$j][\count($origin[$j]) - 1] = $combined; - } - } - - $outOrigin = array_merge($outOrigin, $origin); - - $found = true; - } - - return $found; - } - - /** - * Extract a relationship from the fragment. - * - * When extracting the last portion of a selector we will be left with a - * fragment which may end with a direction relationship combinator. This - * method will extract the relationship fragment and return it along side - * the rest. - * - * @param array $fragment The selector fragment maybe ending with a direction relationship combinator. - * - * @return array The selector without the relationship fragment if any, the relationship fragment. - */ - protected function extractRelationshipFromFragment(array $fragment) - { - $parents = []; - $children = []; - - $j = $i = \count($fragment); - - for (;;) { - $children = $j != $i ? \array_slice($fragment, $j, $i - $j) : []; - $parents = \array_slice($fragment, 0, $j); - $slice = end($parents); - - if (empty($slice) || ! $this->isImmediateRelationshipCombinator($slice[0])) { - break; - } - - $j -= 2; - } - - return [$parents, $children]; - } - - /** - * Combine selector single - * - * @param array $base - * @param array $other - * - * @return array - */ - protected function combineSelectorSingle($base, $other) - { - $tag = []; - $out = []; - $wasTag = false; - $pseudo = []; - - while (\count($other) && strpos(end($other), ':') === 0) { - array_unshift($pseudo, array_pop($other)); - } - - foreach ([array_reverse($base), array_reverse($other)] as $single) { - $rang = count($single); - - foreach ($single as $part) { - if (preg_match('/^[\[:]/', $part)) { - $out[] = $part; - $wasTag = false; - } elseif (preg_match('/^[\.#]/', $part)) { - array_unshift($out, $part); - $wasTag = false; - } elseif (preg_match('/^[^_-]/', $part) && $rang === 1) { - $tag[] = $part; - $wasTag = true; - } elseif ($wasTag) { - $tag[\count($tag) - 1] .= $part; - } else { - array_unshift($out, $part); - } - $rang--; - } - } - - if (\count($tag)) { - array_unshift($out, $tag[0]); - } - - while (\count($pseudo)) { - $out[] = array_shift($pseudo); - } - - return $out; - } - - /** - * Compile media - * - * @param \ScssPhp\ScssPhp\Block $media - * - * @return void - */ - protected function compileMedia(Block $media) - { - assert($media instanceof MediaBlock); - $this->pushEnv($media); - - $mediaQueries = $this->compileMediaQuery($this->multiplyMedia($this->env)); - - if (! empty($mediaQueries)) { - assert($this->scope !== null); - $previousScope = $this->scope; - $parentScope = $this->mediaParent($this->scope); - - foreach ($mediaQueries as $mediaQuery) { - $this->scope = $this->makeOutputBlock(Type::T_MEDIA, [$mediaQuery]); - - $parentScope->children[] = $this->scope; - $parentScope = $this->scope; - } - - // top level properties in a media cause it to be wrapped - $needsWrap = false; - - foreach ($media->children as $child) { - $type = $child[0]; - - if ( - $type !== Type::T_BLOCK && - $type !== Type::T_MEDIA && - $type !== Type::T_DIRECTIVE && - $type !== Type::T_IMPORT - ) { - $needsWrap = true; - break; - } - } - - if ($needsWrap) { - $wrapped = new Block(); - $wrapped->sourceName = $media->sourceName; - $wrapped->sourceIndex = $media->sourceIndex; - $wrapped->sourceLine = $media->sourceLine; - $wrapped->sourceColumn = $media->sourceColumn; - $wrapped->selectors = []; - $wrapped->comments = []; - $wrapped->parent = $media; - $wrapped->children = $media->children; - - $media->children = [[Type::T_BLOCK, $wrapped]]; - } - - $this->compileChildrenNoReturn($media->children, $this->scope); - - $this->scope = $previousScope; - } - - $this->popEnv(); - } - - /** - * Media parent - * - * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $scope - * - * @return \ScssPhp\ScssPhp\Formatter\OutputBlock - */ - protected function mediaParent(OutputBlock $scope) - { - while (! empty($scope->parent)) { - if (! empty($scope->type) && $scope->type !== Type::T_MEDIA) { - break; - } - - $scope = $scope->parent; - } - - return $scope; - } - - /** - * Compile directive - * - * @param DirectiveBlock|array $directive - * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $out - * - * @return void - */ - protected function compileDirective($directive, OutputBlock $out) - { - if (\is_array($directive)) { - $directiveName = $this->compileDirectiveName($directive[0]); - $s = '@' . $directiveName; - - if (! empty($directive[1])) { - $s .= ' ' . $this->compileValue($directive[1]); - } - // sass-spec compliance on newline after directives, a bit tricky :/ - $appendNewLine = (! empty($directive[2]) || strpos($s, "\n")) ? "\n" : ""; - if (\is_array($directive[0]) && empty($directive[1])) { - $appendNewLine = "\n"; - } - - if (empty($directive[3])) { - $this->appendRootDirective($s . ';' . $appendNewLine, $out, [Type::T_COMMENT, Type::T_DIRECTIVE]); - } else { - $this->appendOutputLine($out, Type::T_DIRECTIVE, $s . ';'); - } - } else { - $directive->name = $this->compileDirectiveName($directive->name); - $s = '@' . $directive->name; - - if (! empty($directive->value)) { - $s .= ' ' . $this->compileValue($directive->value); - } - - if ($directive->name === 'keyframes' || substr($directive->name, -10) === '-keyframes') { - $this->compileKeyframeBlock($directive, [$s]); - } else { - $this->compileNestedBlock($directive, [$s]); - } - } - } - - /** - * directive names can include some interpolation - * - * @param string|array $directiveName - * @return string - * @throws CompilerException - */ - protected function compileDirectiveName($directiveName) - { - if (is_string($directiveName)) { - return $directiveName; - } - - return $this->compileValue($directiveName); - } - - /** - * Compile at-root - * - * @param \ScssPhp\ScssPhp\Block $block - * - * @return void - */ - protected function compileAtRoot(Block $block) - { - assert($block instanceof AtRootBlock); - $env = $this->pushEnv($block); - $envs = $this->compactEnv($env); - list($with, $without) = $this->compileWith(isset($block->with) ? $block->with : null); - - // wrap inline selector - if ($block->selector) { - $wrapped = new Block(); - $wrapped->sourceName = $block->sourceName; - $wrapped->sourceIndex = $block->sourceIndex; - $wrapped->sourceLine = $block->sourceLine; - $wrapped->sourceColumn = $block->sourceColumn; - $wrapped->selectors = $block->selector; - $wrapped->comments = []; - $wrapped->parent = $block; - $wrapped->children = $block->children; - $wrapped->selfParent = $block->selfParent; - - $block->children = [[Type::T_BLOCK, $wrapped]]; - $block->selector = null; - } - - $selfParent = $block->selfParent; - assert($selfParent !== null, 'at-root blocks must have a selfParent set.'); - - if ( - ! $selfParent->selectors && - isset($block->parent) && - isset($block->parent->selectors) && $block->parent->selectors - ) { - $selfParent = $block->parent; - } - - $this->env = $this->filterWithWithout($envs, $with, $without); - - assert($this->scope !== null); - $saveScope = $this->scope; - $this->scope = $this->filterScopeWithWithout($saveScope, $with, $without); - - // propagate selfParent to the children where they still can be useful - $this->compileChildrenNoReturn($block->children, $this->scope, $selfParent); - - assert($this->scope !== null); - $this->completeScope($this->scope, $saveScope); - $this->scope = $saveScope; - $this->env = $this->extractEnv($envs); - - $this->popEnv(); - } - - /** - * Filter at-root scope depending on with/without option - * - * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $scope - * @param array $with - * @param array $without - * - * @return OutputBlock - */ - protected function filterScopeWithWithout($scope, $with, $without) - { - $filteredScopes = []; - $childStash = []; - - if ($scope->type === Type::T_ROOT) { - return $scope; - } - assert($this->rootBlock !== null); - - // start from the root - while ($scope->parent && $scope->parent->type !== Type::T_ROOT) { - array_unshift($childStash, $scope); - \assert($scope->parent !== null); - $scope = $scope->parent; - } - - for (;;) { - if (! $scope) { - break; - } - - if ($this->isWith($scope, $with, $without)) { - $s = clone $scope; - $s->children = []; - $s->lines = []; - $s->parent = null; - - if ($s->type !== Type::T_MEDIA && $s->type !== Type::T_DIRECTIVE) { - $s->selectors = []; - } - - $filteredScopes[] = $s; - } - - if (\count($childStash)) { - $scope = array_shift($childStash); - } elseif ($scope->children) { - $scope = end($scope->children); - } else { - $scope = null; - } - } - - if (! \count($filteredScopes)) { - return $this->rootBlock; - } - - $newScope = array_shift($filteredScopes); - $newScope->parent = $this->rootBlock; - - $this->rootBlock->children[] = $newScope; - - $p = &$newScope; - - while (\count($filteredScopes)) { - $s = array_shift($filteredScopes); - $s->parent = $p; - $p->children[] = $s; - $newScope = &$p->children[0]; - $p = &$p->children[0]; - } - - return $newScope; - } - - /** - * found missing selector from a at-root compilation in the previous scope - * (if at-root is just enclosing a property, the selector is in the parent tree) - * - * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $scope - * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $previousScope - * - * @return OutputBlock - */ - protected function completeScope($scope, $previousScope) - { - if (! $scope->type && ! $scope->selectors && \count($scope->lines)) { - $scope->selectors = $this->findScopeSelectors($previousScope, $scope->depth); - } - - if ($scope->children) { - foreach ($scope->children as $k => $c) { - $scope->children[$k] = $this->completeScope($c, $previousScope); - } - } - - return $scope; - } - - /** - * Find a selector by the depth node in the scope - * - * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $scope - * @param int $depth - * - * @return array - */ - protected function findScopeSelectors($scope, $depth) - { - if ($scope->depth === $depth && $scope->selectors) { - return $scope->selectors; - } - - if ($scope->children) { - foreach (array_reverse($scope->children) as $c) { - if ($s = $this->findScopeSelectors($c, $depth)) { - return $s; - } - } - } - - return []; - } - - /** - * Compile @at-root's with: inclusion / without: exclusion into 2 lists uses to filter scope/env later - * - * @param array|null $withCondition - * - * @return array - * - * @phpstan-return array{array, array} - */ - protected function compileWith($withCondition) - { - // just compile what we have in 2 lists - $with = []; - $without = ['rule' => true]; - - if ($withCondition) { - if ($withCondition[0] === Type::T_INTERPOLATE) { - $w = $this->compileValue($withCondition); - - $buffer = "($w)"; - $parser = $this->parserFactory(__METHOD__); - - if ($parser->parseValue($buffer, $reParsedWith)) { - \assert(\is_array($reParsedWith)); - $withCondition = $reParsedWith; - } - } - - $withConfig = $this->mapGet($withCondition, static::$with); - if ($withConfig !== null) { - $without = []; // cancel the default - $list = $this->coerceList($withConfig); - - foreach ($list[2] as $item) { - $keyword = $this->compileStringContent($this->coerceString($item)); - - $with[$keyword] = true; - } - } - - $withoutConfig = $this->mapGet($withCondition, static::$without); - if ($withoutConfig !== null) { - $without = []; // cancel the default - $list = $this->coerceList($withoutConfig); - - foreach ($list[2] as $item) { - $keyword = $this->compileStringContent($this->coerceString($item)); - - $without[$keyword] = true; - } - } - } - - return [$with, $without]; - } - - /** - * Filter env stack - * - * @param Environment[] $envs - * @param array $with - * @param array $without - * - * @return Environment - * - * @phpstan-param non-empty-array $envs - */ - protected function filterWithWithout($envs, $with, $without) - { - $filtered = []; - - foreach ($envs as $e) { - if ($e->block && ! $this->isWith($e->block, $with, $without)) { - $ec = clone $e; - $ec->block = null; - $ec->selectors = []; - - $filtered[] = $ec; - } else { - $filtered[] = $e; - } - } - - return $this->extractEnv($filtered); - } - - /** - * Filter WITH rules - * - * @param \ScssPhp\ScssPhp\Block|\ScssPhp\ScssPhp\Formatter\OutputBlock $block - * @param array $with - * @param array $without - * - * @return bool - */ - protected function isWith($block, $with, $without) - { - if (isset($block->type)) { - if ($block->type === Type::T_MEDIA) { - return $this->testWithWithout('media', $with, $without); - } - - if ($block->type === Type::T_DIRECTIVE) { - assert($block instanceof DirectiveBlock || $block instanceof OutputBlock); - if (isset($block->name)) { - return $this->testWithWithout($this->compileDirectiveName($block->name), $with, $without); - } elseif (isset($block->selectors) && preg_match(',@(\w+),ims', json_encode($block->selectors), $m)) { - return $this->testWithWithout($m[1], $with, $without); - } else { - return $this->testWithWithout('???', $with, $without); - } - } - } elseif (isset($block->selectors)) { - // a selector starting with number is a keyframe rule - if (\count($block->selectors)) { - $s = reset($block->selectors); - - while (\is_array($s)) { - $s = reset($s); - } - - if (\is_object($s) && $s instanceof Number) { - return $this->testWithWithout('keyframes', $with, $without); - } - } - - return $this->testWithWithout('rule', $with, $without); - } - - return true; - } - - /** - * Test a single type of block against with/without lists - * - * @param string $what - * @param array $with - * @param array $without - * - * @return bool - * true if the block should be kept, false to reject - */ - protected function testWithWithout($what, $with, $without) - { - // if without, reject only if in the list (or 'all' is in the list) - if (\count($without)) { - return (isset($without[$what]) || isset($without['all'])) ? false : true; - } - - // otherwise reject all what is not in the with list - return (isset($with[$what]) || isset($with['all'])) ? true : false; - } - - - /** - * Compile keyframe block - * - * @param \ScssPhp\ScssPhp\Block $block - * @param string[] $selectors - * - * @return void - */ - protected function compileKeyframeBlock(Block $block, $selectors) - { - $env = $this->pushEnv($block); - - $envs = $this->compactEnv($env); - - $this->env = $this->extractEnv(array_filter($envs, function (Environment $e) { - return ! isset($e->block->selectors); - })); - - $this->scope = $this->makeOutputBlock($block->type, $selectors); - $this->scope->depth = 1; - assert($this->scope->parent !== null); - $this->scope->parent->children[] = $this->scope; - - $this->compileChildrenNoReturn($block->children, $this->scope); - - assert($this->scope !== null); - $this->scope = $this->scope->parent; - $this->env = $this->extractEnv($envs); - - $this->popEnv(); - } - - /** - * Compile nested properties lines - * - * @param \ScssPhp\ScssPhp\Block $block - * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $out - * - * @return void - */ - protected function compileNestedPropertiesBlock(Block $block, OutputBlock $out) - { - assert($block instanceof NestedPropertyBlock); - $prefix = $this->compileValue($block->prefix) . '-'; - - $nested = $this->makeOutputBlock($block->type); - $nested->parent = $out; - - if ($block->hasValue) { - $nested->depth = $out->depth + 1; - } - - $out->children[] = $nested; - - foreach ($block->children as $child) { - switch ($child[0]) { - case Type::T_ASSIGN: - array_unshift($child[1][2], $prefix); - break; - - case Type::T_NESTED_PROPERTY: - assert($child[1] instanceof NestedPropertyBlock); - array_unshift($child[1]->prefix[2], $prefix); - break; - } - - $this->compileChild($child, $nested); - } - } - - /** - * Compile nested block - * - * @param \ScssPhp\ScssPhp\Block $block - * @param string[] $selectors - * - * @return void - */ - protected function compileNestedBlock(Block $block, $selectors) - { - $this->pushEnv($block); - - $this->scope = $this->makeOutputBlock($block->type, $selectors); - assert($this->scope->parent !== null); - $this->scope->parent->children[] = $this->scope; - - // wrap assign children in a block - // except for @font-face - if (!$block instanceof DirectiveBlock || $this->compileDirectiveName($block->name) !== 'font-face') { - // need wrapping? - $needWrapping = false; - - foreach ($block->children as $child) { - if ($child[0] === Type::T_ASSIGN) { - $needWrapping = true; - break; - } - } - - if ($needWrapping) { - $wrapped = new Block(); - $wrapped->sourceName = $block->sourceName; - $wrapped->sourceIndex = $block->sourceIndex; - $wrapped->sourceLine = $block->sourceLine; - $wrapped->sourceColumn = $block->sourceColumn; - $wrapped->selectors = []; - $wrapped->comments = []; - $wrapped->parent = $block; - $wrapped->children = $block->children; - $wrapped->selfParent = $block->selfParent; - - $block->children = [[Type::T_BLOCK, $wrapped]]; - } - } - - $this->compileChildrenNoReturn($block->children, $this->scope); - - assert($this->scope !== null); - $this->scope = $this->scope->parent; - - $this->popEnv(); - } - - /** - * Recursively compiles a block. - * - * A block is analogous to a CSS block in most cases. A single SCSS document - * is encapsulated in a block when parsed, but it does not have parent tags - * so all of its children appear on the root level when compiled. - * - * Blocks are made up of selectors and children. - * - * The children of a block are just all the blocks that are defined within. - * - * Compiling the block involves pushing a fresh environment on the stack, - * and iterating through the props, compiling each one. - * - * @see Compiler::compileChild() - * - * @param \ScssPhp\ScssPhp\Block $block - * - * @return void - */ - protected function compileBlock(Block $block) - { - $env = $this->pushEnv($block); - assert($block->selectors !== null); - $env->selectors = $this->evalSelectors($block->selectors); - - $out = $this->makeOutputBlock(null); - - assert($this->scope !== null); - $this->scope->children[] = $out; - - if (\count($block->children)) { - $out->selectors = $this->multiplySelectors($env, $block->selfParent); - - // propagate selfParent to the children where they still can be useful - $selfParentSelectors = null; - - if (isset($block->selfParent->selectors)) { - $selfParentSelectors = $block->selfParent->selectors; - $block->selfParent->selectors = $out->selectors; - } - - $this->compileChildrenNoReturn($block->children, $out, $block->selfParent); - - // and revert for the following children of the same block - if ($selfParentSelectors) { - assert($block->selfParent !== null); - $block->selfParent->selectors = $selfParentSelectors; - } - } - - $this->popEnv(); - } - - - /** - * Compile the value of a comment that can have interpolation - * - * @param array $value - * @param bool $pushEnv - * - * @return string - */ - protected function compileCommentValue($value, $pushEnv = false) - { - $c = $value[1]; - - if (isset($value[2])) { - if ($pushEnv) { - $this->pushEnv(); - } - - try { - $c = $this->compileValue($value[2]); - } catch (SassScriptException $e) { - $this->logger->warn('Ignoring interpolation errors in multiline comments is deprecated and will be removed in ScssPhp 2.0. ' . $this->addLocationToMessage($e->getMessage()), true); - // ignore error in comment compilation which are only interpolation - } catch (SassException $e) { - $this->logger->warn('Ignoring interpolation errors in multiline comments is deprecated and will be removed in ScssPhp 2.0. ' . $e->getMessage(), true); - // ignore error in comment compilation which are only interpolation - } - - if ($pushEnv) { - $this->popEnv(); - } - } - - return $c; - } - - /** - * Compile root level comment - * - * @param array $block - * - * @return void - */ - protected function compileComment($block) - { - $out = $this->makeOutputBlock(Type::T_COMMENT); - $out->lines[] = $this->compileCommentValue($block, true); - - assert($this->scope !== null); - $this->scope->children[] = $out; - } - - /** - * Evaluate selectors - * - * @param array $selectors - * - * @return array - */ - protected function evalSelectors($selectors) - { - $this->shouldEvaluate = false; - - $evaluatedSelectors = []; - foreach ($selectors as $selector) { - $evaluatedSelectors[] = $this->evalSelector($selector); - } - $selectors = $evaluatedSelectors; - - // after evaluating interpolates, we might need a second pass - if ($this->shouldEvaluate) { - $selectors = $this->replaceSelfSelector($selectors, '&'); - $buffer = $this->collapseSelectors($selectors); - $parser = $this->parserFactory(__METHOD__); - - try { - $isValid = $parser->parseSelector($buffer, $newSelectors, true); - } catch (ParserException $e) { - throw $this->error($e->getMessage()); - } - - if ($isValid) { - $selectors = array_map([$this, 'evalSelector'], $newSelectors); - } - } - - return $selectors; - } - - /** - * Evaluate selector - * - * @param array $selector - * - * @return array - * - * @phpstan-impure - */ - protected function evalSelector($selector) - { - return array_map([$this, 'evalSelectorPart'], $selector); - } - - /** - * Evaluate selector part; replaces all the interpolates, stripping quotes - * - * @param array $part - * - * @return array - * - * @phpstan-impure - */ - protected function evalSelectorPart($part) - { - foreach ($part as &$p) { - if (\is_array($p) && ($p[0] === Type::T_INTERPOLATE || $p[0] === Type::T_STRING)) { - $p = $this->compileValue($p); - - // force re-evaluation if self char or non standard char - if (preg_match(',[^\w-],', $p)) { - $this->shouldEvaluate = true; - } - } elseif ( - \is_string($p) && \strlen($p) >= 2 && - ($p[0] === '"' || $p[0] === "'") && - substr($p, -1) === $p[0] - ) { - $p = substr($p, 1, -1); - } - } - - return $this->flattenSelectorSingle($part); - } - - /** - * Collapse selectors - * - * @param array $selectors - * - * @return string - */ - protected function collapseSelectors($selectors) - { - $parts = []; - - foreach ($selectors as $selector) { - $output = []; - - foreach ($selector as $node) { - $compound = ''; - - if (!is_array($node)) { - $output[] = $node; - continue; - } - - array_walk_recursive( - $node, - function ($value, $key) use (&$compound) { - $compound .= $value; - } - ); - - $output[] = $compound; - } - - $parts[] = implode(' ', $output); - } - - return implode(', ', $parts); - } - - /** - * Collapse selectors - * - * @param array $selectors - * - * @return array - */ - private function collapseSelectorsAsList($selectors) - { - $parts = []; - - foreach ($selectors as $selector) { - $output = []; - $glueNext = false; - - foreach ($selector as $node) { - $compound = ''; - - if (!is_array($node)) { - $compound .= $node; - } else { - array_walk_recursive( - $node, - function ($value, $key) use (&$compound) { - $compound .= $value; - } - ); - } - - if ($this->isImmediateRelationshipCombinator($compound)) { - if (\count($output)) { - $output[\count($output) - 1] .= ' ' . $compound; - } else { - $output[] = $compound; - } - - $glueNext = true; - } elseif ($glueNext) { - $output[\count($output) - 1] .= ' ' . $compound; - $glueNext = false; - } else { - $output[] = $compound; - } - } - - foreach ($output as &$o) { - $o = [Type::T_STRING, '', [$o]]; - } - - $parts[] = [Type::T_LIST, ' ', $output]; - } - - return [Type::T_LIST, ',', $parts]; - } - - /** - * Parse down the selector and revert [self] to "&" before a reparsing - * - * @param array $selectors - * @param string|null $replace - * - * @return array - */ - protected function replaceSelfSelector($selectors, $replace = null) - { - foreach ($selectors as &$part) { - if (\is_array($part)) { - if ($part === [Type::T_SELF]) { - if (\is_null($replace)) { - $replace = $this->reduce([Type::T_SELF]); - $replace = $this->compileValue($replace); - } - $part = $replace; - } else { - $part = $this->replaceSelfSelector($part, $replace); - } - } - } - - return $selectors; - } - - /** - * Flatten selector single; joins together .classes and #ids - * - * @param array $single - * - * @return array - */ - protected function flattenSelectorSingle($single) - { - $joined = []; - - foreach ($single as $part) { - if ( - empty($joined) || - ! \is_string($part) || - preg_match('/[\[.:#%]/', $part) - ) { - $joined[] = $part; - continue; - } - - if (\is_array(end($joined))) { - $joined[] = $part; - } else { - $joined[\count($joined) - 1] .= $part; - } - } - - return $joined; - } - - /** - * Compile selector to string; self(&) should have been replaced by now - * - * @param string|array $selector - * - * @return string - */ - protected function compileSelector($selector) - { - if (! \is_array($selector)) { - return $selector; // media and the like - } - - return implode( - ' ', - array_map( - [$this, 'compileSelectorPart'], - $selector - ) - ); - } - - /** - * Compile selector part - * - * @param array $piece - * - * @return string - */ - protected function compileSelectorPart($piece) - { - foreach ($piece as &$p) { - if (! \is_array($p)) { - continue; - } - - switch ($p[0]) { - case Type::T_SELF: - $p = '&'; - break; - - default: - $p = $this->compileValue($p); - break; - } - } - - return implode($piece); - } - - /** - * Has selector placeholder? - * - * @param array $selector - * - * @return bool - */ - protected function hasSelectorPlaceholder($selector) - { - if (! \is_array($selector)) { - return false; - } - - foreach ($selector as $parts) { - foreach ($parts as $part) { - if (\strlen($part) && '%' === $part[0]) { - return true; - } - } - } - - return false; - } - - /** - * @param string $name - * - * @return void - */ - protected function pushCallStack($name = '') - { - $this->callStack[] = [ - 'n' => $name, - Parser::SOURCE_INDEX => $this->sourceIndex, - Parser::SOURCE_LINE => $this->sourceLine, - Parser::SOURCE_COLUMN => $this->sourceColumn - ]; - - // infinite calling loop - if (\count($this->callStack) > 25000) { - // not displayed but you can var_dump it to deep debug - $msg = $this->callStackMessage(true, 100); - $msg = 'Infinite calling loop'; - - throw $this->error($msg); - } - } - - /** - * @return void - */ - protected function popCallStack() - { - array_pop($this->callStack); - } - - /** - * Compile children and return result - * - * @param array $stms - * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $out - * @param string $traceName - * - * @return array|Number|null - */ - protected function compileChildren($stms, OutputBlock $out, $traceName = '') - { - $this->pushCallStack($traceName); - - foreach ($stms as $stm) { - $ret = $this->compileChild($stm, $out); - - if (isset($ret)) { - $this->popCallStack(); - - return $ret; - } - } - - $this->popCallStack(); - - return null; - } - - /** - * Compile children and throw exception if unexpected at-return - * - * @param array[] $stms - * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $out - * @param \ScssPhp\ScssPhp\Block $selfParent - * @param string $traceName - * - * @return void - * - * @throws \Exception - */ - protected function compileChildrenNoReturn($stms, OutputBlock $out, $selfParent = null, $traceName = '') - { - $this->pushCallStack($traceName); - - foreach ($stms as $stm) { - if ($selfParent && isset($stm[1]) && \is_object($stm[1]) && $stm[1] instanceof Block) { - $oldSelfParent = $stm[1]->selfParent; - $stm[1]->selfParent = $selfParent; - $ret = $this->compileChild($stm, $out); - $stm[1]->selfParent = $oldSelfParent; - } elseif ($selfParent && \in_array($stm[0], [Type::T_INCLUDE, Type::T_EXTEND])) { - $stm['selfParent'] = $selfParent; - $ret = $this->compileChild($stm, $out); - } else { - $ret = $this->compileChild($stm, $out); - } - - if (isset($ret)) { - throw $this->error('@return may only be used within a function'); - } - } - - $this->popCallStack(); - } - - - /** - * evaluate media query : compile internal value keeping the structure unchanged - * - * @param array $queryList - * - * @return array - */ - protected function evaluateMediaQuery($queryList) - { - static $parser = null; - - $outQueryList = []; - - foreach ($queryList as $kql => $query) { - $shouldReparse = false; - - foreach ($query as $kq => $q) { - for ($i = 1; $i < \count($q); $i++) { - $value = $this->compileValue($q[$i]); - - // the parser had no mean to know if media type or expression if it was an interpolation - // so you need to reparse if the T_MEDIA_TYPE looks like anything else a media type - if ( - $q[0] == Type::T_MEDIA_TYPE && - (strpos($value, '(') !== false || - strpos($value, ')') !== false || - strpos($value, ':') !== false || - strpos($value, ',') !== false) - ) { - $shouldReparse = true; - } - - $queryList[$kql][$kq][$i] = [Type::T_KEYWORD, $value]; - } - } - - if ($shouldReparse) { - if (\is_null($parser)) { - $parser = $this->parserFactory(__METHOD__); - } - - $queryString = $this->compileMediaQuery([$queryList[$kql]]); - $queryString = reset($queryString); - - if ($queryString !== false && strpos($queryString, '@media ') === 0) { - $queryString = substr($queryString, 7); - $queries = []; - - if ($parser->parseMediaQueryList($queryString, $queries)) { - $queries = $this->evaluateMediaQuery($queries[2]); - - while (\count($queries)) { - $outQueryList[] = array_shift($queries); - } - - continue; - } - } - } - - $outQueryList[] = $queryList[$kql]; - } - - return $outQueryList; - } - - /** - * Compile media query - * - * @param array $queryList - * - * @return string[] - */ - protected function compileMediaQuery($queryList) - { - $start = '@media '; - $default = trim($start); - $out = []; - $current = ''; - - foreach ($queryList as $query) { - $type = null; - $parts = []; - - $mediaTypeOnly = true; - - foreach ($query as $q) { - if ($q[0] !== Type::T_MEDIA_TYPE) { - $mediaTypeOnly = false; - break; - } - } - - foreach ($query as $q) { - switch ($q[0]) { - case Type::T_MEDIA_TYPE: - $newType = array_map([$this, 'compileValue'], \array_slice($q, 1)); - - // combining not and anything else than media type is too risky and should be avoided - if (! $mediaTypeOnly) { - if (\in_array(Type::T_NOT, $newType) || ($type && \in_array(Type::T_NOT, $type) )) { - if ($type) { - array_unshift($parts, implode(' ', array_filter($type))); - } - - if (! empty($parts)) { - if (\strlen($current)) { - $current .= $this->formatter->tagSeparator; - } - - $current .= implode(' and ', $parts); - } - - if ($current) { - $out[] = $start . $current; - } - - $current = ''; - $type = null; - $parts = []; - } - } - - if ($newType === ['all'] && $default) { - $default = $start . 'all'; - } - - // all can be safely ignored and mixed with whatever else - if ($newType !== ['all']) { - if ($type) { - $type = $this->mergeMediaTypes($type, $newType); - - if (empty($type)) { - // merge failed : ignore this query that is not valid, skip to the next one - $parts = []; - $default = ''; // if everything fail, no @media at all - continue 3; - } - } else { - $type = $newType; - } - } - break; - - case Type::T_MEDIA_EXPRESSION: - if (isset($q[2])) { - $parts[] = '(' - . $this->compileValue($q[1]) - . $this->formatter->assignSeparator - . $this->compileValue($q[2]) - . ')'; - } else { - $parts[] = '(' - . $this->compileValue($q[1]) - . ')'; - } - break; - - case Type::T_MEDIA_VALUE: - $parts[] = $this->compileValue($q[1]); - break; - } - } - - if ($type) { - array_unshift($parts, implode(' ', array_filter($type))); - } - - if (! empty($parts)) { - if (\strlen($current)) { - $current .= $this->formatter->tagSeparator; - } - - $current .= implode(' and ', $parts); - } - } - - if ($current) { - $out[] = $start . $current; - } - - // no @media type except all, and no conflict? - if (! $out && $default) { - $out[] = $default; - } - - return $out; - } - - /** - * Merge direct relationships between selectors - * - * @param array $selectors1 - * @param array $selectors2 - * - * @return array - */ - protected function mergeDirectRelationships($selectors1, $selectors2) - { - if (empty($selectors1) || empty($selectors2)) { - return array_merge($selectors1, $selectors2); - } - - $part1 = end($selectors1); - $part2 = end($selectors2); - - if (! $this->isImmediateRelationshipCombinator($part1[0]) && $part1 !== $part2) { - return array_merge($selectors1, $selectors2); - } - - $merged = []; - - do { - $part1 = array_pop($selectors1); - $part2 = array_pop($selectors2); - - if (! $this->isImmediateRelationshipCombinator($part1[0]) && $part1 !== $part2) { - if ($this->isImmediateRelationshipCombinator(reset($merged)[0])) { - array_unshift($merged, [$part1[0] . $part2[0]]); - $merged = array_merge($selectors1, $selectors2, $merged); - } else { - $merged = array_merge($selectors1, [$part1], $selectors2, [$part2], $merged); - } - - break; - } - - array_unshift($merged, $part1); - } while (! empty($selectors1) && ! empty($selectors2)); - - return $merged; - } - - /** - * Merge media types - * - * @param array $type1 - * @param array $type2 - * - * @return array|null - */ - protected function mergeMediaTypes($type1, $type2) - { - if (empty($type1)) { - return $type2; - } - - if (empty($type2)) { - return $type1; - } - - if (\count($type1) > 1) { - $m1 = strtolower($type1[0]); - $t1 = strtolower($type1[1]); - } else { - $m1 = ''; - $t1 = strtolower($type1[0]); - } - - if (\count($type2) > 1) { - $m2 = strtolower($type2[0]); - $t2 = strtolower($type2[1]); - } else { - $m2 = ''; - $t2 = strtolower($type2[0]); - } - - if (($m1 === Type::T_NOT) ^ ($m2 === Type::T_NOT)) { - if ($t1 === $t2) { - return null; - } - - return [ - $m1 === Type::T_NOT ? $m2 : $m1, - $m1 === Type::T_NOT ? $t2 : $t1, - ]; - } - - if ($m1 === Type::T_NOT && $m2 === Type::T_NOT) { - // CSS has no way of representing "neither screen nor print" - if ($t1 !== $t2) { - return null; - } - - return [Type::T_NOT, $t1]; - } - - if ($t1 !== $t2) { - return null; - } - - // t1 == t2, neither m1 nor m2 are "not" - return [empty($m1) ? $m2 : $m1, $t1]; - } - - /** - * Compile import; returns true if the value was something that could be imported - * - * @param array $rawPath - * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $out - * @param bool $once - * - * @return bool - */ - protected function compileImport($rawPath, OutputBlock $out, $once = false) - { - if ($rawPath[0] === Type::T_STRING) { - $path = $this->compileStringContent($rawPath); - - if (strpos($path, 'url(') !== 0 && $filePath = $this->findImport($path, $this->currentDirectory)) { - $this->registerImport($this->currentDirectory, $path, $filePath); - - if (! $once || ! \in_array($filePath, $this->importedFiles)) { - $this->importFile($filePath, $out); - $this->importedFiles[] = $filePath; - } - - return true; - } - - $this->appendRootDirective('@import ' . $this->compileImportPath($rawPath) . ';', $out); - - return false; - } - - if ($rawPath[0] === Type::T_LIST) { - // handle a list of strings - if (\count($rawPath[2]) === 0) { - return false; - } - - foreach ($rawPath[2] as $path) { - if ($path[0] !== Type::T_STRING) { - $this->appendRootDirective('@import ' . $this->compileImportPath($rawPath) . ';', $out); - - return false; - } - } - - foreach ($rawPath[2] as $path) { - $this->compileImport($path, $out, $once); - } - - return true; - } - - $this->appendRootDirective('@import ' . $this->compileImportPath($rawPath) . ';', $out); - - return false; - } - - /** - * @param array $rawPath - * @return string - * @throws CompilerException - */ - protected function compileImportPath($rawPath) - { - $path = $this->compileValue($rawPath); - - // case url() without quotes : suppress \r \n remaining in the path - // if this is a real string there can not be CR or LF char - if (strpos($path, 'url(') === 0) { - $path = str_replace(array("\r", "\n"), array('', ' '), $path); - } else { - // if this is a file name in a string, spaces should be escaped - $path = $this->reduce($rawPath); - $path = $this->escapeImportPathString($path); - $path = $this->compileValue($path); - } - - return $path; - } - - /** - * @param array $path - * @return array - * @throws CompilerException - */ - protected function escapeImportPathString($path) - { - switch ($path[0]) { - case Type::T_LIST: - foreach ($path[2] as $k => $v) { - $path[2][$k] = $this->escapeImportPathString($v); - } - break; - case Type::T_STRING: - if ($path[1]) { - $path = $this->compileValue($path); - $path = str_replace(' ', '\\ ', $path); - $path = [Type::T_KEYWORD, $path]; - } - break; - } - - return $path; - } - - /** - * Append a root directive like @import or @charset as near as the possible from the source code - * (keeping before comments, @import and @charset coming before in the source code) - * - * @param string $line - * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $out - * @param array $allowed - * - * @return void - */ - protected function appendRootDirective($line, $out, $allowed = [Type::T_COMMENT]) - { - $root = $out; - - while ($root->parent) { - $root = $root->parent; - } - - $i = 0; - - while ($i < \count($root->children)) { - if (! isset($root->children[$i]->type) || ! \in_array($root->children[$i]->type, $allowed)) { - break; - } - - $i++; - } - - // remove incompatible children from the bottom of the list - $saveChildren = []; - - while ($i < \count($root->children)) { - $saveChildren[] = array_pop($root->children); - } - - // insert the directive as a comment - $child = $this->makeOutputBlock(Type::T_COMMENT); - $child->lines[] = $line; - $child->sourceName = $this->sourceNames[$this->sourceIndex] ?: '(stdin)'; - $child->sourceLine = $this->sourceLine; - $child->sourceColumn = $this->sourceColumn; - - $root->children[] = $child; - - // repush children - while (\count($saveChildren)) { - $root->children[] = array_pop($saveChildren); - } - } - - /** - * Append lines to the current output block: - * directly to the block or through a child if necessary - * - * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $out - * @param string $type - * @param string $line - * - * @return void - */ - protected function appendOutputLine(OutputBlock $out, $type, $line) - { - $outWrite = &$out; - - // check if it's a flat output or not - if (\count($out->children)) { - $lastChild = &$out->children[\count($out->children) - 1]; - - if ( - $lastChild->depth === $out->depth && - \is_null($lastChild->selectors) && - ! \count($lastChild->children) - ) { - $outWrite = $lastChild; - } else { - $nextLines = $this->makeOutputBlock($type); - $nextLines->parent = $out; - $nextLines->depth = $out->depth; - - $out->children[] = $nextLines; - $outWrite = &$nextLines; - } - } - - $outWrite->lines[] = $line; - } - - /** - * Compile child; returns a value to halt execution - * - * @param array $child - * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $out - * - * @return array|Number|null - */ - protected function compileChild($child, OutputBlock $out) - { - if (isset($child[Parser::SOURCE_LINE])) { - $this->sourceIndex = isset($child[Parser::SOURCE_INDEX]) ? $child[Parser::SOURCE_INDEX] : null; - $this->sourceLine = $child[Parser::SOURCE_LINE]; - $this->sourceColumn = isset($child[Parser::SOURCE_COLUMN]) ? $child[Parser::SOURCE_COLUMN] : -1; - } elseif (\is_array($child) && isset($child[1]->sourceLine) && $child[1] instanceof Block) { - $this->sourceIndex = $child[1]->sourceIndex; - $this->sourceLine = $child[1]->sourceLine; - $this->sourceColumn = $child[1]->sourceColumn; - } elseif (! empty($out->sourceLine) && ! empty($out->sourceName)) { - $this->sourceLine = $out->sourceLine; - $sourceIndex = array_search($out->sourceName, $this->sourceNames); - $this->sourceColumn = $out->sourceColumn; - - if ($sourceIndex === false) { - $sourceIndex = null; - } - $this->sourceIndex = $sourceIndex; - } - - switch ($child[0]) { - case Type::T_SCSSPHP_IMPORT_ONCE: - $rawPath = $this->reduce($child[1]); - - $this->compileImport($rawPath, $out, true); - break; - - case Type::T_IMPORT: - $rawPath = $this->reduce($child[1]); - - $this->compileImport($rawPath, $out); - break; - - case Type::T_DIRECTIVE: - $this->compileDirective($child[1], $out); - break; - - case Type::T_AT_ROOT: - $this->compileAtRoot($child[1]); - break; - - case Type::T_MEDIA: - $this->compileMedia($child[1]); - break; - - case Type::T_BLOCK: - $this->compileBlock($child[1]); - break; - - case Type::T_CHARSET: - break; - - case Type::T_CUSTOM_PROPERTY: - list(, $name, $value) = $child; - $compiledName = $this->compileValue($name); - - // if the value reduces to null from something else then - // the property should be discarded - if ($value[0] !== Type::T_NULL) { - $value = $this->reduce($value); - - if ($value[0] === Type::T_NULL || $value === static::$nullString) { - break; - } - } - - $compiledValue = $this->compileValue($value); - - $line = $this->formatter->customProperty( - $compiledName, - $compiledValue - ); - - $this->appendOutputLine($out, Type::T_ASSIGN, $line); - break; - - case Type::T_ASSIGN: - list(, $name, $value) = $child; - - if ($name[0] === Type::T_VARIABLE) { - $flags = isset($child[3]) ? $child[3] : []; - $isDefault = \in_array('!default', $flags); - $isGlobal = \in_array('!global', $flags); - - if ($isGlobal) { - $this->set($name[1], $this->reduce($value), false, $this->rootEnv, $value); - break; - } - - $shouldSet = $isDefault && - (\is_null($result = $this->get($name[1], false)) || - $result === static::$null); - - if (! $isDefault || $shouldSet) { - $this->set($name[1], $this->reduce($value), true, null, $value); - } - break; - } - - $compiledName = $this->compileValue($name); - - // handle shorthand syntaxes : size / line-height... - if (\in_array($compiledName, ['font', 'grid-row', 'grid-column', 'border-radius'])) { - if ($value[0] === Type::T_VARIABLE) { - // if the font value comes from variable, the content is already reduced - // (i.e., formulas were already calculated), so we need the original unreduced value - $value = $this->get($value[1], true, null, true); - } - - $shorthandValue=&$value; - - $shorthandDividerNeedsUnit = false; - $maxListElements = null; - $maxShorthandDividers = 1; - - switch ($compiledName) { - case 'border-radius': - $maxListElements = 4; - $shorthandDividerNeedsUnit = true; - break; - } - - if ($compiledName === 'font' && $value[0] === Type::T_LIST && $value[1] === ',') { - // this is the case if more than one font is given: example: "font: 400 1em/1.3 arial,helvetica" - // we need to handle the first list element - $shorthandValue=&$value[2][0]; - } - - if ($shorthandValue[0] === Type::T_EXPRESSION && $shorthandValue[1] === '/') { - $revert = true; - - if ($shorthandDividerNeedsUnit) { - $divider = $shorthandValue[3]; - - if (\is_array($divider)) { - $divider = $this->reduce($divider, true); - } - - if ($divider instanceof Number && \intval($divider->getDimension()) && $divider->unitless()) { - $revert = false; - } - } - - if ($revert) { - $shorthandValue = $this->expToString($shorthandValue); - } - } elseif ($shorthandValue[0] === Type::T_LIST) { - foreach ($shorthandValue[2] as &$item) { - if ($item[0] === Type::T_EXPRESSION && $item[1] === '/') { - if ($maxShorthandDividers > 0) { - $revert = true; - - // if the list of values is too long, this has to be a shorthand, - // otherwise it could be a real division - if (\is_null($maxListElements) || \count($shorthandValue[2]) <= $maxListElements) { - if ($shorthandDividerNeedsUnit) { - $divider = $item[3]; - - if (\is_array($divider)) { - $divider = $this->reduce($divider, true); - } - - if ($divider instanceof Number && \intval($divider->getDimension()) && $divider->unitless()) { - $revert = false; - } - } - } - - if ($revert) { - $item = $this->expToString($item); - $maxShorthandDividers--; - } - } - } - } - } - } - - // if the value reduces to null from something else then - // the property should be discarded - if ($value[0] !== Type::T_NULL) { - $value = $this->reduce($value); - - if ($value[0] === Type::T_NULL || $value === static::$nullString) { - break; - } - } - - $compiledValue = $this->compileValue($value); - - // ignore empty value - if (\strlen($compiledValue)) { - $line = $this->formatter->property( - $compiledName, - $compiledValue - ); - $this->appendOutputLine($out, Type::T_ASSIGN, $line); - } - break; - - case Type::T_COMMENT: - if ($out->type === Type::T_ROOT) { - $this->compileComment($child); - break; - } - - $line = $this->compileCommentValue($child, true); - $this->appendOutputLine($out, Type::T_COMMENT, $line); - break; - - case Type::T_MIXIN: - case Type::T_FUNCTION: - list(, $block) = $child; - assert($block instanceof CallableBlock); - // the block need to be able to go up to it's parent env to resolve vars - $block->parentEnv = $this->getStoreEnv(); - $this->set(static::$namespaces[$block->type] . $block->name, $block, true); - break; - - case Type::T_EXTEND: - foreach ($child[1] as $sel) { - $replacedSel = $this->replaceSelfSelector($sel); - - if ($replacedSel !== $sel) { - throw $this->error('Parent selectors aren\'t allowed here.'); - } - - $results = $this->evalSelectors([$sel]); - - foreach ($results as $result) { - if (\count($result) !== 1) { - throw $this->error('complex selectors may not be extended.'); - } - - // only use the first one - $result = $result[0]; - $selectors = $out->selectors; - - if (! $selectors && isset($child['selfParent'])) { - $selectors = $this->multiplySelectors($this->env, $child['selfParent']); - } - assert($selectors !== null); - - if (\count($result) > 1) { - $replacement = implode(', ', $result); - $fname = $this->getPrettyPath($this->sourceNames[$this->sourceIndex]); - $line = $this->sourceLine; - - $message = <<logger->warn($message); - } - - $this->pushExtends($result, $selectors, $child); - } - } - break; - - case Type::T_IF: - list(, $if) = $child; - assert($if instanceof IfBlock); - - if ($this->isTruthy($this->reduce($if->cond, true))) { - return $this->compileChildren($if->children, $out); - } - - foreach ($if->cases as $case) { - if ( - $case instanceof ElseBlock || - $case instanceof ElseifBlock && $this->isTruthy($this->reduce($case->cond)) - ) { - return $this->compileChildren($case->children, $out); - } - } - break; - - case Type::T_EACH: - list(, $each) = $child; - assert($each instanceof EachBlock); - - $list = $this->coerceList($this->reduce($each->list), ',', true); - - $this->pushEnv(); - - foreach ($list[2] as $item) { - if (\count($each->vars) === 1) { - $this->set($each->vars[0], $item, true); - } else { - list(,, $values) = $this->coerceList($item); - - foreach ($each->vars as $i => $var) { - $this->set($var, isset($values[$i]) ? $values[$i] : static::$null, true); - } - } - - $ret = $this->compileChildren($each->children, $out); - - if ($ret) { - $store = $this->env->store; - $this->popEnv(); - $this->backPropagateEnv($store, $each->vars); - - return $ret; - } - } - $store = $this->env->store; - $this->popEnv(); - $this->backPropagateEnv($store, $each->vars); - - break; - - case Type::T_WHILE: - list(, $while) = $child; - assert($while instanceof WhileBlock); - - while ($this->isTruthy($this->reduce($while->cond, true))) { - $ret = $this->compileChildren($while->children, $out); - - if ($ret) { - return $ret; - } - } - break; - - case Type::T_FOR: - list(, $for) = $child; - assert($for instanceof ForBlock); - - $startNumber = $this->assertNumber($this->reduce($for->start, true)); - $endNumber = $this->assertNumber($this->reduce($for->end, true)); - - $start = $this->assertInteger($startNumber); - - $numeratorUnits = $startNumber->getNumeratorUnits(); - $denominatorUnits = $startNumber->getDenominatorUnits(); - - $end = $this->assertInteger($endNumber->coerce($numeratorUnits, $denominatorUnits)); - - $d = $start < $end ? 1 : -1; - - $this->pushEnv(); - - for (;;) { - if ( - (! $for->until && $start - $d == $end) || - ($for->until && $start == $end) - ) { - break; - } - - $this->set($for->var, new Number($start, $numeratorUnits, $denominatorUnits)); - $start += $d; - - $ret = $this->compileChildren($for->children, $out); - - if ($ret) { - $store = $this->env->store; - $this->popEnv(); - $this->backPropagateEnv($store, [$for->var]); - - return $ret; - } - } - - $store = $this->env->store; - $this->popEnv(); - $this->backPropagateEnv($store, [$for->var]); - - break; - - case Type::T_RETURN: - return $this->reduce($child[1], true); - - case Type::T_NESTED_PROPERTY: - $this->compileNestedPropertiesBlock($child[1], $out); - break; - - case Type::T_INCLUDE: - // including a mixin - list(, $name, $argValues, $content, $argUsing) = $child; - - $mixin = $this->get(static::$namespaces['mixin'] . $name, false); - - if (! $mixin) { - throw $this->error("Undefined mixin $name"); - } - - assert($mixin instanceof CallableBlock); - - $callingScope = $this->getStoreEnv(); - - // push scope, apply args - $this->pushEnv(); - $this->env->depth--; - - // Find the parent selectors in the env to be able to know what '&' refers to in the mixin - // and assign this fake parent to childs - $selfParent = null; - - if (isset($child['selfParent']) && $child['selfParent'] instanceof Block && isset($child['selfParent']->selectors)) { - $selfParent = $child['selfParent']; - } else { - $parentSelectors = $this->multiplySelectors($this->env); - - if ($parentSelectors) { - $parent = new Block(); - $parent->selectors = $parentSelectors; - - foreach ($mixin->children as $k => $child) { - if (isset($child[1]) && $child[1] instanceof Block) { - $mixin->children[$k][1]->parent = $parent; - } - } - } - } - - // clone the stored content to not have its scope spoiled by a further call to the same mixin - // i.e., recursive @include of the same mixin - if (isset($content)) { - $copyContent = clone $content; - $copyContent->scope = clone $callingScope; - - $this->setRaw(static::$namespaces['special'] . 'content', $copyContent, $this->env); - } else { - $this->setRaw(static::$namespaces['special'] . 'content', null, $this->env); - } - - // save the "using" argument list for applying it to when "@content" is invoked - if (isset($argUsing)) { - $this->setRaw(static::$namespaces['special'] . 'using', $argUsing, $this->env); - } else { - $this->setRaw(static::$namespaces['special'] . 'using', null, $this->env); - } - - if (isset($mixin->args)) { - $this->applyArguments($mixin->args, $argValues); - } - - $this->env->marker = 'mixin'; - - if (! empty($mixin->parentEnv)) { - $this->env->declarationScopeParent = $mixin->parentEnv; - } else { - throw $this->error("@mixin $name() without parentEnv"); - } - - $this->compileChildrenNoReturn($mixin->children, $out, $selfParent, $this->env->marker . ' ' . $name); - - $this->popEnv(); - break; - - case Type::T_MIXIN_CONTENT: - $env = isset($this->storeEnv) ? $this->storeEnv : $this->env; - $content = $this->get(static::$namespaces['special'] . 'content', false, $env); - $argUsing = $this->get(static::$namespaces['special'] . 'using', false, $env); - $argContent = $child[1]; - - if (! $content) { - break; - } - - $storeEnv = $this->storeEnv; - $varsUsing = []; - - if (isset($argUsing) && isset($argContent)) { - // Get the arguments provided for the content with the names provided in the "using" argument list - $this->storeEnv = null; - $varsUsing = $this->applyArguments($argUsing, $argContent, false); - } - - // restore the scope from the @content - $this->storeEnv = $content->scope; - - // append the vars from using if any - foreach ($varsUsing as $name => $val) { - $this->set($name, $val, true, $this->storeEnv); - } - - $this->compileChildrenNoReturn($content->children, $out); - - $this->storeEnv = $storeEnv; - break; - - case Type::T_DEBUG: - list(, $value) = $child; - - $fname = $this->getPrettyPath($this->sourceNames[$this->sourceIndex]); - $line = $this->sourceLine; - $value = $this->compileDebugValue($value); - - $this->logger->debug("$fname:$line DEBUG: $value"); - break; - - case Type::T_WARN: - list(, $value) = $child; - - $fname = $this->getPrettyPath($this->sourceNames[$this->sourceIndex]); - $line = $this->sourceLine; - $value = $this->compileDebugValue($value); - - $this->logger->warn("$value\n on line $line of $fname"); - break; - - case Type::T_ERROR: - list(, $value) = $child; - - $fname = $this->getPrettyPath($this->sourceNames[$this->sourceIndex]); - $line = $this->sourceLine; - $value = $this->compileValue($this->reduce($value, true)); - - throw $this->error("File $fname on line $line ERROR: $value\n"); - - default: - throw $this->error("unknown child type: $child[0]"); - } - - return null; - } - - /** - * Reduce expression to string - * - * @param array $exp - * @param bool $keepParens - * - * @return array - */ - protected function expToString($exp, $keepParens = false) - { - list(, $op, $left, $right, $inParens, $whiteLeft, $whiteRight) = $exp; - - $content = []; - - if ($keepParens && $inParens) { - $content[] = '('; - } - - $content[] = $this->reduce($left); - - if ($whiteLeft) { - $content[] = ' '; - } - - $content[] = $op; - - if ($whiteRight) { - $content[] = ' '; - } - - $content[] = $this->reduce($right); - - if ($keepParens && $inParens) { - $content[] = ')'; - } - - return [Type::T_STRING, '', $content]; - } - - /** - * Is truthy? - * - * @param array|Number $value - * - * @return bool - */ - public function isTruthy($value) - { - return $value !== static::$false && $value !== static::$null; - } - - /** - * Is the value a direct relationship combinator? - * - * @param string $value - * - * @return bool - */ - protected function isImmediateRelationshipCombinator($value) - { - return $value === '>' || $value === '+' || $value === '~'; - } - - /** - * Should $value cause its operand to eval - * - * @param array $value - * - * @return bool - */ - protected function shouldEval($value) - { - switch ($value[0]) { - case Type::T_EXPRESSION: - if ($value[1] === '/') { - return $this->shouldEval($value[2]) || $this->shouldEval($value[3]); - } - - // fall-thru - case Type::T_VARIABLE: - case Type::T_FUNCTION_CALL: - return true; - } - - return false; - } - - /** - * Reduce value - * - * @param array|Number $value - * @param bool $inExp - * - * @return array|Number - */ - protected function reduce($value, $inExp = false) - { - if ($value instanceof Number) { - return $value; - } - - switch ($value[0]) { - case Type::T_EXPRESSION: - list(, $op, $left, $right, $inParens) = $value; - - $opName = isset(static::$operatorNames[$op]) ? static::$operatorNames[$op] : $op; - $inExp = $inExp || $this->shouldEval($left) || $this->shouldEval($right); - - $left = $this->reduce($left, true); - - if ($op !== 'and' && $op !== 'or') { - $right = $this->reduce($right, true); - } - - // special case: looks like css shorthand - if ( - $opName == 'div' && ! $inParens && ! $inExp && - (($right[0] !== Type::T_NUMBER && isset($right[2]) && $right[2] != '') || - ($right[0] === Type::T_NUMBER && ! $right->unitless())) - ) { - return $this->expToString($value); - } - - $left = $this->coerceForExpression($left); - $right = $this->coerceForExpression($right); - $ltype = $left[0]; - $rtype = $right[0]; - - $ucOpName = ucfirst($opName); - $ucLType = ucfirst($ltype); - $ucRType = ucfirst($rtype); - - $shouldEval = $inParens || $inExp; - - // this tries: - // 1. op[op name][left type][right type] - // 2. op[left type][right type] (passing the op as first arg) - // 3. op[op name] - if (\is_callable([$this, $fn = "op{$ucOpName}{$ucLType}{$ucRType}"])) { - $out = $this->$fn($left, $right, $shouldEval); - } elseif (\is_callable([$this, $fn = "op{$ucLType}{$ucRType}"])) { - $out = $this->$fn($op, $left, $right, $shouldEval); - } elseif (\is_callable([$this, $fn = "op{$ucOpName}"])) { - $out = $this->$fn($left, $right, $shouldEval); - } else { - $out = null; - } - - if (isset($out)) { - return $out; - } - - return $this->expToString($value); - - case Type::T_UNARY: - list(, $op, $exp, $inParens) = $value; - - $inExp = $inExp || $this->shouldEval($exp); - $exp = $this->reduce($exp); - - if ($exp instanceof Number) { - switch ($op) { - case '+': - return $exp; - - case '-': - return $exp->unaryMinus(); - } - } - - if ($op === 'not') { - if ($inExp || $inParens) { - if ($exp === static::$false || $exp === static::$null) { - return static::$true; - } - - return static::$false; - } - - $op = $op . ' '; - } - - return [Type::T_STRING, '', [$op, $exp]]; - - case Type::T_VARIABLE: - return $this->reduce($this->get($value[1])); - - case Type::T_LIST: - foreach ($value[2] as &$item) { - $item = $this->reduce($item); - } - unset($item); - - if (isset($value[3]) && \is_array($value[3])) { - foreach ($value[3] as &$item) { - $item = $this->reduce($item); - } - unset($item); - } - - return $value; - - case Type::T_MAP: - foreach ($value[1] as &$item) { - $item = $this->reduce($item); - } - - foreach ($value[2] as &$item) { - $item = $this->reduce($item); - } - - return $value; - - case Type::T_STRING: - foreach ($value[2] as &$item) { - if (\is_array($item) || $item instanceof Number) { - $item = $this->reduce($item); - } - } - - return $value; - - case Type::T_INTERPOLATE: - $value[1] = $this->reduce($value[1]); - - if ($inExp) { - return [Type::T_KEYWORD, $this->compileValue($value, false)]; - } - - return $value; - - case Type::T_FUNCTION_CALL: - return $this->fncall($value[1], $value[2]); - - case Type::T_SELF: - $selfParent = ! empty($this->env->block->selfParent) ? $this->env->block->selfParent : null; - $selfSelector = $this->multiplySelectors($this->env, $selfParent); - $selfSelector = $this->collapseSelectorsAsList($selfSelector); - - return $selfSelector; - - default: - return $value; - } - } - - /** - * Function caller - * - * @param string|array $functionReference - * @param array $argValues - * - * @return array|Number - */ - protected function fncall($functionReference, $argValues) - { - // a string means this is a static hard reference coming from the parsing - if (is_string($functionReference)) { - $name = $functionReference; - - $functionReference = $this->getFunctionReference($name); - if ($functionReference === static::$null || $functionReference[0] !== Type::T_FUNCTION_REFERENCE) { - $functionReference = [Type::T_FUNCTION, $name, [Type::T_LIST, ',', []]]; - } - } - - // a function type means we just want a plain css function call - if ($functionReference[0] === Type::T_FUNCTION) { - // for CSS functions, simply flatten the arguments into a list - $listArgs = []; - - foreach ((array) $argValues as $arg) { - if (empty($arg[0]) || count($argValues) === 1) { - $listArgs[] = $this->reduce($this->stringifyFncallArgs($arg[1])); - } - } - - return [Type::T_FUNCTION, $functionReference[1], [Type::T_LIST, ',', $listArgs]]; - } - - if ($functionReference === static::$null || $functionReference[0] !== Type::T_FUNCTION_REFERENCE) { - return static::$defaultValue; - } - - - switch ($functionReference[1]) { - // SCSS @function - case 'scss': - return $this->callScssFunction($functionReference[3], $argValues); - - // native PHP functions - case 'user': - case 'native': - list(,,$name, $fn, $prototype) = $functionReference; - - // special cases of css valid functions min/max - $name = strtolower($name); - if (\in_array($name, ['min', 'max']) && count($argValues) >= 1) { - $cssFunction = $this->cssValidArg( - [Type::T_FUNCTION_CALL, $name, $argValues], - ['min', 'max', 'calc', 'env', 'var'] - ); - if ($cssFunction !== false) { - return $cssFunction; - } - } - $returnValue = $this->callNativeFunction($name, $fn, $prototype, $argValues); - - if (! isset($returnValue)) { - return $this->fncall([Type::T_FUNCTION, $name, [Type::T_LIST, ',', []]], $argValues); - } - - return $returnValue; - - default: - return static::$defaultValue; - } - } - - /** - * @param array|Number $arg - * @param string[] $allowed_function - * @param bool $inFunction - * - * @return array|Number|false - */ - protected function cssValidArg($arg, $allowed_function = [], $inFunction = false) - { - if ($arg instanceof Number) { - return $this->stringifyFncallArgs($arg); - } - - switch ($arg[0]) { - case Type::T_INTERPOLATE: - return [Type::T_KEYWORD, $this->CompileValue($arg)]; - - case Type::T_FUNCTION: - if (! \in_array($arg[1], $allowed_function)) { - return false; - } - if ($arg[2][0] === Type::T_LIST) { - foreach ($arg[2][2] as $k => $subarg) { - $arg[2][2][$k] = $this->cssValidArg($subarg, $allowed_function, $arg[1]); - if ($arg[2][2][$k] === false) { - return false; - } - } - } - return $arg; - - case Type::T_FUNCTION_CALL: - if (! \in_array($arg[1], $allowed_function)) { - return false; - } - $cssArgs = []; - foreach ($arg[2] as $argValue) { - if ($argValue === static::$null) { - return false; - } - $cssArg = $this->cssValidArg($argValue[1], $allowed_function, $arg[1]); - if (empty($argValue[0]) && $cssArg !== false) { - $cssArgs[] = [$argValue[0], $cssArg]; - } else { - return false; - } - } - - return $this->fncall([Type::T_FUNCTION, $arg[1], [Type::T_LIST, ',', []]], $cssArgs); - - case Type::T_STRING: - case Type::T_KEYWORD: - if (!$inFunction or !\in_array($inFunction, ['calc', 'env', 'var'])) { - return false; - } - return $this->stringifyFncallArgs($arg); - - case Type::T_LIST: - if (!$inFunction) { - return false; - } - if (empty($arg['enclosing']) and $arg[1] === '') { - foreach ($arg[2] as $k => $subarg) { - $arg[2][$k] = $this->cssValidArg($subarg, $allowed_function, $inFunction); - if ($arg[2][$k] === false) { - return false; - } - } - $arg[0] = Type::T_STRING; - return $arg; - } - return false; - - case Type::T_EXPRESSION: - if (! \in_array($arg[1], ['+', '-', '/', '*'])) { - return false; - } - $arg[2] = $this->cssValidArg($arg[2], $allowed_function, $inFunction); - $arg[3] = $this->cssValidArg($arg[3], $allowed_function, $inFunction); - if ($arg[2] === false || $arg[3] === false) { - return false; - } - return $this->expToString($arg, true); - - case Type::T_VARIABLE: - case Type::T_SELF: - default: - return false; - } - } - - - /** - * Reformat fncall arguments to proper css function output - * - * @param array|Number $arg - * - * @return array|Number - */ - protected function stringifyFncallArgs($arg) - { - if ($arg instanceof Number) { - return $arg; - } - - switch ($arg[0]) { - case Type::T_LIST: - foreach ($arg[2] as $k => $v) { - $arg[2][$k] = $this->stringifyFncallArgs($v); - } - break; - - case Type::T_EXPRESSION: - if ($arg[1] === '/') { - $arg[2] = $this->stringifyFncallArgs($arg[2]); - $arg[3] = $this->stringifyFncallArgs($arg[3]); - $arg[5] = $arg[6] = false; // no space around / - $arg = $this->expToString($arg); - } - break; - - case Type::T_FUNCTION_CALL: - $name = strtolower($arg[1]); - - if (in_array($name, ['max', 'min', 'calc'])) { - $args = $arg[2]; - $arg = $this->fncall([Type::T_FUNCTION, $name, [Type::T_LIST, ',', []]], $args); - } - break; - } - - return $arg; - } - - /** - * Find a function reference - * @param string $name - * @param bool $safeCopy - * @return array - */ - protected function getFunctionReference($name, $safeCopy = false) - { - // SCSS @function - if ($func = $this->get(static::$namespaces['function'] . $name, false)) { - if ($safeCopy) { - $func = clone $func; - } - - return [Type::T_FUNCTION_REFERENCE, 'scss', $name, $func]; - } - - // native PHP functions - - // try to find a native lib function - $normalizedName = $this->normalizeName($name); - - if (isset($this->userFunctions[$normalizedName])) { - // see if we can find a user function - list($f, $prototype) = $this->userFunctions[$normalizedName]; - - return [Type::T_FUNCTION_REFERENCE, 'user', $name, $f, $prototype]; - } - - $lowercasedName = strtolower($normalizedName); - - // Special functions overriding a CSS function are case-insensitive. We normalize them as lowercase - // to avoid the deprecation warning about the wrong case being used. - if ($lowercasedName === 'min' || $lowercasedName === 'max' || $lowercasedName === 'rgb' || $lowercasedName === 'rgba' || $lowercasedName === 'hsl' || $lowercasedName === 'hsla') { - $normalizedName = $lowercasedName; - } - - if (($f = $this->getBuiltinFunction($normalizedName)) && \is_callable($f)) { - /** @var string $libName */ - $libName = $f[1]; - $prototype = isset(static::$$libName) ? static::$$libName : null; - - // All core functions have a prototype defined. Not finding the - // prototype can mean 2 things: - // - the function comes from a child class (deprecated just after) - // - the function was found with a different case, which relates to calling the - // wrong Sass function due to our camelCase usage (`fade-in()` vs `fadein()`), - // because PHP method names are case-insensitive while property names are - // case-sensitive. - if ($prototype === null || strtolower($normalizedName) !== $normalizedName) { - $r = new \ReflectionMethod($this, $libName); - $actualLibName = $r->name; - - if ($actualLibName !== $libName || strtolower($normalizedName) !== $normalizedName) { - $kebabCaseName = preg_replace('~(?<=\\w)([A-Z])~', '-$1', substr($actualLibName, 3)); - assert($kebabCaseName !== null); - $originalName = strtolower($kebabCaseName); - $warning = "Calling built-in functions with a non-standard name is deprecated since Scssphp 1.8.0 and will not work anymore in 2.0 (they will be treated as CSS function calls instead).\nUse \"$originalName\" instead of \"$name\"."; - @trigger_error($warning, E_USER_DEPRECATED); - $fname = $this->getPrettyPath($this->sourceNames[$this->sourceIndex]); - $line = $this->sourceLine; - Warn::deprecation("$warning\n on line $line of $fname"); - - // Use the actual function definition - $prototype = isset(static::$$actualLibName) ? static::$$actualLibName : null; - $f[1] = $libName = $actualLibName; - } - } - - if (\get_class($this) !== __CLASS__ && !isset($this->warnedChildFunctions[$libName])) { - $r = new \ReflectionMethod($this, $libName); - $declaringClass = $r->getDeclaringClass()->name; - - $needsWarning = $this->warnedChildFunctions[$libName] = $declaringClass !== __CLASS__; - - if ($needsWarning) { - if (method_exists(__CLASS__, $libName)) { - @trigger_error(sprintf('Overriding the "%s" core function by extending the Compiler is deprecated and will be unsupported in 2.0. Remove the "%s::%s" method.', $normalizedName, $declaringClass, $libName), E_USER_DEPRECATED); - } else { - @trigger_error(sprintf('Registering custom functions by extending the Compiler and using the lib* discovery mechanism is deprecated and will be removed in 2.0. Replace the "%s::%s" method with registering the "%s" function through "Compiler::registerFunction".', $declaringClass, $libName, $normalizedName), E_USER_DEPRECATED); - } - } - } - - return [Type::T_FUNCTION_REFERENCE, 'native', $name, $f, $prototype]; - } - - return static::$null; - } - - - /** - * Normalize name - * - * @param string $name - * - * @return string - */ - protected function normalizeName($name) - { - return str_replace('-', '_', $name); - } - - /** - * Normalize value - * - * @internal - * - * @param array|Number $value - * - * @return array|Number - */ - public function normalizeValue($value) - { - $value = $this->coerceForExpression($this->reduce($value)); - - if ($value instanceof Number) { - return $value; - } - - switch ($value[0]) { - case Type::T_LIST: - $value = $this->extractInterpolation($value); - - if ($value[0] !== Type::T_LIST) { - return [Type::T_KEYWORD, $this->compileValue($value)]; - } - - foreach ($value[2] as $key => $item) { - $value[2][$key] = $this->normalizeValue($item); - } - - if (! empty($value['enclosing'])) { - unset($value['enclosing']); - } - - if ($value[1] === '' && count($value[2]) > 1) { - $value[1] = ' '; - } - - return $value; - - case Type::T_STRING: - return [$value[0], '"', [$this->compileStringContent($value)]]; - - case Type::T_INTERPOLATE: - return [Type::T_KEYWORD, $this->compileValue($value)]; - - default: - return $value; - } - } - - /** - * Add numbers - * - * @param Number $left - * @param Number $right - * - * @return Number - */ - protected function opAddNumberNumber(Number $left, Number $right) - { - return $left->plus($right); - } - - /** - * Multiply numbers - * - * @param Number $left - * @param Number $right - * - * @return Number - */ - protected function opMulNumberNumber(Number $left, Number $right) - { - return $left->times($right); - } - - /** - * Subtract numbers - * - * @param Number $left - * @param Number $right - * - * @return Number - */ - protected function opSubNumberNumber(Number $left, Number $right) - { - return $left->minus($right); - } - - /** - * Divide numbers - * - * @param Number $left - * @param Number $right - * - * @return Number - */ - protected function opDivNumberNumber(Number $left, Number $right) - { - return $left->dividedBy($right); - } - - /** - * Mod numbers - * - * @param Number $left - * @param Number $right - * - * @return Number - */ - protected function opModNumberNumber(Number $left, Number $right) - { - return $left->modulo($right); - } - - /** - * Add strings - * - * @param array $left - * @param array $right - * - * @return array|null - */ - protected function opAdd($left, $right) - { - if ($strLeft = $this->coerceString($left)) { - if ($right[0] === Type::T_STRING) { - $right[1] = ''; - } - - $strLeft[2][] = $right; - - return $strLeft; - } - - if ($strRight = $this->coerceString($right)) { - if ($left[0] === Type::T_STRING) { - $left[1] = ''; - } - - array_unshift($strRight[2], $left); - - return $strRight; - } - - return null; - } - - /** - * Boolean and - * - * @param array|Number $left - * @param array|Number $right - * @param bool $shouldEval - * - * @return array|Number|null - */ - protected function opAnd($left, $right, $shouldEval) - { - $truthy = ($left === static::$null || $right === static::$null) || - ($left === static::$false || $left === static::$true) && - ($right === static::$false || $right === static::$true); - - if (! $shouldEval) { - if (! $truthy) { - return null; - } - } - - if ($left !== static::$false && $left !== static::$null) { - return $this->reduce($right, true); - } - - return $left; - } - - /** - * Boolean or - * - * @param array|Number $left - * @param array|Number $right - * @param bool $shouldEval - * - * @return array|Number|null - */ - protected function opOr($left, $right, $shouldEval) - { - $truthy = ($left === static::$null || $right === static::$null) || - ($left === static::$false || $left === static::$true) && - ($right === static::$false || $right === static::$true); - - if (! $shouldEval) { - if (! $truthy) { - return null; - } - } - - if ($left !== static::$false && $left !== static::$null) { - return $left; - } - - return $this->reduce($right, true); - } - - /** - * Compare colors - * - * @param string $op - * @param array $left - * @param array $right - * - * @return array - */ - protected function opColorColor($op, $left, $right) - { - if ($op !== '==' && $op !== '!=') { - $warning = "Color arithmetic is deprecated and will be an error in future versions.\n" - . "Consider using Sass's color functions instead."; - $fname = $this->getPrettyPath($this->sourceNames[$this->sourceIndex]); - $line = $this->sourceLine; - - Warn::deprecation("$warning\n on line $line of $fname"); - } - - $out = [Type::T_COLOR]; - - foreach ([1, 2, 3] as $i) { - $lval = isset($left[$i]) ? $left[$i] : 0; - $rval = isset($right[$i]) ? $right[$i] : 0; - - switch ($op) { - case '+': - $out[] = $lval + $rval; - break; - - case '-': - $out[] = $lval - $rval; - break; - - case '*': - $out[] = $lval * $rval; - break; - - case '%': - if ($rval == 0) { - throw $this->error("color: Can't take modulo by zero"); - } - - $out[] = $lval % $rval; - break; - - case '/': - if ($rval == 0) { - throw $this->error("color: Can't divide by zero"); - } - - $out[] = (int) ($lval / $rval); - break; - - case '==': - return $this->opEq($left, $right); - - case '!=': - return $this->opNeq($left, $right); - - default: - throw $this->error("color: unknown op $op"); - } - } - - if (isset($left[4])) { - $out[4] = $left[4]; - } elseif (isset($right[4])) { - $out[4] = $right[4]; - } - - return $this->fixColor($out); - } - - /** - * Compare color and number - * - * @param string $op - * @param array $left - * @param Number $right - * - * @return array - */ - protected function opColorNumber($op, $left, Number $right) - { - if ($op === '==') { - return static::$false; - } - - if ($op === '!=') { - return static::$true; - } - - $value = $right->getDimension(); - - return $this->opColorColor( - $op, - $left, - [Type::T_COLOR, $value, $value, $value] - ); - } - - /** - * Compare number and color - * - * @param string $op - * @param Number $left - * @param array $right - * - * @return array - */ - protected function opNumberColor($op, Number $left, $right) - { - if ($op === '==') { - return static::$false; - } - - if ($op === '!=') { - return static::$true; - } - - $value = $left->getDimension(); - - return $this->opColorColor( - $op, - [Type::T_COLOR, $value, $value, $value], - $right - ); - } - - /** - * Compare number1 == number2 - * - * @param array|Number $left - * @param array|Number $right - * - * @return array - */ - protected function opEq($left, $right) - { - if (($lStr = $this->coerceString($left)) && ($rStr = $this->coerceString($right))) { - $lStr[1] = ''; - $rStr[1] = ''; - - $left = $this->compileValue($lStr); - $right = $this->compileValue($rStr); - } - - return $this->toBool($left === $right); - } - - /** - * Compare number1 != number2 - * - * @param array|Number $left - * @param array|Number $right - * - * @return array - */ - protected function opNeq($left, $right) - { - if (($lStr = $this->coerceString($left)) && ($rStr = $this->coerceString($right))) { - $lStr[1] = ''; - $rStr[1] = ''; - - $left = $this->compileValue($lStr); - $right = $this->compileValue($rStr); - } - - return $this->toBool($left !== $right); - } - - /** - * Compare number1 == number2 - * - * @param Number $left - * @param Number $right - * - * @return array - */ - protected function opEqNumberNumber(Number $left, Number $right) - { - return $this->toBool($left->equals($right)); - } - - /** - * Compare number1 != number2 - * - * @param Number $left - * @param Number $right - * - * @return array - */ - protected function opNeqNumberNumber(Number $left, Number $right) - { - return $this->toBool(!$left->equals($right)); - } - - /** - * Compare number1 >= number2 - * - * @param Number $left - * @param Number $right - * - * @return array - */ - protected function opGteNumberNumber(Number $left, Number $right) - { - return $this->toBool($left->greaterThanOrEqual($right)); - } - - /** - * Compare number1 > number2 - * - * @param Number $left - * @param Number $right - * - * @return array - */ - protected function opGtNumberNumber(Number $left, Number $right) - { - return $this->toBool($left->greaterThan($right)); - } - - /** - * Compare number1 <= number2 - * - * @param Number $left - * @param Number $right - * - * @return array - */ - protected function opLteNumberNumber(Number $left, Number $right) - { - return $this->toBool($left->lessThanOrEqual($right)); - } - - /** - * Compare number1 < number2 - * - * @param Number $left - * @param Number $right - * - * @return array - */ - protected function opLtNumberNumber(Number $left, Number $right) - { - return $this->toBool($left->lessThan($right)); - } - - /** - * Cast to boolean - * - * @api - * - * @param bool $thing - * - * @return array - */ - public function toBool($thing) - { - return $thing ? static::$true : static::$false; - } - - /** - * Escape non printable chars in strings output as in dart-sass - * - * @internal - * - * @param string $string - * @param bool $inKeyword - * - * @return string - */ - public function escapeNonPrintableChars($string, $inKeyword = false) - { - static $replacement = []; - if (empty($replacement[$inKeyword])) { - for ($i = 0; $i < 32; $i++) { - if ($i !== 9 || $inKeyword) { - $replacement[$inKeyword][chr($i)] = '\\' . dechex($i) . ($inKeyword ? ' ' : chr(0)); - } - } - } - $string = str_replace(array_keys($replacement[$inKeyword]), array_values($replacement[$inKeyword]), $string); - // chr(0) is not a possible char from the input, so any chr(0) comes from our escaping replacement - if (strpos($string, chr(0)) !== false) { - if (substr($string, -1) === chr(0)) { - $string = substr($string, 0, -1); - } - $string = str_replace( - [chr(0) . '\\',chr(0) . ' '], - [ '\\', ' '], - $string - ); - if (strpos($string, chr(0)) !== false) { - $parts = explode(chr(0), $string); - $string = array_shift($parts); - while (count($parts)) { - $next = array_shift($parts); - if (strpos("0123456789abcdefABCDEF" . chr(9), $next[0]) !== false) { - $string .= " "; - } - $string .= $next; - } - } - } - - return $string; - } - - /** - * Compiles a primitive value into a CSS property value. - * - * Values in scssphp are typed by being wrapped in arrays, their format is - * typically: - * - * array(type, contents [, additional_contents]*) - * - * The input is expected to be reduced. This function will not work on - * things like expressions and variables. - * - * @api - * - * @param array|Number $value - * @param bool $quote - * - * @return string - */ - public function compileValue($value, $quote = true) - { - $value = $this->reduce($value); - - if ($value instanceof Number) { - return $value->output($this); - } - - switch ($value[0]) { - case Type::T_KEYWORD: - return $this->escapeNonPrintableChars($value[1], true); - - case Type::T_COLOR: - // [1] - red component (either number for a %) - // [2] - green component - // [3] - blue component - // [4] - optional alpha component - list(, $r, $g, $b) = $value; - - $r = $this->compileRGBAValue($r); - $g = $this->compileRGBAValue($g); - $b = $this->compileRGBAValue($b); - - if (\count($value) === 5) { - $alpha = $this->compileRGBAValue($value[4], true); - - if (! is_numeric($alpha) || $alpha < 1) { - $colorName = Colors::RGBaToColorName($r, $g, $b, $alpha); - - if (! \is_null($colorName)) { - return $colorName; - } - - if (\is_int($alpha) || \is_float($alpha)) { - $a = new Number($alpha, ''); - } elseif (is_numeric($alpha)) { - $a = new Number((float) $alpha, ''); - } else { - $a = $alpha; - } - - return 'rgba(' . $r . ', ' . $g . ', ' . $b . ', ' . $a . ')'; - } - } - - if (! is_numeric($r) || ! is_numeric($g) || ! is_numeric($b)) { - return 'rgb(' . $r . ', ' . $g . ', ' . $b . ')'; - } - - $colorName = Colors::RGBaToColorName($r, $g, $b); - - if (! \is_null($colorName)) { - return $colorName; - } - - $h = sprintf('#%02x%02x%02x', $r, $g, $b); - - // Converting hex color to short notation (e.g. #003399 to #039) - if ($h[1] === $h[2] && $h[3] === $h[4] && $h[5] === $h[6]) { - $h = '#' . $h[1] . $h[3] . $h[5]; - } - - return $h; - - case Type::T_STRING: - $content = $this->compileStringContent($value, $quote); - - if ($value[1] && $quote) { - $content = str_replace('\\', '\\\\', $content); - - $content = $this->escapeNonPrintableChars($content); - - // force double quote as string quote for the output in certain cases - if ( - $value[1] === "'" && - (strpos($content, '"') === false or strpos($content, "'") !== false) - ) { - $value[1] = '"'; - } elseif ( - $value[1] === '"' && - (strpos($content, '"') !== false and strpos($content, "'") === false) - ) { - $value[1] = "'"; - } - - $content = str_replace($value[1], '\\' . $value[1], $content); - } - - return $value[1] . $content . $value[1]; - - case Type::T_FUNCTION: - $args = ! empty($value[2]) ? $this->compileValue($value[2], $quote) : ''; - - return "$value[1]($args)"; - - case Type::T_FUNCTION_REFERENCE: - $name = ! empty($value[2]) ? $value[2] : ''; - - return "get-function(\"$name\")"; - - case Type::T_LIST: - $value = $this->extractInterpolation($value); - - if ($value[0] !== Type::T_LIST) { - return $this->compileValue($value, $quote); - } - - list(, $delim, $items) = $value; - $pre = $post = ''; - - if (! empty($value['enclosing'])) { - switch ($value['enclosing']) { - case 'parent': - //$pre = '('; - //$post = ')'; - break; - case 'forced_parent': - $pre = '('; - $post = ')'; - break; - case 'bracket': - case 'forced_bracket': - $pre = '['; - $post = ']'; - break; - } - } - - $separator = $delim === '/' ? ' /' : $delim; - - $prefix_value = ''; - - if ($delim !== ' ') { - $prefix_value = ' '; - } - - $filtered = []; - - $same_string_quote = null; - foreach ($items as $item) { - if (\is_null($same_string_quote)) { - $same_string_quote = false; - if ($item[0] === Type::T_STRING) { - $same_string_quote = $item[1]; - foreach ($items as $ii) { - if ($ii[0] !== Type::T_STRING) { - $same_string_quote = false; - break; - } - } - } - } - if ($item[0] === Type::T_NULL) { - continue; - } - if ($same_string_quote === '"' && $item[0] === Type::T_STRING && $item[1]) { - $item[1] = $same_string_quote; - } - - $compiled = $this->compileValue($item, $quote); - - if ($prefix_value && \strlen($compiled)) { - $compiled = $prefix_value . $compiled; - } - - $filtered[] = $compiled; - } - - return $pre . substr(implode($separator, $filtered), \strlen($prefix_value)) . $post; - - case Type::T_MAP: - $keys = $value[1]; - $values = $value[2]; - $filtered = []; - - for ($i = 0, $s = \count($keys); $i < $s; $i++) { - $filtered[$this->compileValue($keys[$i], $quote)] = $this->compileValue($values[$i], $quote); - } - - array_walk($filtered, function (&$value, $key) { - $value = $key . ': ' . $value; - }); - - return '(' . implode(', ', $filtered) . ')'; - - case Type::T_INTERPOLATED: - // node created by extractInterpolation - list(, $interpolate, $left, $right) = $value; - list(,, $whiteLeft, $whiteRight) = $interpolate; - - $delim = $left[1]; - - if ($delim && $delim !== ' ' && ! $whiteLeft) { - $delim .= ' '; - } - - $left = \count($left[2]) > 0 - ? $this->compileValue($left, $quote) . $delim . $whiteLeft - : ''; - - $delim = $right[1]; - - if ($delim && $delim !== ' ') { - $delim .= ' '; - } - - $right = \count($right[2]) > 0 ? - $whiteRight . $delim . $this->compileValue($right, $quote) : ''; - - return $left . $this->compileValue($interpolate, $quote) . $right; - - case Type::T_INTERPOLATE: - // strip quotes if it's a string - $reduced = $this->reduce($value[1]); - - if ($reduced instanceof Number) { - return $this->compileValue($reduced, $quote); - } - - switch ($reduced[0]) { - case Type::T_LIST: - $reduced = $this->extractInterpolation($reduced); - - if ($reduced[0] !== Type::T_LIST) { - break; - } - - list(, $delim, $items) = $reduced; - - if ($delim !== ' ') { - $delim .= ' '; - } - - $filtered = []; - - foreach ($items as $item) { - if ($item[0] === Type::T_NULL) { - continue; - } - - if ($item[0] === Type::T_STRING) { - $filtered[] = $this->compileStringContent($item, $quote); - } elseif ($item[0] === Type::T_KEYWORD) { - $filtered[] = $item[1]; - } else { - $filtered[] = $this->compileValue($item, $quote); - } - } - - $reduced = [Type::T_KEYWORD, implode("$delim", $filtered)]; - break; - - case Type::T_STRING: - $reduced = [Type::T_STRING, '', [$this->compileStringContent($reduced)]]; - break; - - case Type::T_NULL: - $reduced = [Type::T_KEYWORD, '']; - } - - return $this->compileValue($reduced, $quote); - - case Type::T_NULL: - return 'null'; - - case Type::T_COMMENT: - return $this->compileCommentValue($value); - - default: - throw $this->error('unknown value type: ' . json_encode($value)); - } - } - - /** - * @param array|Number $value - * - * @return string - */ - protected function compileDebugValue($value) - { - $value = $this->reduce($value, true); - - if ($value instanceof Number) { - return $this->compileValue($value); - } - - switch ($value[0]) { - case Type::T_STRING: - return $this->compileStringContent($value); - - default: - return $this->compileValue($value); - } - } - - /** - * Flatten list - * - * @param array $list - * - * @return string - * - * @deprecated - */ - protected function flattenList($list) - { - @trigger_error(sprintf('The "%s" method is deprecated.', __METHOD__), E_USER_DEPRECATED); - - return $this->compileValue($list); - } - - /** - * Gets the text of a Sass string - * - * Calling this method on anything else than a SassString is unsupported. Use {@see assertString} first - * to ensure that the value is indeed a string. - * - * @param array $value - * - * @return string - */ - public function getStringText(array $value) - { - if ($value[0] !== Type::T_STRING) { - throw new \InvalidArgumentException('The argument is not a sass string. Did you forgot to use "assertString"?'); - } - - return $this->compileStringContent($value); - } - - /** - * Compile string content - * - * @param array $string - * @param bool $quote - * - * @return string - */ - protected function compileStringContent($string, $quote = true) - { - $parts = []; - - foreach ($string[2] as $part) { - if (\is_array($part) || $part instanceof Number) { - $parts[] = $this->compileValue($part, $quote); - } else { - $parts[] = $part; - } - } - - return implode($parts); - } - - /** - * Extract interpolation; it doesn't need to be recursive, compileValue will handle that - * - * @param array $list - * - * @return array - */ - protected function extractInterpolation($list) - { - $items = $list[2]; - - foreach ($items as $i => $item) { - if ($item[0] === Type::T_INTERPOLATE) { - $before = [Type::T_LIST, $list[1], \array_slice($items, 0, $i)]; - $after = [Type::T_LIST, $list[1], \array_slice($items, $i + 1)]; - - return [Type::T_INTERPOLATED, $item, $before, $after]; - } - } - - return $list; - } - - /** - * Find the final set of selectors - * - * @param \ScssPhp\ScssPhp\Compiler\Environment $env - * @param \ScssPhp\ScssPhp\Block $selfParent - * - * @return array - */ - protected function multiplySelectors(Environment $env, $selfParent = null) - { - $envs = $this->compactEnv($env); - $selectors = []; - $parentSelectors = [[]]; - - $selfParentSelectors = null; - - if (! \is_null($selfParent) && $selfParent->selectors) { - $selfParentSelectors = $this->evalSelectors($selfParent->selectors); - } - - while ($env = array_pop($envs)) { - if (empty($env->selectors)) { - continue; - } - - $selectors = $env->selectors; - - do { - $stillHasSelf = false; - $prevSelectors = $selectors; - $selectors = []; - - foreach ($parentSelectors as $parent) { - foreach ($prevSelectors as $selector) { - if ($selfParentSelectors) { - foreach ($selfParentSelectors as $selfParent) { - // if no '&' in the selector, each call will give same result, only add once - $s = $this->joinSelectors($parent, $selector, $stillHasSelf, $selfParent); - $selectors[serialize($s)] = $s; - } - } else { - $s = $this->joinSelectors($parent, $selector, $stillHasSelf); - $selectors[serialize($s)] = $s; - } - } - } - } while ($stillHasSelf); - - $parentSelectors = $selectors; - } - - $selectors = array_values($selectors); - - // case we are just starting a at-root : nothing to multiply but parentSelectors - if (! $selectors && $selfParentSelectors) { - $selectors = $selfParentSelectors; - } - - return $selectors; - } - - /** - * Join selectors; looks for & to replace, or append parent before child - * - * @param array $parent - * @param array $child - * @param bool $stillHasSelf - * @param array $selfParentSelectors - - * @return array - */ - protected function joinSelectors($parent, $child, &$stillHasSelf, $selfParentSelectors = null) - { - $setSelf = false; - $out = []; - - foreach ($child as $part) { - $newPart = []; - - foreach ($part as $p) { - // only replace & once and should be recalled to be able to make combinations - if ($p === static::$selfSelector && $setSelf) { - $stillHasSelf = true; - } - - if ($p === static::$selfSelector && ! $setSelf) { - $setSelf = true; - - if (\is_null($selfParentSelectors)) { - $selfParentSelectors = $parent; - } - - foreach ($selfParentSelectors as $i => $parentPart) { - if ($i > 0) { - $out[] = $newPart; - $newPart = []; - } - - foreach ($parentPart as $pp) { - if (\is_array($pp)) { - $flatten = []; - - array_walk_recursive($pp, function ($a) use (&$flatten) { - $flatten[] = $a; - }); - - $pp = implode($flatten); - } - - $newPart[] = $pp; - } - } - } else { - $newPart[] = $p; - } - } - - $out[] = $newPart; - } - - return $setSelf ? $out : array_merge($parent, $child); - } - - /** - * Multiply media - * - * @param \ScssPhp\ScssPhp\Compiler\Environment $env - * @param array $childQueries - * - * @return array - */ - protected function multiplyMedia(Environment $env = null, $childQueries = null) - { - if ( - ! isset($env) || - ! empty($env->block->type) && $env->block->type !== Type::T_MEDIA - ) { - return $childQueries; - } - - // plain old block, skip - if (empty($env->block->type)) { - return $this->multiplyMedia($env->parent, $childQueries); - } - - assert($env->block instanceof MediaBlock); - - $parentQueries = isset($env->block->queryList) - ? $env->block->queryList - : [[[Type::T_MEDIA_VALUE, $env->block->value]]]; - - $store = [$this->env, $this->storeEnv]; - - $this->env = $env; - $this->storeEnv = null; - $parentQueries = $this->evaluateMediaQuery($parentQueries); - - list($this->env, $this->storeEnv) = $store; - - if (\is_null($childQueries)) { - $childQueries = $parentQueries; - } else { - $originalQueries = $childQueries; - $childQueries = []; - - foreach ($parentQueries as $parentQuery) { - foreach ($originalQueries as $childQuery) { - $childQueries[] = array_merge( - $parentQuery, - [[Type::T_MEDIA_TYPE, [Type::T_KEYWORD, 'all']]], - $childQuery - ); - } - } - } - - return $this->multiplyMedia($env->parent, $childQueries); - } - - /** - * Convert env linked list to stack - * - * @param Environment $env - * - * @return Environment[] - * - * @phpstan-return non-empty-array - */ - protected function compactEnv(Environment $env) - { - for ($envs = []; $env; $env = $env->parent) { - $envs[] = $env; - } - - return $envs; - } - - /** - * Convert env stack to singly linked list - * - * @param Environment[] $envs - * - * @return Environment - * - * @phpstan-param non-empty-array $envs - */ - protected function extractEnv($envs) - { - for ($env = null; $e = array_pop($envs);) { - $e->parent = $env; - $env = $e; - } - - return $env; - } - - /** - * Push environment - * - * @param \ScssPhp\ScssPhp\Block $block - * - * @return \ScssPhp\ScssPhp\Compiler\Environment - */ - protected function pushEnv(Block $block = null) - { - $env = new Environment(); - $env->parent = $this->env; - $env->parentStore = $this->storeEnv; - $env->store = []; - $env->block = $block; - $env->depth = isset($this->env->depth) ? $this->env->depth + 1 : 0; - - $this->env = $env; - $this->storeEnv = null; - - return $env; - } - - /** - * Pop environment - * - * @return void - */ - protected function popEnv() - { - $this->storeEnv = $this->env->parentStore; - $this->env = $this->env->parent; - } - - /** - * Propagate vars from a just poped Env (used in @each and @for) - * - * @param array $store - * @param null|string[] $excludedVars - * - * @return void - */ - protected function backPropagateEnv($store, $excludedVars = null) - { - foreach ($store as $key => $value) { - if (empty($excludedVars) || ! \in_array($key, $excludedVars)) { - $this->set($key, $value, true); - } - } - } - - /** - * Get store environment - * - * @return \ScssPhp\ScssPhp\Compiler\Environment - */ - protected function getStoreEnv() - { - return isset($this->storeEnv) ? $this->storeEnv : $this->env; - } - - /** - * Set variable - * - * @param string $name - * @param mixed $value - * @param bool $shadow - * @param \ScssPhp\ScssPhp\Compiler\Environment $env - * @param mixed $valueUnreduced - * - * @return void - */ - protected function set($name, $value, $shadow = false, Environment $env = null, $valueUnreduced = null) - { - $name = $this->normalizeName($name); - - if (! isset($env)) { - $env = $this->getStoreEnv(); - } - - if ($shadow) { - $this->setRaw($name, $value, $env, $valueUnreduced); - } else { - $this->setExisting($name, $value, $env, $valueUnreduced); - } - } - - /** - * Set existing variable - * - * @param string $name - * @param mixed $value - * @param \ScssPhp\ScssPhp\Compiler\Environment $env - * @param mixed $valueUnreduced - * - * @return void - */ - protected function setExisting($name, $value, Environment $env, $valueUnreduced = null) - { - $storeEnv = $env; - $specialContentKey = static::$namespaces['special'] . 'content'; - - $hasNamespace = $name[0] === '^' || $name[0] === '@' || $name[0] === '%'; - - $maxDepth = 10000; - - for (;;) { - if ($maxDepth-- <= 0) { - break; - } - - if (\array_key_exists($name, $env->store)) { - break; - } - - if (! $hasNamespace && isset($env->marker)) { - if (! empty($env->store[$specialContentKey])) { - $env = $env->store[$specialContentKey]->scope; - continue; - } - - if (! empty($env->declarationScopeParent)) { - $env = $env->declarationScopeParent; - continue; - } else { - $env = $storeEnv; - break; - } - } - - if (isset($env->parentStore)) { - $env = $env->parentStore; - } elseif (isset($env->parent)) { - $env = $env->parent; - } else { - $env = $storeEnv; - break; - } - } - - $env->store[$name] = $value; - - if ($valueUnreduced) { - $env->storeUnreduced[$name] = $valueUnreduced; - } - } - - /** - * Set raw variable - * - * @param string $name - * @param mixed $value - * @param \ScssPhp\ScssPhp\Compiler\Environment $env - * @param mixed $valueUnreduced - * - * @return void - */ - protected function setRaw($name, $value, Environment $env, $valueUnreduced = null) - { - $env->store[$name] = $value; - - if ($valueUnreduced) { - $env->storeUnreduced[$name] = $valueUnreduced; - } - } - - /** - * Get variable - * - * @internal - * - * @param string $name - * @param bool $shouldThrow - * @param \ScssPhp\ScssPhp\Compiler\Environment $env - * @param bool $unreduced - * - * @return mixed|null - */ - public function get($name, $shouldThrow = true, Environment $env = null, $unreduced = false) - { - $normalizedName = $this->normalizeName($name); - $specialContentKey = static::$namespaces['special'] . 'content'; - - if (! isset($env)) { - $env = $this->getStoreEnv(); - } - - $hasNamespace = $normalizedName[0] === '^' || $normalizedName[0] === '@' || $normalizedName[0] === '%'; - - $maxDepth = 10000; - - for (;;) { - if ($maxDepth-- <= 0) { - break; - } - - if (\array_key_exists($normalizedName, $env->store)) { - if ($unreduced && isset($env->storeUnreduced[$normalizedName])) { - return $env->storeUnreduced[$normalizedName]; - } - - return $env->store[$normalizedName]; - } - - if (! $hasNamespace && isset($env->marker)) { - if (! empty($env->store[$specialContentKey])) { - $env = $env->store[$specialContentKey]->scope; - continue; - } - - if (! empty($env->declarationScopeParent)) { - $env = $env->declarationScopeParent; - } else { - $env = $this->rootEnv; - } - continue; - } - - if (isset($env->parentStore)) { - $env = $env->parentStore; - } elseif (isset($env->parent)) { - $env = $env->parent; - } else { - break; - } - } - - if ($shouldThrow) { - throw $this->error("Undefined variable \$$name" . ($maxDepth <= 0 ? ' (infinite recursion)' : '')); - } - - // found nothing - return null; - } - - /** - * Has variable? - * - * @param string $name - * @param \ScssPhp\ScssPhp\Compiler\Environment $env - * - * @return bool - */ - protected function has($name, Environment $env = null) - { - return ! \is_null($this->get($name, false, $env)); - } - - /** - * Inject variables - * - * @param array $args - * - * @return void - */ - protected function injectVariables(array $args) - { - if (empty($args)) { - return; - } - - $parser = $this->parserFactory(__METHOD__); - - foreach ($args as $name => $strValue) { - if ($name[0] === '$') { - $name = substr($name, 1); - } - - if (!\is_string($strValue) || ! $parser->parseValue($strValue, $value)) { - $value = $this->coerceValue($strValue); - } - - $this->set($name, $value); - } - } - - /** - * Replaces variables. - * - * @param array $variables - * - * @return void - */ - public function replaceVariables(array $variables) - { - $this->registeredVars = []; - $this->addVariables($variables); - } - - /** - * Replaces variables. - * - * @param array $variables - * - * @return void - */ - public function addVariables(array $variables) - { - $triggerWarning = false; - - foreach ($variables as $name => $value) { - if (!$value instanceof Number && !\is_array($value)) { - $triggerWarning = true; - } - - $this->registeredVars[$name] = $value; - } - - if ($triggerWarning) { - @trigger_error('Passing raw values to as custom variables to the Compiler is deprecated. Use "\ScssPhp\ScssPhp\ValueConverter::parseValue" or "\ScssPhp\ScssPhp\ValueConverter::fromPhp" to convert them instead.', E_USER_DEPRECATED); - } - } - - /** - * Set variables - * - * @api - * - * @param array $variables - * - * @return void - * - * @deprecated Use "addVariables" or "replaceVariables" instead. - */ - public function setVariables(array $variables) - { - @trigger_error('The method "setVariables" of the Compiler is deprecated. Use the "addVariables" method for the equivalent behavior or "replaceVariables" if merging with previous variables was not desired.'); - - $this->addVariables($variables); - } - - /** - * Unset variable - * - * @api - * - * @param string $name - * - * @return void - */ - public function unsetVariable($name) - { - unset($this->registeredVars[$name]); - } - - /** - * Returns list of variables - * - * @api - * - * @return array - */ - public function getVariables() - { - return $this->registeredVars; - } - - /** - * Adds to list of parsed files - * - * @internal - * - * @param string|null $path - * - * @return void - */ - public function addParsedFile($path) - { - if (! \is_null($path) && is_file($path)) { - $this->parsedFiles[realpath($path)] = filemtime($path); - } - } - - /** - * Returns list of parsed files - * - * @deprecated - * @return array - */ - public function getParsedFiles() - { - @trigger_error('The method "getParsedFiles" of the Compiler is deprecated. Use the "getIncludedFiles" method on the CompilationResult instance returned by compileString() instead. Be careful that the signature of the method is different.', E_USER_DEPRECATED); - return $this->parsedFiles; - } - - /** - * Add import path - * - * @api - * - * @param string|callable $path - * - * @return void - */ - public function addImportPath($path) - { - if (! \in_array($path, $this->importPaths)) { - $this->importPaths[] = $path; - } - } - - /** - * Set import paths - * - * @api - * - * @param string|array $path - * - * @return void - */ - public function setImportPaths($path) - { - $paths = (array) $path; - $actualImportPaths = array_filter($paths, function ($path) { - return $path !== ''; - }); - - $this->legacyCwdImportPath = \count($actualImportPaths) !== \count($paths); - - if ($this->legacyCwdImportPath) { - @trigger_error('Passing an empty string in the import paths to refer to the current working directory is deprecated. If that\'s the intended behavior, the value of "getcwd()" should be used directly instead. If this was used for resolving relative imports of the input alongside "chdir" with the source directory, the path of the input file should be passed to "compileString()" instead.', E_USER_DEPRECATED); - } - - $this->importPaths = $actualImportPaths; - } - - /** - * Set number precision - * - * @api - * - * @param int $numberPrecision - * - * @return void - * - * @deprecated The number precision is not configurable anymore. The default is enough for all browsers. - */ - public function setNumberPrecision($numberPrecision) - { - @trigger_error('The number precision is not configurable anymore. ' - . 'The default is enough for all browsers.', E_USER_DEPRECATED); - } - - /** - * Sets the output style. - * - * @api - * - * @param string $style One of the OutputStyle constants - * - * @return void - * - * @phpstan-param OutputStyle::* $style - */ - public function setOutputStyle($style) - { - switch ($style) { - case OutputStyle::EXPANDED: - $this->configuredFormatter = Expanded::class; - break; - - case OutputStyle::COMPRESSED: - $this->configuredFormatter = Compressed::class; - break; - - default: - throw new \InvalidArgumentException(sprintf('Invalid output style "%s".', $style)); - } - } - - /** - * Set formatter - * - * @api - * - * @param string $formatterName - * - * @return void - * - * @deprecated Use {@see setOutputStyle} instead. - * - * @phpstan-param class-string $formatterName - */ - public function setFormatter($formatterName) - { - if (!\in_array($formatterName, [Expanded::class, Compressed::class], true)) { - @trigger_error('Formatters other than Expanded and Compressed are deprecated.', E_USER_DEPRECATED); - } - @trigger_error('The method "setFormatter" is deprecated. Use "setOutputStyle" instead.', E_USER_DEPRECATED); - - $this->configuredFormatter = $formatterName; - } - - /** - * Set line number style - * - * @api - * - * @param string $lineNumberStyle - * - * @return void - * - * @deprecated The line number output is not supported anymore. Use source maps instead. - */ - public function setLineNumberStyle($lineNumberStyle) - { - @trigger_error('The line number output is not supported anymore. ' - . 'Use source maps instead.', E_USER_DEPRECATED); - } - - /** - * Configures the handling of non-ASCII outputs. - * - * If $charset is `true`, this will include a `@charset` declaration or a - * UTF-8 [byte-order mark][] if the stylesheet contains any non-ASCII - * characters. Otherwise, it will never include a `@charset` declaration or a - * byte-order mark. - * - * [byte-order mark]: https://en.wikipedia.org/wiki/Byte_order_mark#UTF-8 - * - * @param bool $charset - * - * @return void - */ - public function setCharset($charset) - { - $this->charset = $charset; - } - - /** - * Enable/disable source maps - * - * @api - * - * @param int $sourceMap - * - * @return void - * - * @phpstan-param self::SOURCE_MAP_* $sourceMap - */ - public function setSourceMap($sourceMap) - { - $this->sourceMap = $sourceMap; - } - - /** - * Set source map options - * - * @api - * - * @param array $sourceMapOptions - * - * @phpstan-param array{sourceRoot?: string, sourceMapFilename?: string|null, sourceMapURL?: string|null, sourceMapWriteTo?: string|null, outputSourceFiles?: bool, sourceMapRootpath?: string, sourceMapBasepath?: string} $sourceMapOptions - * - * @return void - */ - public function setSourceMapOptions($sourceMapOptions) - { - $this->sourceMapOptions = $sourceMapOptions; - } - - /** - * Register function - * - * @api - * - * @param string $name - * @param callable $callback - * @param string[]|null $argumentDeclaration - * - * @return void - */ - public function registerFunction($name, $callback, $argumentDeclaration = null) - { - if (self::isNativeFunction($name)) { - @trigger_error(sprintf('The "%s" function is a core sass function. Overriding it with a custom implementation through "%s" is deprecated and won\'t be supported in ScssPhp 2.0 anymore.', $name, __METHOD__), E_USER_DEPRECATED); - } - - if ($argumentDeclaration === null) { - @trigger_error('Omitting the argument declaration when registering custom function is deprecated and won\'t be supported in ScssPhp 2.0 anymore.', E_USER_DEPRECATED); - } - - if ($this->reflectCallable($callback)->getNumberOfRequiredParameters() > 1) { - @trigger_error('The second argument passed to the callback of custom functions is deprecated and won\'t be supported in ScssPhp 2.0 anymore. Register a callback accepting only 1 parameter instead.', E_USER_DEPRECATED); - } - - $this->userFunctions[$this->normalizeName($name)] = [$callback, $argumentDeclaration]; - } - - /** - * @return \ReflectionFunctionAbstract - */ - private function reflectCallable(callable $c) - { - if (\is_object($c) && !$c instanceof \Closure) { - $c = [$c, '__invoke']; - } - - if (\is_string($c) && false !== strpos($c, '::')) { - $c = explode('::', $c, 2); - } - - if (\is_array($c)) { - return new \ReflectionMethod($c[0], $c[1]); - } - - \assert(\is_string($c) || $c instanceof \Closure); - - return new \ReflectionFunction($c); - } - - /** - * Unregister function - * - * @api - * - * @param string $name - * - * @return void - */ - public function unregisterFunction($name) - { - unset($this->userFunctions[$this->normalizeName($name)]); - } - - /** - * Add feature - * - * @api - * - * @param string $name - * - * @return void - * - * @deprecated Registering additional features is deprecated. - */ - public function addFeature($name) - { - @trigger_error('Registering additional features is deprecated.', E_USER_DEPRECATED); - - $this->registeredFeatures[$name] = true; - } - - /** - * Import file - * - * @param string $path - * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $out - * - * @return void - */ - protected function importFile($path, OutputBlock $out) - { - $this->pushCallStack('import ' . $this->getPrettyPath($path)); - // see if tree is cached - $realPath = realpath($path); - - if ($realPath === false) { - $realPath = $path; - } - - if (substr($path, -5) === '.sass') { - $this->sourceIndex = \count($this->sourceNames); - $this->sourceNames[] = $path; - $this->sourceLine = 1; - $this->sourceColumn = 1; - - throw $this->error('The Sass indented syntax is not implemented.'); - } - - if (isset($this->importCache[$realPath])) { - $this->handleImportLoop($realPath); - - $tree = $this->importCache[$realPath]; - } else { - $code = file_get_contents($path); - $parser = $this->parserFactory($path); - $tree = $parser->parse($code); - - $this->importCache[$realPath] = $tree; - } - - $currentDirectory = $this->currentDirectory; - $this->currentDirectory = dirname($path); - - $this->compileChildrenNoReturn($tree->children, $out); - $this->currentDirectory = $currentDirectory; - $this->popCallStack(); - } - - /** - * Save the imported files with their resolving path context - * - * @param string|null $currentDirectory - * @param string $path - * @param string $filePath - * - * @return void - */ - private function registerImport($currentDirectory, $path, $filePath) - { - $this->resolvedImports[] = ['currentDir' => $currentDirectory, 'path' => $path, 'filePath' => $filePath]; - } - - /** - * Detects whether the import is a CSS import. - * - * For legacy reasons, custom importers are called for those, allowing them - * to replace them with an actual Sass import. However this behavior is - * deprecated. Custom importers are expected to return null when they receive - * a CSS import. - * - * @param string $url - * - * @return bool - */ - public static function isCssImport($url) - { - return 1 === preg_match('~\.css$|^https?://|^//~', $url); - } - - /** - * Return the file path for an import url if it exists - * - * @internal - * - * @param string $url - * @param string|null $currentDir - * - * @return string|null - */ - public function findImport($url, $currentDir = null) - { - // Vanilla css and external requests. These are not meant to be Sass imports. - // Callback importers are still called for BC. - if (self::isCssImport($url)) { - foreach ($this->importPaths as $dir) { - if (\is_string($dir)) { - continue; - } - - if (\is_callable($dir)) { - // check custom callback for import path - $file = \call_user_func($dir, $url); - - if (! \is_null($file)) { - if (\is_array($dir)) { - $callableDescription = (\is_object($dir[0]) ? \get_class($dir[0]) : $dir[0]) . '::' . $dir[1]; - } elseif ($dir instanceof \Closure) { - $r = new \ReflectionFunction($dir); - if (false !== strpos($r->name, '{closure}')) { - $callableDescription = sprintf('closure{%s:%s}', $r->getFileName(), $r->getStartLine()); - } elseif ($class = $r->getClosureScopeClass()) { - $callableDescription = $class->name . '::' . $r->name; - } else { - $callableDescription = $r->name; - } - } elseif (\is_object($dir)) { - $callableDescription = \get_class($dir) . '::__invoke'; - } else { - $callableDescription = 'callable'; // Fallback if we don't have a dedicated description - } - @trigger_error(sprintf('Returning a file to import for CSS or external references in custom importer callables is deprecated and will not be supported anymore in ScssPhp 2.0. This behavior is not compliant with the Sass specification. Update your "%s" importer.', $callableDescription), E_USER_DEPRECATED); - - return $file; - } - } - } - return null; - } - - if (!\is_null($currentDir)) { - $relativePath = $this->resolveImportPath($url, $currentDir); - - if (!\is_null($relativePath)) { - return $relativePath; - } - } - - foreach ($this->importPaths as $dir) { - if (\is_string($dir)) { - $path = $this->resolveImportPath($url, $dir); - - if (!\is_null($path)) { - return $path; - } - } elseif (\is_callable($dir)) { - // check custom callback for import path - $file = \call_user_func($dir, $url); - - if (! \is_null($file)) { - return $file; - } - } - } - - if ($this->legacyCwdImportPath) { - $path = $this->resolveImportPath($url, getcwd()); - - if (!\is_null($path)) { - @trigger_error('Resolving imports relatively to the current working directory is deprecated. If that\'s the intended behavior, the value of "getcwd()" should be added as an import path explicitly instead. If this was used for resolving relative imports of the input alongside "chdir" with the source directory, the path of the input file should be passed to "compileString()" instead.', E_USER_DEPRECATED); - - return $path; - } - } - - throw $this->error("`$url` file not found for @import"); - } - - /** - * @param string $url - * @param string $baseDir - * - * @return string|null - */ - private function resolveImportPath($url, $baseDir) - { - $path = Path::join($baseDir, $url); - - $hasExtension = preg_match('/.s[ac]ss$/', $url); - - if ($hasExtension) { - return $this->checkImportPathConflicts($this->tryImportPath($path)); - } - - $result = $this->checkImportPathConflicts($this->tryImportPathWithExtensions($path)); - - if (!\is_null($result)) { - return $result; - } - - return $this->tryImportPathAsDirectory($path); - } - - /** - * @param string[] $paths - * - * @return string|null - */ - private function checkImportPathConflicts(array $paths) - { - if (\count($paths) === 0) { - return null; - } - - if (\count($paths) === 1) { - return $paths[0]; - } - - $formattedPrettyPaths = []; - - foreach ($paths as $path) { - $formattedPrettyPaths[] = ' ' . $this->getPrettyPath($path); - } - - throw $this->error("It's not clear which file to import. Found:\n" . implode("\n", $formattedPrettyPaths)); - } - - /** - * @param string $path - * - * @return string[] - */ - private function tryImportPathWithExtensions($path) - { - $result = array_merge( - $this->tryImportPath($path . '.sass'), - $this->tryImportPath($path . '.scss') - ); - - if ($result) { - return $result; - } - - return $this->tryImportPath($path . '.css'); - } - - /** - * @param string $path - * - * @return string[] - */ - private function tryImportPath($path) - { - $partial = dirname($path) . '/_' . basename($path); - - $candidates = []; - - if (is_file($partial)) { - $candidates[] = $partial; - } - - if (is_file($path)) { - $candidates[] = $path; - } - - return $candidates; - } - - /** - * @param string $path - * - * @return string|null - */ - private function tryImportPathAsDirectory($path) - { - if (!is_dir($path)) { - return null; - } - - return $this->checkImportPathConflicts($this->tryImportPathWithExtensions($path . '/index')); - } - - /** - * @param string|null $path - * - * @return string - */ - private function getPrettyPath($path) - { - if ($path === null) { - return '(unknown file)'; - } - - $normalizedPath = $path; - $normalizedRootDirectory = $this->rootDirectory . '/'; - - if (\DIRECTORY_SEPARATOR === '\\') { - $normalizedRootDirectory = str_replace('\\', '/', $normalizedRootDirectory); - $normalizedPath = str_replace('\\', '/', $path); - } - - if (0 === strpos($normalizedPath, $normalizedRootDirectory)) { - return substr($path, \strlen($normalizedRootDirectory)); - } - - return $path; - } - - /** - * Set encoding - * - * @api - * - * @param string|null $encoding - * - * @return void - * - * @deprecated Non-compliant support for other encodings than UTF-8 is deprecated. - */ - public function setEncoding($encoding) - { - if (!$encoding || strtolower($encoding) === 'utf-8') { - @trigger_error(sprintf('The "%s" method is deprecated.', __METHOD__), E_USER_DEPRECATED); - } else { - @trigger_error(sprintf('The "%s" method is deprecated. Parsing will only support UTF-8 in ScssPhp 2.0. The non-UTF-8 parsing of ScssPhp 1.x is not spec compliant.', __METHOD__), E_USER_DEPRECATED); - } - - $this->encoding = $encoding; - } - - /** - * Ignore errors? - * - * @api - * - * @param bool $ignoreErrors - * - * @return \ScssPhp\ScssPhp\Compiler - * - * @deprecated Ignoring Sass errors is not longer supported. - */ - public function setIgnoreErrors($ignoreErrors) - { - @trigger_error('Ignoring Sass errors is not longer supported.', E_USER_DEPRECATED); - - return $this; - } - - /** - * Get source position - * - * @api - * - * @return array - * - * @deprecated - */ - public function getSourcePosition() - { - @trigger_error(sprintf('The "%s" method is deprecated.', __METHOD__), E_USER_DEPRECATED); - - $sourceFile = isset($this->sourceNames[$this->sourceIndex]) ? $this->sourceNames[$this->sourceIndex] : ''; - - return [$sourceFile, $this->sourceLine, $this->sourceColumn]; - } - - /** - * Throw error (exception) - * - * @api - * - * @param string $msg Message with optional sprintf()-style vararg parameters - * - * @return never - * - * @throws \ScssPhp\ScssPhp\Exception\CompilerException - * - * @deprecated use "error" and throw the exception in the caller instead. - */ - public function throwError($msg) - { - @trigger_error( - 'The method "throwError" is deprecated. Use "error" and throw the exception in the caller instead', - E_USER_DEPRECATED - ); - - throw $this->error(...func_get_args()); - } - - /** - * Build an error (exception) - * - * @internal - * - * @param string $msg Message with optional sprintf()-style vararg parameters - * @param bool|float|int|string|null ...$args - * - * @return CompilerException - */ - public function error($msg, ...$args) - { - if ($args) { - $msg = sprintf($msg, ...$args); - } - - if (! $this->ignoreCallStackMessage) { - $msg = $this->addLocationToMessage($msg); - } - - return new CompilerException($msg); - } - - /** - * @param string $msg - * - * @return string - */ - private function addLocationToMessage($msg) - { - $line = $this->sourceLine; - $column = $this->sourceColumn; - - $loc = isset($this->sourceNames[$this->sourceIndex]) - ? $this->getPrettyPath($this->sourceNames[$this->sourceIndex]) . " on line $line, at column $column" - : "line: $line, column: $column"; - - $msg = "$msg: $loc"; - - $callStackMsg = $this->callStackMessage(); - - if ($callStackMsg) { - $msg .= "\nCall Stack:\n" . $callStackMsg; - } - - return $msg; - } - - /** - * @param string $functionName - * @param array $ExpectedArgs - * @param int $nbActual - * @return CompilerException - * - * @deprecated - */ - public function errorArgsNumber($functionName, $ExpectedArgs, $nbActual) - { - @trigger_error(sprintf('The "%s" method is deprecated.', __METHOD__), E_USER_DEPRECATED); - - $nbExpected = \count($ExpectedArgs); - - if ($nbActual > $nbExpected) { - return $this->error( - 'Error: Only %d arguments allowed in %s(), but %d were passed.', - $nbExpected, - $functionName, - $nbActual - ); - } else { - $missing = []; - - while (count($ExpectedArgs) && count($ExpectedArgs) > $nbActual) { - array_unshift($missing, array_pop($ExpectedArgs)); - } - - return $this->error( - 'Error: %s() argument%s %s missing.', - $functionName, - count($missing) > 1 ? 's' : '', - implode(', ', $missing) - ); - } - } - - /** - * Beautify call stack for output - * - * @param bool $all - * @param int|null $limit - * - * @return string - */ - protected function callStackMessage($all = false, $limit = null) - { - $callStackMsg = []; - $ncall = 0; - - if ($this->callStack) { - foreach (array_reverse($this->callStack) as $call) { - if ($all || (isset($call['n']) && $call['n'])) { - $msg = '#' . $ncall++ . ' ' . $call['n'] . ' '; - $msg .= (isset($this->sourceNames[$call[Parser::SOURCE_INDEX]]) - ? $this->getPrettyPath($this->sourceNames[$call[Parser::SOURCE_INDEX]]) - : '(unknown file)'); - $msg .= ' on line ' . $call[Parser::SOURCE_LINE]; - - $callStackMsg[] = $msg; - - if (! \is_null($limit) && $ncall > $limit) { - break; - } - } - } - } - - return implode("\n", $callStackMsg); - } - - /** - * Handle import loop - * - * @param string $name - * - * @return void - * - * @throws \Exception - */ - protected function handleImportLoop($name) - { - for ($env = $this->env; $env; $env = $env->parent) { - if (! $env->block) { - continue; - } - - $file = $this->sourceNames[$env->block->sourceIndex]; - - if ($file === null) { - continue; - } - - if (realpath($file) === $name) { - throw $this->error('An @import loop has been found: %s imports %s', $file, basename($file)); - } - } - } - - /** - * Call SCSS @function - * - * @param CallableBlock|null $func - * @param array $argValues - * - * @return array|Number - */ - protected function callScssFunction($func, $argValues) - { - if (! $func) { - return static::$defaultValue; - } - $name = $func->name; - - $this->pushEnv(); - - // set the args - if (isset($func->args)) { - $this->applyArguments($func->args, $argValues); - } - - // throw away lines and children - $tmp = new OutputBlock(); - $tmp->lines = []; - $tmp->children = []; - - $this->env->marker = 'function'; - - if (! empty($func->parentEnv)) { - $this->env->declarationScopeParent = $func->parentEnv; - } else { - throw $this->error("@function $name() without parentEnv"); - } - - $ret = $this->compileChildren($func->children, $tmp, $this->env->marker . ' ' . $name); - - $this->popEnv(); - - return ! isset($ret) ? static::$defaultValue : $ret; - } - - /** - * Call built-in and registered (PHP) functions - * - * @param string $name - * @param callable $function - * @param array $prototype - * @param array $args - * - * @return array|Number|null - */ - protected function callNativeFunction($name, $function, $prototype, $args) - { - $libName = (is_array($function) ? end($function) : null); - $sorted_kwargs = $this->sortNativeFunctionArgs($libName, $prototype, $args); - - if (\is_null($sorted_kwargs)) { - return null; - } - @list($sorted, $kwargs) = $sorted_kwargs; - - if ($name !== 'if') { - foreach ($sorted as &$val) { - if ($val !== null) { - $val = $this->reduce($val, true); - } - } - } - - $returnValue = \call_user_func($function, $sorted, $kwargs); - - if (! isset($returnValue)) { - return null; - } - - if (\is_array($returnValue) || $returnValue instanceof Number) { - return $returnValue; - } - - @trigger_error(sprintf('Returning a PHP value from the "%s" custom function is deprecated. A sass value must be returned instead.', $name), E_USER_DEPRECATED); - - return $this->coerceValue($returnValue); - } - - /** - * Get built-in function - * - * @param string $name Normalized name - * - * @return array - */ - protected function getBuiltinFunction($name) - { - $libName = self::normalizeNativeFunctionName($name); - return [$this, $libName]; - } - - /** - * Normalize native function name - * - * @internal - * - * @param string $name - * - * @return string - */ - public static function normalizeNativeFunctionName($name) - { - $name = str_replace("-", "_", $name); - $libName = 'lib' . preg_replace_callback( - '/_(.)/', - function ($m) { - return ucfirst($m[1]); - }, - ucfirst($name) - ); - return $libName; - } - - /** - * Check if a function is a native built-in scss function, for css parsing - * - * @internal - * - * @param string $name - * - * @return bool - */ - public static function isNativeFunction($name) - { - return method_exists(Compiler::class, self::normalizeNativeFunctionName($name)); - } - - /** - * Sorts keyword arguments - * - * @param string $functionName - * @param array|null $prototypes - * @param array $args - * - * @return array|null - */ - protected function sortNativeFunctionArgs($functionName, $prototypes, $args) - { - if (! isset($prototypes)) { - $keyArgs = []; - $posArgs = []; - - if (\is_array($args) && \count($args) && \end($args) === static::$null) { - array_pop($args); - } - - // separate positional and keyword arguments - foreach ($args as $arg) { - list($key, $value) = $arg; - - if (empty($key) or empty($key[1])) { - $posArgs[] = empty($arg[2]) ? $value : $arg; - } else { - $keyArgs[$key[1]] = $value; - } - } - - return [$posArgs, $keyArgs]; - } - - // specific cases ? - if (\in_array($functionName, ['libRgb', 'libRgba', 'libHsl', 'libHsla'])) { - // notation 100 127 255 / 0 is in fact a simple list of 4 values - foreach ($args as $k => $arg) { - if (!isset($arg[1])) { - continue; // This happens when using a trailing comma - } - if ($arg[1][0] === Type::T_LIST && \count($arg[1][2]) === 3) { - $args[$k][1][2] = $this->extractSlashAlphaInColorFunction($arg[1][2]); - } - } - } - - list($positionalArgs, $namedArgs, $names, $separator, $hasSplat) = $this->evaluateArguments($args, false); - - if (! \is_array(reset($prototypes))) { - $prototypes = [$prototypes]; - } - - $parsedPrototypes = array_map([$this, 'parseFunctionPrototype'], $prototypes); - assert(!empty($parsedPrototypes)); - $matchedPrototype = $this->selectFunctionPrototype($parsedPrototypes, \count($positionalArgs), $names); - - $this->verifyPrototype($matchedPrototype, \count($positionalArgs), $names, $hasSplat); - - $vars = $this->applyArgumentsToDeclaration($matchedPrototype, $positionalArgs, $namedArgs, $separator); - - $finalArgs = []; - $keyArgs = []; - - foreach ($matchedPrototype['arguments'] as $argument) { - list($normalizedName, $originalName, $default) = $argument; - - if (isset($vars[$normalizedName])) { - $value = $vars[$normalizedName]; - } else { - $value = $default; - } - - // special null value as default: translate to real null here - if ($value === [Type::T_KEYWORD, 'null']) { - $value = null; - } - - $finalArgs[] = $value; - $keyArgs[$originalName] = $value; - } - - if ($matchedPrototype['rest_argument'] !== null) { - $value = $vars[$matchedPrototype['rest_argument']]; - - $finalArgs[] = $value; - $keyArgs[$matchedPrototype['rest_argument']] = $value; - } - - return [$finalArgs, $keyArgs]; - } - - /** - * Parses a function prototype to the internal representation of arguments. - * - * The input is an array of strings describing each argument, as supported - * in {@see registerFunction}. Argument names don't include the `$`. - * The output contains the list of positional argument, with their normalized - * name (underscores are replaced by dashes), their original name (to be used - * in case of error reporting) and their default value. The output also contains - * the normalized name of the rest argument, or null if the function prototype - * is not variadic. - * - * @param string[] $prototype - * - * @return array - * @phpstan-return array{arguments: list, rest_argument: string|null} - */ - private function parseFunctionPrototype(array $prototype) - { - static $parser = null; - - $arguments = []; - $restArgument = null; - - foreach ($prototype as $p) { - if (null !== $restArgument) { - throw new \InvalidArgumentException('The argument declaration is invalid. The rest argument must be the last one.'); - } - - $default = null; - $p = explode(':', $p, 2); - $name = str_replace('_', '-', $p[0]); - - if (isset($p[1])) { - $defaultSource = trim($p[1]); - - if ($defaultSource === 'null') { - // differentiate this null from the static::$null - $default = [Type::T_KEYWORD, 'null']; - } else { - if (\is_null($parser)) { - $parser = $this->parserFactory(__METHOD__); - } - - $parser->parseValue($defaultSource, $default); - } - } - - if (substr($name, -3) === '...') { - $restArgument = substr($name, 0, -3); - } else { - $arguments[] = [$name, $p[0], $default]; - } - } - - return [ - 'arguments' => $arguments, - 'rest_argument' => $restArgument, - ]; - } - - /** - * Returns the function prototype for the given positional and named arguments. - * - * If no exact match is found, finds the closest approximation. Note that this - * doesn't guarantee that $positional and $names are valid for the returned - * prototype. - * - * @param array[] $prototypes - * @param int $positional - * @param array $names A set of names, as both keys and values - * - * @return array - * - * @phpstan-param non-empty-array, rest_argument: string|null}> $prototypes - * @phpstan-return array{arguments: list, rest_argument: string|null} - */ - private function selectFunctionPrototype(array $prototypes, $positional, array $names) - { - $fuzzyMatch = null; - $minMismatchDistance = null; - - foreach ($prototypes as $prototype) { - // Ideally, find an exact match. - if ($this->checkPrototypeMatches($prototype, $positional, $names)) { - return $prototype; - } - - $mismatchDistance = \count($prototype['arguments']) - $positional; - - if ($minMismatchDistance !== null) { - if (abs($mismatchDistance) > abs($minMismatchDistance)) { - continue; - } - - // If two overloads have the same mismatch distance, favor the overload - // that has more arguments. - if (abs($mismatchDistance) === abs($minMismatchDistance) && $mismatchDistance < 0) { - continue; - } - } - - $minMismatchDistance = $mismatchDistance; - $fuzzyMatch = $prototype; - } - - return $fuzzyMatch; - } - - /** - * Checks whether the argument invocation matches the callable prototype. - * - * The rules are similar to {@see verifyPrototype}. The boolean return value - * avoids the overhead of building and catching exceptions when the reason of - * not matching the prototype does not need to be known. - * - * @param array $prototype - * @param int $positional - * @param array $names - * - * @return bool - * - * @phpstan-param array{arguments: list, rest_argument: string|null} $prototype - */ - private function checkPrototypeMatches(array $prototype, $positional, array $names) - { - $nameUsed = 0; - - foreach ($prototype['arguments'] as $i => $argument) { - list ($name, $originalName, $default) = $argument; - - if ($i < $positional) { - if (isset($names[$name])) { - return false; - } - } elseif (isset($names[$name])) { - $nameUsed++; - } elseif ($default === null) { - return false; - } - } - - if ($prototype['rest_argument'] !== null) { - return true; - } - - if ($positional > \count($prototype['arguments'])) { - return false; - } - - if ($nameUsed < \count($names)) { - return false; - } - - return true; - } - - /** - * Verifies that the argument invocation is valid for the callable prototype. - * - * @param array $prototype - * @param int $positional - * @param array $names - * @param bool $hasSplat - * - * @return void - * - * @throws SassScriptException - * - * @phpstan-param array{arguments: list, rest_argument: string|null} $prototype - */ - private function verifyPrototype(array $prototype, $positional, array $names, $hasSplat) - { - $nameUsed = 0; - - foreach ($prototype['arguments'] as $i => $argument) { - list ($name, $originalName, $default) = $argument; - - if ($i < $positional) { - if (isset($names[$name])) { - throw new SassScriptException(sprintf('Argument $%s was passed both by position and by name.', $originalName)); - } - } elseif (isset($names[$name])) { - $nameUsed++; - } elseif ($default === null) { - throw new SassScriptException(sprintf('Missing argument $%s', $originalName)); - } - } - - if ($prototype['rest_argument'] !== null) { - return; - } - - if ($positional > \count($prototype['arguments'])) { - $message = sprintf( - 'Only %d %sargument%s allowed, but %d %s passed.', - \count($prototype['arguments']), - empty($names) ? '' : 'positional ', - \count($prototype['arguments']) === 1 ? '' : 's', - $positional, - $positional === 1 ? 'was' : 'were' - ); - if (!$hasSplat) { - throw new SassScriptException($message); - } - - $message = $this->addLocationToMessage($message); - $message .= "\nThis will be an error in future versions of Sass."; - $this->logger->warn($message, true); - } - - if ($nameUsed < \count($names)) { - $unknownNames = array_values(array_diff($names, array_column($prototype['arguments'], 0))); - $lastName = array_pop($unknownNames); - $message = sprintf( - 'No argument%s named $%s%s.', - $unknownNames ? 's' : '', - $unknownNames ? implode(', $', $unknownNames) . ' or $' : '', - $lastName - ); - throw new SassScriptException($message); - } - } - - /** - * Evaluates the argument from the invocation. - * - * This returns several things about this invocation: - * - the list of positional arguments - * - the map of named arguments, indexed by normalized names - * - the set of names used in the arguments (that's an array using the normalized names as keys for O(1) access) - * - the separator used by the list using the splat operator, if any - * - a boolean indicator whether any splat argument (list or map) was used, to support the incomplete error reporting. - * - * @param array[] $args - * @param bool $reduce Whether arguments should be reduced to their value - * - * @return array - * - * @throws SassScriptException - * - * @phpstan-return array{0: list, 1: array, 2: array, 3: string|null, 4: bool} - */ - private function evaluateArguments(array $args, $reduce = true) - { - // this represents trailing commas - if (\count($args) && end($args) === static::$null) { - array_pop($args); - } - - $splatSeparator = null; - $keywordArgs = []; - $names = []; - $positionalArgs = []; - $hasKeywordArgument = false; - $hasSplat = false; - - foreach ($args as $arg) { - if (!empty($arg[0])) { - $hasKeywordArgument = true; - - assert(\is_string($arg[0][1])); - $name = str_replace('_', '-', $arg[0][1]); - - if (isset($keywordArgs[$name])) { - throw new SassScriptException(sprintf('Duplicate named argument $%s.', $arg[0][1])); - } - - $keywordArgs[$name] = $this->maybeReduce($reduce, $arg[1]); - $names[$name] = $name; - } elseif (! empty($arg[2])) { - // $arg[2] means a var followed by ... in the arg ($list... ) - $val = $this->reduce($arg[1], true); - $hasSplat = true; - - if ($val[0] === Type::T_LIST) { - foreach ($val[2] as $item) { - if (\is_null($splatSeparator)) { - $splatSeparator = $val[1]; - } - - $positionalArgs[] = $this->maybeReduce($reduce, $item); - } - - if (isset($val[3]) && \is_array($val[3])) { - foreach ($val[3] as $name => $item) { - assert(\is_string($name)); - - $normalizedName = str_replace('_', '-', $name); - - if (isset($keywordArgs[$normalizedName])) { - throw new SassScriptException(sprintf('Duplicate named argument $%s.', $name)); - } - - $keywordArgs[$normalizedName] = $this->maybeReduce($reduce, $item); - $names[$normalizedName] = $normalizedName; - $hasKeywordArgument = true; - } - } - } elseif ($val[0] === Type::T_MAP) { - foreach ($val[1] as $i => $name) { - $name = $this->compileStringContent($this->coerceString($name)); - $item = $val[2][$i]; - - if (! is_numeric($name)) { - $normalizedName = str_replace('_', '-', $name); - - if (isset($keywordArgs[$normalizedName])) { - throw new SassScriptException(sprintf('Duplicate named argument $%s.', $name)); - } - - $keywordArgs[$normalizedName] = $this->maybeReduce($reduce, $item); - $names[$normalizedName] = $normalizedName; - $hasKeywordArgument = true; - } else { - if (\is_null($splatSeparator)) { - $splatSeparator = $val[1]; - } - - $positionalArgs[] = $this->maybeReduce($reduce, $item); - } - } - } elseif ($val[0] !== Type::T_NULL) { // values other than null are treated a single-element lists, while null is the empty list - $positionalArgs[] = $this->maybeReduce($reduce, $val); - } - } elseif ($hasKeywordArgument) { - throw new SassScriptException('Positional arguments must come before keyword arguments.'); - } else { - $positionalArgs[] = $this->maybeReduce($reduce, $arg[1]); - } - } - - return [$positionalArgs, $keywordArgs, $names, $splatSeparator, $hasSplat]; - } - - /** - * @param bool $reduce - * @param array|Number $value - * - * @return array|Number - */ - private function maybeReduce($reduce, $value) - { - if ($reduce) { - return $this->reduce($value, true); - } - - return $value; - } - - /** - * Apply argument values per definition - * - * @param array[] $argDef - * @param array|null $argValues - * @param bool $storeInEnv - * @param bool $reduce only used if $storeInEnv = false - * - * @return array - * - * @phpstan-param list $argDef - * - * @throws \Exception - */ - protected function applyArguments($argDef, $argValues, $storeInEnv = true, $reduce = true) - { - $output = []; - - if (\is_null($argValues)) { - $argValues = []; - } - - if ($storeInEnv) { - $storeEnv = $this->getStoreEnv(); - - $env = new Environment(); - $env->store = $storeEnv->store; - } - - $prototype = ['arguments' => [], 'rest_argument' => null]; - $originalRestArgumentName = null; - - foreach ($argDef as $arg) { - list($name, $default, $isVariable) = $arg; - $normalizedName = str_replace('_', '-', $name); - - if ($isVariable) { - $originalRestArgumentName = $name; - $prototype['rest_argument'] = $normalizedName; - } else { - $prototype['arguments'][] = [$normalizedName, $name, !empty($default) ? $default : null]; - } - } - - list($positionalArgs, $namedArgs, $names, $splatSeparator, $hasSplat) = $this->evaluateArguments($argValues, $reduce); - - $this->verifyPrototype($prototype, \count($positionalArgs), $names, $hasSplat); - - $vars = $this->applyArgumentsToDeclaration($prototype, $positionalArgs, $namedArgs, $splatSeparator); - - foreach ($prototype['arguments'] as $argument) { - list($normalizedName, $name) = $argument; - - if (!isset($vars[$normalizedName])) { - continue; - } - - $val = $vars[$normalizedName]; - - if ($storeInEnv) { - $this->set($name, $this->reduce($val, true), true, $env); - } else { - $output[$name] = ($reduce ? $this->reduce($val, true) : $val); - } - } - - if ($prototype['rest_argument'] !== null) { - assert($originalRestArgumentName !== null); - $name = $originalRestArgumentName; - $val = $vars[$prototype['rest_argument']]; - - if ($storeInEnv) { - $this->set($name, $this->reduce($val, true), true, $env); - } else { - $output[$name] = ($reduce ? $this->reduce($val, true) : $val); - } - } - - if ($storeInEnv) { - $storeEnv->store = $env->store; - } - - foreach ($prototype['arguments'] as $argument) { - list($normalizedName, $name, $default) = $argument; - - if (isset($vars[$normalizedName])) { - continue; - } - assert($default !== null); - - if ($storeInEnv) { - $this->set($name, $this->reduce($default, true), true); - } else { - $output[$name] = ($reduce ? $this->reduce($default, true) : $default); - } - } - - return $output; - } - - /** - * Apply argument values per definition. - * - * This method assumes that the arguments are valid for the provided prototype. - * The validation with {@see verifyPrototype} must have been run before calling - * it. - * Arguments are returned as a map from the normalized argument names to the - * value. Additional arguments are collected in a sass argument list available - * under the name of the rest argument in the result. - * - * Defaults are not applied as they are resolved in a different environment. - * - * @param array $prototype - * @param array $positionalArgs - * @param array $namedArgs - * @param string|null $splatSeparator - * - * @return array - * - * @phpstan-param array{arguments: list, rest_argument: string|null} $prototype - */ - private function applyArgumentsToDeclaration(array $prototype, array $positionalArgs, array $namedArgs, $splatSeparator) - { - $output = []; - $minLength = min(\count($positionalArgs), \count($prototype['arguments'])); - - for ($i = 0; $i < $minLength; $i++) { - list($name) = $prototype['arguments'][$i]; - $val = $positionalArgs[$i]; - - $output[$name] = $val; - } - - $restNamed = $namedArgs; - - for ($i = \count($positionalArgs); $i < \count($prototype['arguments']); $i++) { - $argument = $prototype['arguments'][$i]; - list($name) = $argument; - - if (isset($namedArgs[$name])) { - $val = $namedArgs[$name]; - unset($restNamed[$name]); - } else { - continue; - } - - $output[$name] = $val; - } - - if ($prototype['rest_argument'] !== null) { - $name = $prototype['rest_argument']; - $rest = array_values(array_slice($positionalArgs, \count($prototype['arguments']))); - - $val = [Type::T_LIST, \is_null($splatSeparator) ? ',' : $splatSeparator , $rest, $restNamed]; - - $output[$name] = $val; - } - - return $output; - } - - /** - * Coerce a php value into a scss one - * - * @param mixed $value - * - * @return array|Number - */ - protected function coerceValue($value) - { - if (\is_array($value) || $value instanceof Number) { - return $value; - } - - if (\is_bool($value)) { - return $this->toBool($value); - } - - if (\is_null($value)) { - return static::$null; - } - - if (\is_int($value) || \is_float($value)) { - return new Number($value, ''); - } - - if (is_numeric($value)) { - return new Number((float) $value, ''); - } - - if ($value === '') { - return static::$emptyString; - } - - $value = [Type::T_KEYWORD, $value]; - $color = $this->coerceColor($value); - - if ($color) { - return $color; - } - - return $value; - } - - /** - * Tries to convert an item to a Sass map - * - * @param Number|array $item - * - * @return array|null - */ - private function tryMap($item) - { - if ($item instanceof Number) { - return null; - } - - if ($item[0] === Type::T_MAP) { - return $item; - } - - if ( - $item[0] === Type::T_LIST && - $item[2] === [] - ) { - return static::$emptyMap; - } - - return null; - } - - /** - * Coerce something to map - * - * @param array|Number $item - * - * @return array|Number - */ - protected function coerceMap($item) - { - $map = $this->tryMap($item); - - if ($map !== null) { - return $map; - } - - return $item; - } - - /** - * Coerce something to list - * - * @param array|Number $item - * @param string $delim - * @param bool $removeTrailingNull - * - * @return array - */ - protected function coerceList($item, $delim = ',', $removeTrailingNull = false) - { - if ($item instanceof Number) { - return [Type::T_LIST, '', [$item]]; - } - - if ($item[0] === Type::T_LIST) { - // remove trailing null from the list - if ($removeTrailingNull && end($item[2]) === static::$null) { - array_pop($item[2]); - } - - return $item; - } - - if ($item[0] === Type::T_MAP) { - $keys = $item[1]; - $values = $item[2]; - $list = []; - - for ($i = 0, $s = \count($keys); $i < $s; $i++) { - $key = $keys[$i]; - $value = $values[$i]; - - $list[] = [ - Type::T_LIST, - ' ', - [$key, $value] - ]; - } - - return [Type::T_LIST, $list ? ',' : '', $list]; - } - - return [Type::T_LIST, '', [$item]]; - } - - /** - * Coerce color for expression - * - * @param array|Number $value - * - * @return array|Number - */ - protected function coerceForExpression($value) - { - if ($color = $this->coerceColor($value)) { - return $color; - } - - return $value; - } - - /** - * Coerce value to color - * - * @param array|Number $value - * @param bool $inRGBFunction - * - * @return array|null - */ - protected function coerceColor($value, $inRGBFunction = false) - { - if ($value instanceof Number) { - return null; - } - - switch ($value[0]) { - case Type::T_COLOR: - for ($i = 1; $i <= 3; $i++) { - if (! is_numeric($value[$i])) { - $cv = $this->compileRGBAValue($value[$i]); - - if (! is_numeric($cv)) { - return null; - } - - $value[$i] = $cv; - } - - if (isset($value[4])) { - if (! is_numeric($value[4])) { - $cv = $this->compileRGBAValue($value[4], true); - - if (! is_numeric($cv)) { - return null; - } - - $value[4] = $cv; - } - } - } - - return $value; - - case Type::T_LIST: - if ($inRGBFunction) { - if (\count($value[2]) == 3 || \count($value[2]) == 4) { - $color = $value[2]; - array_unshift($color, Type::T_COLOR); - - return $this->coerceColor($color); - } - } - - return null; - - case Type::T_KEYWORD: - if (! \is_string($value[1])) { - return null; - } - - $name = strtolower($value[1]); - - // hexa color? - if (preg_match('/^#([0-9a-f]+)$/i', $name, $m)) { - $nofValues = \strlen($m[1]); - - if (\in_array($nofValues, [3, 4, 6, 8])) { - $nbChannels = 3; - $color = []; - $num = hexdec($m[1]); - - switch ($nofValues) { - case 4: - $nbChannels = 4; - // then continuing with the case 3: - case 3: - for ($i = 0; $i < $nbChannels; $i++) { - $t = $num & 0xf; - array_unshift($color, $t << 4 | $t); - $num >>= 4; - } - - break; - - case 8: - $nbChannels = 4; - // then continuing with the case 6: - case 6: - for ($i = 0; $i < $nbChannels; $i++) { - array_unshift($color, $num & 0xff); - $num >>= 8; - } - - break; - } - - if ($nbChannels === 4) { - if ($color[3] === 255) { - $color[3] = 1; // fully opaque - } else { - $color[3] = round($color[3] / 255, Number::PRECISION); - } - } - - array_unshift($color, Type::T_COLOR); - - return $color; - } - } - - if ($rgba = Colors::colorNameToRGBa($name)) { - return isset($rgba[3]) - ? [Type::T_COLOR, $rgba[0], $rgba[1], $rgba[2], $rgba[3]] - : [Type::T_COLOR, $rgba[0], $rgba[1], $rgba[2]]; - } - - return null; - } - - return null; - } - - /** - * @param int|Number $value - * @param bool $isAlpha - * - * @return int|mixed - */ - protected function compileRGBAValue($value, $isAlpha = false) - { - if ($isAlpha) { - return $this->compileColorPartValue($value, 0, 1, false); - } - - return $this->compileColorPartValue($value, 0, 255, true); - } - - /** - * @param mixed $value - * @param int|float $min - * @param int|float $max - * @param bool $isInt - * - * @return int|mixed - */ - protected function compileColorPartValue($value, $min, $max, $isInt = true) - { - if (! is_numeric($value)) { - if (\is_array($value)) { - $reduced = $this->reduce($value); - - if ($reduced instanceof Number) { - $value = $reduced; - } - } - - if ($value instanceof Number) { - if ($value->unitless()) { - $num = $value->getDimension(); - } elseif ($value->hasUnit('%')) { - $num = $max * $value->getDimension() / 100; - } else { - throw $this->error('Expected %s to have no units or "%%".', $value); - } - - $value = $num; - } elseif (\is_array($value)) { - $value = $this->compileValue($value); - } - } - - if (is_numeric($value)) { - if ($isInt) { - $value = round($value); - } - - $value = min($max, max($min, $value)); - - return $value; - } - - return $value; - } - - /** - * Coerce value to string - * - * @param array|Number $value - * - * @return array - */ - protected function coerceString($value) - { - if ($value[0] === Type::T_STRING) { - assert(\is_array($value)); - - return $value; - } - - return [Type::T_STRING, '', [$this->compileValue($value)]]; - } - - /** - * Assert value is a string - * - * This method deals with internal implementation details of the value - * representation where unquoted strings can sometimes be stored under - * other types. - * The returned value is always using the T_STRING type. - * - * @api - * - * @param array|Number $value - * @param string|null $varName - * - * @return array - * - * @throws SassScriptException - */ - public function assertString($value, $varName = null) - { - // case of url(...) parsed a a function - if ($value[0] === Type::T_FUNCTION) { - $value = $this->coerceString($value); - } - - if (! \in_array($value[0], [Type::T_STRING, Type::T_KEYWORD])) { - $value = $this->compileValue($value); - throw SassScriptException::forArgument("$value is not a string.", $varName); - } - - return $this->coerceString($value); - } - - /** - * Coerce value to a percentage - * - * @param array|Number $value - * - * @return int|float - * - * @deprecated - */ - protected function coercePercent($value) - { - @trigger_error(sprintf('"%s" is deprecated since 1.7.0.', __METHOD__), E_USER_DEPRECATED); - - if ($value instanceof Number) { - if ($value->hasUnit('%')) { - return $value->getDimension() / 100; - } - - return $value->getDimension(); - } - - return 0; - } - - /** - * Assert value is a map - * - * @api - * - * @param array|Number $value - * @param string|null $varName - * - * @return array - * - * @throws SassScriptException - */ - public function assertMap($value, $varName = null) - { - $map = $this->tryMap($value); - - if ($map === null) { - $value = $this->compileValue($value); - - throw SassScriptException::forArgument("$value is not a map.", $varName); - } - - return $map; - } - - /** - * Assert value is a list - * - * @api - * - * @param array|Number $value - * - * @return array - * - * @throws \Exception - */ - public function assertList($value) - { - if ($value[0] !== Type::T_LIST) { - throw $this->error('expecting list, %s received', $value[0]); - } - assert(\is_array($value)); - - return $value; - } - - /** - * Gets the keywords of an argument list. - * - * Keys in the returned array are normalized names (underscores are replaced with dashes) - * without the leading `$`. - * Calling this helper with anything that an argument list received for a rest argument - * of the function argument declaration is not supported. - * - * @param array|Number $value - * - * @return array - */ - public function getArgumentListKeywords($value) - { - if ($value[0] !== Type::T_LIST || !isset($value[3]) || !\is_array($value[3])) { - throw new \InvalidArgumentException('The argument is not a sass argument list.'); - } - - return $value[3]; - } - - /** - * Assert value is a color - * - * @api - * - * @param array|Number $value - * @param string|null $varName - * - * @return array - * - * @throws SassScriptException - */ - public function assertColor($value, $varName = null) - { - if ($color = $this->coerceColor($value)) { - return $color; - } - - $value = $this->compileValue($value); - - throw SassScriptException::forArgument("$value is not a color.", $varName); - } - - /** - * Assert value is a number - * - * @api - * - * @param array|Number $value - * @param string|null $varName - * - * @return Number - * - * @throws SassScriptException - */ - public function assertNumber($value, $varName = null) - { - if (!$value instanceof Number) { - $value = $this->compileValue($value); - throw SassScriptException::forArgument("$value is not a number.", $varName); - } - - return $value; - } - - /** - * Assert value is a integer - * - * @api - * - * @param array|Number $value - * @param string|null $varName - * - * @return int - * - * @throws SassScriptException - */ - public function assertInteger($value, $varName = null) - { - $value = $this->assertNumber($value, $varName)->getDimension(); - if (round($value - \intval($value), Number::PRECISION) > 0) { - throw SassScriptException::forArgument("$value is not an integer.", $varName); - } - - return intval($value); - } - - /** - * Extract the ... / alpha on the last argument of channel arg - * in color functions - * - * @param array $args - * @return array - */ - private function extractSlashAlphaInColorFunction($args) - { - $last = end($args); - if (\count($args) === 3 && $last[0] === Type::T_EXPRESSION && $last[1] === '/') { - array_pop($args); - $args[] = $last[2]; - $args[] = $last[3]; - } - return $args; - } - - - /** - * Make sure a color's components don't go out of bounds - * - * @param array $c - * - * @return array - */ - protected function fixColor($c) - { - foreach ([1, 2, 3] as $i) { - if ($c[$i] < 0) { - $c[$i] = 0; - } - - if ($c[$i] > 255) { - $c[$i] = 255; - } - - if (!\is_int($c[$i])) { - $c[$i] = round($c[$i]); - } - } - - return $c; - } - - /** - * Convert RGB to HSL - * - * @internal - * - * @param int $red - * @param int $green - * @param int $blue - * - * @return array - */ - public function toHSL($red, $green, $blue) - { - $min = min($red, $green, $blue); - $max = max($red, $green, $blue); - - $l = $min + $max; - $d = $max - $min; - - if ((int) $d === 0) { - $h = $s = 0; - } else { - if ($l < 255) { - $s = $d / $l; - } else { - $s = $d / (510 - $l); - } - - if ($red == $max) { - $h = 60 * ($green - $blue) / $d; - } elseif ($green == $max) { - $h = 60 * ($blue - $red) / $d + 120; - } else { - $h = 60 * ($red - $green) / $d + 240; - } - } - - return [Type::T_HSL, fmod($h + 360, 360), $s * 100, $l / 5.1]; - } - - /** - * Hue to RGB helper - * - * @param float $m1 - * @param float $m2 - * @param float $h - * - * @return float - */ - protected function hueToRGB($m1, $m2, $h) - { - if ($h < 0) { - $h += 1; - } elseif ($h > 1) { - $h -= 1; - } - - if ($h * 6 < 1) { - return $m1 + ($m2 - $m1) * $h * 6; - } - - if ($h * 2 < 1) { - return $m2; - } - - if ($h * 3 < 2) { - return $m1 + ($m2 - $m1) * (2 / 3 - $h) * 6; - } - - return $m1; - } - - /** - * Convert HSL to RGB - * - * @internal - * - * @param int|float $hue H from 0 to 360 - * @param int|float $saturation S from 0 to 100 - * @param int|float $lightness L from 0 to 100 - * - * @return array - */ - public function toRGB($hue, $saturation, $lightness) - { - if ($hue < 0) { - $hue += 360; - } - - $h = $hue / 360; - $s = min(100, max(0, $saturation)) / 100; - $l = min(100, max(0, $lightness)) / 100; - - $m2 = $l <= 0.5 ? $l * ($s + 1) : $l + $s - $l * $s; - $m1 = $l * 2 - $m2; - - $r = $this->hueToRGB($m1, $m2, $h + 1 / 3) * 255; - $g = $this->hueToRGB($m1, $m2, $h) * 255; - $b = $this->hueToRGB($m1, $m2, $h - 1 / 3) * 255; - - $out = [Type::T_COLOR, $r, $g, $b]; - - return $out; - } - - /** - * Convert HWB to RGB - * https://www.w3.org/TR/css-color-4/#hwb-to-rgb - * - * @api - * - * @param int|float $hue H from 0 to 360 - * @param int|float $whiteness W from 0 to 100 - * @param int|float $blackness B from 0 to 100 - * - * @return array - */ - private function HWBtoRGB($hue, $whiteness, $blackness) - { - $w = min(100, max(0, $whiteness)) / 100; - $b = min(100, max(0, $blackness)) / 100; - - $sum = $w + $b; - if ($sum > 1.0) { - $w = $w / $sum; - $b = $b / $sum; - } - $b = min(1.0 - $w, $b); - - $rgb = $this->toRGB($hue, 100, 50); - for ($i = 1; $i < 4; $i++) { - $rgb[$i] *= (1.0 - $w - $b); - $rgb[$i] = round($rgb[$i] + 255 * $w + 0.0001); - } - - return $rgb; - } - - /** - * Convert RGB to HWB - * - * @api - * - * @param int $red - * @param int $green - * @param int $blue - * - * @return array - */ - private function RGBtoHWB($red, $green, $blue) - { - $min = min($red, $green, $blue); - $max = max($red, $green, $blue); - - $d = $max - $min; - - if ((int) $d === 0) { - $h = 0; - } else { - if ($red == $max) { - $h = 60 * ($green - $blue) / $d; - } elseif ($green == $max) { - $h = 60 * ($blue - $red) / $d + 120; - } else { - $h = 60 * ($red - $green) / $d + 240; - } - } - - return [Type::T_HWB, fmod($h, 360), $min / 255 * 100, 100 - $max / 255 * 100]; - } - - - // Built in functions - - protected static $libCall = ['function', 'args...']; - protected function libCall($args) - { - $functionReference = $args[0]; - - if (in_array($functionReference[0], [Type::T_STRING, Type::T_KEYWORD])) { - $name = $this->compileStringContent($this->coerceString($functionReference)); - $warning = "Passing a string to call() is deprecated and will be illegal\n" - . "in Sass 4.0. Use call(function-reference($name)) instead."; - Warn::deprecation($warning); - $functionReference = $this->libGetFunction([$this->assertString($functionReference, 'function')]); - } - - if ($functionReference === static::$null) { - return static::$null; - } - - if (! in_array($functionReference[0], [Type::T_FUNCTION_REFERENCE, Type::T_FUNCTION])) { - throw $this->error('Function reference expected, got ' . $functionReference[0]); - } - - $callArgs = [ - [null, $args[1], true] - ]; - - return $this->reduce([Type::T_FUNCTION_CALL, $functionReference, $callArgs]); - } - - - protected static $libGetFunction = [ - ['name'], - ['name', 'css'] - ]; - protected function libGetFunction($args) - { - $name = $this->compileStringContent($this->assertString(array_shift($args), 'name')); - $isCss = false; - - if (count($args)) { - $isCss = array_shift($args); - $isCss = (($isCss === static::$true) ? true : false); - } - - if ($isCss) { - return [Type::T_FUNCTION, $name, [Type::T_LIST, ',', []]]; - } - - return $this->getFunctionReference($name, true); - } - - protected static $libIf = ['condition', 'if-true', 'if-false:']; - protected function libIf($args) - { - list($cond, $t, $f) = $args; - - if (! $this->isTruthy($this->reduce($cond, true))) { - return $this->reduce($f, true); - } - - return $this->reduce($t, true); - } - - protected static $libIndex = ['list', 'value']; - protected function libIndex($args) - { - list($list, $value) = $args; - - if ( - $list[0] === Type::T_MAP || - $list[0] === Type::T_STRING || - $list[0] === Type::T_KEYWORD || - $list[0] === Type::T_INTERPOLATE - ) { - $list = $this->coerceList($list, ' '); - } - - if ($list[0] !== Type::T_LIST) { - return static::$null; - } - - // Numbers are represented with value objects, for which the PHP equality operator does not - // match the Sass rules (and we cannot overload it). As they are the only type of values - // represented with a value object for now, they require a special case. - if ($value instanceof Number) { - $key = 0; - foreach ($list[2] as $item) { - $key++; - $itemValue = $this->normalizeValue($item); - - if ($itemValue instanceof Number && $value->equals($itemValue)) { - return new Number($key, ''); - } - } - return static::$null; - } - - $values = []; - - foreach ($list[2] as $item) { - $values[] = $this->normalizeValue($item); - } - - $key = array_search($this->normalizeValue($value), $values); - - return false === $key ? static::$null : new Number($key + 1, ''); - } - - protected static $libRgb = [ - ['color'], - ['color', 'alpha'], - ['channels'], - ['red', 'green', 'blue'], - ['red', 'green', 'blue', 'alpha'] ]; - - /** - * @param array $args - * @param array $kwargs - * @param string $funcName - * - * @return array - */ - protected function libRgb($args, $kwargs, $funcName = 'rgb') - { - switch (\count($args)) { - case 1: - if (! $color = $this->coerceColor($args[0], true)) { - $color = [Type::T_STRING, '', [$funcName . '(', $args[0], ')']]; - } - break; - - case 3: - $color = [Type::T_COLOR, $args[0], $args[1], $args[2]]; - - if (! $color = $this->coerceColor($color)) { - $color = [Type::T_STRING, '', [$funcName . '(', $args[0], ', ', $args[1], ', ', $args[2], ')']]; - } - - return $color; - - case 2: - if ($color = $this->coerceColor($args[0], true)) { - $alpha = $this->compileRGBAValue($args[1], true); - - if (is_numeric($alpha)) { - $color[4] = $alpha; - } else { - $color = [Type::T_STRING, '', - [$funcName . '(', $color[1], ', ', $color[2], ', ', $color[3], ', ', $alpha, ')']]; - } - } else { - $color = [Type::T_STRING, '', [$funcName . '(', $args[0], ', ', $args[1], ')']]; - } - break; - - case 4: - default: - $color = [Type::T_COLOR, $args[0], $args[1], $args[2], $args[3]]; - - if (! $color = $this->coerceColor($color)) { - $color = [Type::T_STRING, '', - [$funcName . '(', $args[0], ', ', $args[1], ', ', $args[2], ', ', $args[3], ')']]; - } - break; - } - - return $color; - } - - protected static $libRgba = [ - ['color'], - ['color', 'alpha'], - ['channels'], - ['red', 'green', 'blue'], - ['red', 'green', 'blue', 'alpha'] ]; - protected function libRgba($args, $kwargs) - { - return $this->libRgb($args, $kwargs, 'rgba'); - } - - /** - * Helper function for adjust_color, change_color, and scale_color - * - * @param array $args - * @param string $operation - * @param callable $fn - * - * @return array - * - * @phpstan-param callable(float|int, float|int|null, float|int): (float|int) $fn - */ - protected function alterColor(array $args, $operation, $fn) - { - $color = $this->assertColor($args[0], 'color'); - - if ($args[1][2]) { - throw new SassScriptException('Only one positional argument is allowed. All other arguments must be passed by name.'); - } - - $kwargs = $this->getArgumentListKeywords($args[1]); - - $scale = $operation === 'scale'; - $change = $operation === 'change'; - - /** - * @param string $name - * @param float|int $max - * @param bool $checkPercent - * @param bool $assertPercent - * @return float|int|null - */ - $getParam = function ($name, $max, $checkPercent = false, $assertPercent = false) use (&$kwargs, $scale, $change) { - if (!isset($kwargs[$name])) { - return null; - } - - $number = $this->assertNumber($kwargs[$name], $name); - unset($kwargs[$name]); - - if (!$scale && $checkPercent) { - if (!$number->hasUnit('%')) { - $warning = $this->error("{$name} Passing a number `$number` without unit % is deprecated."); - $this->logger->warn($warning->getMessage(), true); - } - } - - if ($scale || $assertPercent) { - $number->assertUnit('%', $name); - } - - if ($scale) { - $max = 100; - } - - if ($scale || $assertPercent) { - return $number->valueInRange($change ? 0 : -$max, $max, $name); - } - - return $number->valueInRangeWithUnit($change ? 0 : -$max, $max, $name, $checkPercent ? '%' : ''); - }; - - $alpha = $getParam('alpha', 1); - $red = $getParam('red', 255); - $green = $getParam('green', 255); - $blue = $getParam('blue', 255); - - if ($scale || !isset($kwargs['hue'])) { - $hue = null; - } else { - $hueNumber = $this->assertNumber($kwargs['hue'], 'hue'); - unset($kwargs['hue']); - $hue = $hueNumber->getDimension(); - } - $saturation = $getParam('saturation', 100, true); - $lightness = $getParam('lightness', 100, true); - $whiteness = $getParam('whiteness', 100, false, true); - $blackness = $getParam('blackness', 100, false, true); - - if (!empty($kwargs)) { - $unknownNames = array_keys($kwargs); - $lastName = array_pop($unknownNames); - $message = sprintf( - 'No argument%s named $%s%s.', - $unknownNames ? 's' : '', - $unknownNames ? implode(', $', $unknownNames) . ' or $' : '', - $lastName - ); - throw new SassScriptException($message); - } - - $hasRgb = $red !== null || $green !== null || $blue !== null; - $hasSL = $saturation !== null || $lightness !== null; - $hasWB = $whiteness !== null || $blackness !== null; - - if ($hasRgb && ($hasSL || $hasWB || $hue !== null)) { - throw new SassScriptException(sprintf('RGB parameters may not be passed along with %s parameters.', $hasWB ? 'HWB' : 'HSL')); - } - - if ($hasWB && $hasSL) { - throw new SassScriptException('HSL parameters may not be passed along with HWB parameters.'); - } - - if ($hasRgb) { - $color[1] = round($fn($color[1], $red, 255)); - $color[2] = round($fn($color[2], $green, 255)); - $color[3] = round($fn($color[3], $blue, 255)); - } elseif ($hasWB) { - $hwb = $this->RGBtoHWB($color[1], $color[2], $color[3]); - if ($hue !== null) { - $hwb[1] = $change ? $hue : $hwb[1] + $hue; - } - $hwb[2] = $fn($hwb[2], $whiteness, 100); - $hwb[3] = $fn($hwb[3], $blackness, 100); - - $rgb = $this->HWBtoRGB($hwb[1], $hwb[2], $hwb[3]); - - if (isset($color[4])) { - $rgb[4] = $color[4]; - } - - $color = $rgb; - } elseif ($hue !== null || $hasSL) { - $hsl = $this->toHSL($color[1], $color[2], $color[3]); - - if ($hue !== null) { - $hsl[1] = $change ? $hue : $hsl[1] + $hue; - } - $hsl[2] = $fn($hsl[2], $saturation, 100); - $hsl[3] = $fn($hsl[3], $lightness, 100); - - $rgb = $this->toRGB($hsl[1], $hsl[2], $hsl[3]); - - if (isset($color[4])) { - $rgb[4] = $color[4]; - } - - $color = $rgb; - } - - if ($alpha !== null) { - $existingAlpha = isset($color[4]) ? $color[4] : 1; - $color[4] = $fn($existingAlpha, $alpha, 1); - } - - return $color; - } - - protected static $libAdjustColor = ['color', 'kwargs...']; - protected function libAdjustColor($args) - { - return $this->alterColor($args, 'adjust', function ($base, $alter, $max) { - if ($alter === null) { - return $base; - } - - $new = $base + $alter; - - if ($new < 0) { - return 0; - } - - if ($new > $max) { - return $max; - } - - return $new; - }); - } - - protected static $libChangeColor = ['color', 'kwargs...']; - protected function libChangeColor($args) - { - return $this->alterColor($args, 'change', function ($base, $alter, $max) { - if ($alter === null) { - return $base; - } - - return $alter; - }); - } - - protected static $libScaleColor = ['color', 'kwargs...']; - protected function libScaleColor($args) - { - return $this->alterColor($args, 'scale', function ($base, $scale, $max) { - if ($scale === null) { - return $base; - } - - $scale = $scale / 100; - - if ($scale < 0) { - return $base * $scale + $base; - } - - return ($max - $base) * $scale + $base; - }); - } - - protected static $libIeHexStr = ['color']; - protected function libIeHexStr($args) - { - $color = $this->coerceColor($args[0]); - - if (\is_null($color)) { - throw $this->error('Error: argument `$color` of `ie-hex-str($color)` must be a color'); - } - - $color[4] = isset($color[4]) ? round(255 * $color[4]) : 255; - - return [Type::T_STRING, '', [sprintf('#%02X%02X%02X%02X', $color[4], $color[1], $color[2], $color[3])]]; - } - - protected static $libRed = ['color']; - protected function libRed($args) - { - $color = $this->coerceColor($args[0]); - - if (\is_null($color)) { - throw $this->error('Error: argument `$color` of `red($color)` must be a color'); - } - - return new Number((int) $color[1], ''); - } - - protected static $libGreen = ['color']; - protected function libGreen($args) - { - $color = $this->coerceColor($args[0]); - - if (\is_null($color)) { - throw $this->error('Error: argument `$color` of `green($color)` must be a color'); - } - - return new Number((int) $color[2], ''); - } - - protected static $libBlue = ['color']; - protected function libBlue($args) - { - $color = $this->coerceColor($args[0]); - - if (\is_null($color)) { - throw $this->error('Error: argument `$color` of `blue($color)` must be a color'); - } - - return new Number((int) $color[3], ''); - } - - protected static $libAlpha = ['color']; - protected function libAlpha($args) - { - if ($color = $this->coerceColor($args[0])) { - return new Number(isset($color[4]) ? $color[4] : 1, ''); - } - - // this might be the IE function, so return value unchanged - return null; - } - - protected static $libOpacity = ['color']; - protected function libOpacity($args) - { - $value = $args[0]; - - if ($value instanceof Number) { - return null; - } - - return $this->libAlpha($args); - } - - // mix two colors - protected static $libMix = [ - ['color1', 'color2', 'weight:50%'], - ['color-1', 'color-2', 'weight:50%'] - ]; - protected function libMix($args) - { - list($first, $second, $weight) = $args; - - $first = $this->assertColor($first, 'color1'); - $second = $this->assertColor($second, 'color2'); - $weightScale = $this->assertNumber($weight, 'weight')->valueInRange(0, 100, 'weight') / 100; - - $firstAlpha = isset($first[4]) ? $first[4] : 1; - $secondAlpha = isset($second[4]) ? $second[4] : 1; - - $normalizedWeight = $weightScale * 2 - 1; - $alphaDistance = $firstAlpha - $secondAlpha; - - $combinedWeight = $normalizedWeight * $alphaDistance == -1 ? $normalizedWeight : ($normalizedWeight + $alphaDistance) / (1 + $normalizedWeight * $alphaDistance); - $weight1 = ($combinedWeight + 1) / 2.0; - $weight2 = 1.0 - $weight1; - - $new = [Type::T_COLOR, - $weight1 * $first[1] + $weight2 * $second[1], - $weight1 * $first[2] + $weight2 * $second[2], - $weight1 * $first[3] + $weight2 * $second[3], - ]; - - if ($firstAlpha != 1.0 || $secondAlpha != 1.0) { - $new[] = $firstAlpha * $weightScale + $secondAlpha * (1 - $weightScale); - } - - return $this->fixColor($new); - } - - protected static $libHsl = [ - ['channels'], - ['hue', 'saturation'], - ['hue', 'saturation', 'lightness'], - ['hue', 'saturation', 'lightness', 'alpha'] ]; - - /** - * @param array $args - * @param array $kwargs - * @param string $funcName - * - * @return array|null - */ - protected function libHsl($args, $kwargs, $funcName = 'hsl') - { - $args_to_check = $args; - - if (\count($args) == 1) { - if ($args[0][0] !== Type::T_LIST || \count($args[0][2]) < 3 || \count($args[0][2]) > 4) { - return [Type::T_STRING, '', [$funcName . '(', $args[0], ')']]; - } - - $args = $args[0][2]; - $args_to_check = $kwargs['channels'][2]; - } - - if (\count($args) === 2) { - // if var() is used as an argument, return as a css function - foreach ($args as $arg) { - if ($arg[0] === Type::T_FUNCTION && in_array($arg[1], ['var'])) { - return null; - } - } - - throw new SassScriptException('Missing argument $lightness.'); - } - - foreach ($kwargs as $arg) { - if (in_array($arg[0], [Type::T_FUNCTION_CALL, Type::T_FUNCTION]) && in_array($arg[1], ['min', 'max'])) { - return null; - } - } - - foreach ($args_to_check as $k => $arg) { - if (in_array($arg[0], [Type::T_FUNCTION_CALL, Type::T_FUNCTION]) && in_array($arg[1], ['min', 'max'])) { - if (count($kwargs) > 1 || ($k >= 2 && count($args) === 4)) { - return null; - } - - $args[$k] = $this->stringifyFncallArgs($arg); - } - - if ( - $k >= 2 && count($args) === 4 && - in_array($arg[0], [Type::T_FUNCTION_CALL, Type::T_FUNCTION]) && - in_array($arg[1], ['calc','env']) - ) { - return null; - } - } - - $hue = $this->reduce($args[0]); - $saturation = $this->reduce($args[1]); - $lightness = $this->reduce($args[2]); - $alpha = null; - - if (\count($args) === 4) { - $alpha = $this->compileColorPartValue($args[3], 0, 100, false); - - if (!$hue instanceof Number || !$saturation instanceof Number || ! $lightness instanceof Number || ! is_numeric($alpha)) { - return [Type::T_STRING, '', - [$funcName . '(', $args[0], ', ', $args[1], ', ', $args[2], ', ', $args[3], ')']]; - } - } else { - if (!$hue instanceof Number || !$saturation instanceof Number || ! $lightness instanceof Number) { - return [Type::T_STRING, '', [$funcName . '(', $args[0], ', ', $args[1], ', ', $args[2], ')']]; - } - } - - $hueValue = fmod($hue->getDimension(), 360); - - while ($hueValue < 0) { - $hueValue += 360; - } - - $color = $this->toRGB($hueValue, max(0, min($saturation->getDimension(), 100)), max(0, min($lightness->getDimension(), 100))); - - if (! \is_null($alpha)) { - $color[4] = $alpha; - } - - return $color; - } - - protected static $libHsla = [ - ['channels'], - ['hue', 'saturation'], - ['hue', 'saturation', 'lightness'], - ['hue', 'saturation', 'lightness', 'alpha']]; - protected function libHsla($args, $kwargs) - { - return $this->libHsl($args, $kwargs, 'hsla'); - } - - protected static $libHue = ['color']; - protected function libHue($args) - { - $color = $this->assertColor($args[0], 'color'); - $hsl = $this->toHSL($color[1], $color[2], $color[3]); - - return new Number($hsl[1], 'deg'); - } - - protected static $libSaturation = ['color']; - protected function libSaturation($args) - { - $color = $this->assertColor($args[0], 'color'); - $hsl = $this->toHSL($color[1], $color[2], $color[3]); - - return new Number($hsl[2], '%'); - } - - protected static $libLightness = ['color']; - protected function libLightness($args) - { - $color = $this->assertColor($args[0], 'color'); - $hsl = $this->toHSL($color[1], $color[2], $color[3]); - - return new Number($hsl[3], '%'); - } - - /* - * Todo : a integrer dans le futur module color - protected static $libHwb = [ - ['channels'], - ['hue', 'whiteness', 'blackness'], - ['hue', 'whiteness', 'blackness', 'alpha'] ]; - protected function libHwb($args, $kwargs, $funcName = 'hwb') - { - $args_to_check = $args; - - if (\count($args) == 1) { - if ($args[0][0] !== Type::T_LIST) { - throw $this->error("Missing elements \$whiteness and \$blackness"); - } - - if (\trim($args[0][1])) { - throw $this->error("\$channels must be a space-separated list."); - } - - if (! empty($args[0]['enclosing'])) { - throw $this->error("\$channels must be an unbracketed list."); - } - - $args = $args[0][2]; - if (\count($args) > 3) { - throw $this->error("hwb() : Only 3 elements are allowed but ". \count($args) . "were passed"); - } - - $args_to_check = $this->extractSlashAlphaInColorFunction($kwargs['channels'][2]); - if (\count($args_to_check) !== \count($kwargs['channels'][2])) { - $args = $args_to_check; - } - } - - if (\count($args_to_check) < 2) { - throw $this->error("Missing elements \$whiteness and \$blackness"); - } - if (\count($args_to_check) < 3) { - throw $this->error("Missing element \$blackness"); - } - if (\count($args_to_check) > 4) { - throw $this->error("hwb() : Only 4 elements are allowed but ". \count($args) . "were passed"); - } - - foreach ($kwargs as $k => $arg) { - if (in_array($arg[0], [Type::T_FUNCTION_CALL]) && in_array($arg[1], ['min', 'max'])) { - return null; - } - } - - foreach ($args_to_check as $k => $arg) { - if (in_array($arg[0], [Type::T_FUNCTION_CALL]) && in_array($arg[1], ['min', 'max'])) { - if (count($kwargs) > 1 || ($k >= 2 && count($args) === 4)) { - return null; - } - - $args[$k] = $this->stringifyFncallArgs($arg); - } - - if ( - $k >= 2 && count($args) === 4 && - in_array($arg[0], [Type::T_FUNCTION_CALL, Type::T_FUNCTION]) && - in_array($arg[1], ['calc','env']) - ) { - return null; - } - } - - $hue = $this->reduce($args[0]); - $whiteness = $this->reduce($args[1]); - $blackness = $this->reduce($args[2]); - $alpha = null; - - if (\count($args) === 4) { - $alpha = $this->compileColorPartValue($args[3], 0, 1, false); - - if (! \is_numeric($alpha)) { - $val = $this->compileValue($args[3]); - throw $this->error("\$alpha: $val is not a number"); - } - } - - $this->assertNumber($hue, 'hue'); - $this->assertUnit($whiteness, ['%'], 'whiteness'); - $this->assertUnit($blackness, ['%'], 'blackness'); - - $this->assertRange($whiteness, 0, 100, "0% and 100%", "whiteness"); - $this->assertRange($blackness, 0, 100, "0% and 100%", "blackness"); - - $w = $whiteness->getDimension(); - $b = $blackness->getDimension(); - - $hueValue = $hue->getDimension() % 360; - - while ($hueValue < 0) { - $hueValue += 360; - } - - $color = $this->HWBtoRGB($hueValue, $w, $b); - - if (! \is_null($alpha)) { - $color[4] = $alpha; - } - - return $color; - } - - protected static $libWhiteness = ['color']; - protected function libWhiteness($args, $kwargs, $funcName = 'whiteness') { - - $color = $this->assertColor($args[0]); - $hwb = $this->RGBtoHWB($color[1], $color[2], $color[3]); - - return new Number($hwb[2], '%'); - } - - protected static $libBlackness = ['color']; - protected function libBlackness($args, $kwargs, $funcName = 'blackness') { - - $color = $this->assertColor($args[0]); - $hwb = $this->RGBtoHWB($color[1], $color[2], $color[3]); - - return new Number($hwb[3], '%'); - } - */ - - /** - * @param array $color - * @param int $idx - * @param int|float $amount - * - * @return array - */ - protected function adjustHsl($color, $idx, $amount) - { - $hsl = $this->toHSL($color[1], $color[2], $color[3]); - $hsl[$idx] += $amount; - - if ($idx !== 1) { - // Clamp the saturation and lightness - $hsl[$idx] = min(max(0, $hsl[$idx]), 100); - } - - $out = $this->toRGB($hsl[1], $hsl[2], $hsl[3]); - - if (isset($color[4])) { - $out[4] = $color[4]; - } - - return $out; - } - - protected static $libAdjustHue = ['color', 'degrees']; - protected function libAdjustHue($args) - { - $color = $this->assertColor($args[0], 'color'); - $degrees = $this->assertNumber($args[1], 'degrees')->getDimension(); - - return $this->adjustHsl($color, 1, $degrees); - } - - protected static $libLighten = ['color', 'amount']; - protected function libLighten($args) - { - $color = $this->assertColor($args[0], 'color'); - $amount = Util::checkRange('amount', new Range(0, 100), $args[1], '%'); - - return $this->adjustHsl($color, 3, $amount); - } - - protected static $libDarken = ['color', 'amount']; - protected function libDarken($args) - { - $color = $this->assertColor($args[0], 'color'); - $amount = Util::checkRange('amount', new Range(0, 100), $args[1], '%'); - - return $this->adjustHsl($color, 3, -$amount); - } - - protected static $libSaturate = [['color', 'amount'], ['amount']]; - protected function libSaturate($args) - { - $value = $args[0]; - - if (count($args) === 1) { - $this->assertNumber($args[0], 'amount'); - - return null; - } - - $color = $this->assertColor($args[0], 'color'); - $amount = $this->assertNumber($args[1], 'amount'); - - return $this->adjustHsl($color, 2, $amount->valueInRange(0, 100, 'amount')); - } - - protected static $libDesaturate = ['color', 'amount']; - protected function libDesaturate($args) - { - $color = $this->assertColor($args[0], 'color'); - $amount = $this->assertNumber($args[1], 'amount'); - - return $this->adjustHsl($color, 2, -$amount->valueInRange(0, 100, 'amount')); - } - - protected static $libGrayscale = ['color']; - protected function libGrayscale($args) - { - $value = $args[0]; - - if ($value instanceof Number) { - return null; - } - - return $this->adjustHsl($this->assertColor($value, 'color'), 2, -100); - } - - protected static $libComplement = ['color']; - protected function libComplement($args) - { - return $this->adjustHsl($this->assertColor($args[0], 'color'), 1, 180); - } - - protected static $libInvert = ['color', 'weight:100%']; - protected function libInvert($args) - { - $value = $args[0]; - - $weight = $this->assertNumber($args[1], 'weight'); - - if ($value instanceof Number) { - if ($weight->getDimension() != 100 || !$weight->hasUnit('%')) { - throw new SassScriptException('Only one argument may be passed to the plain-CSS invert() function.'); - } - - return null; - } - - $color = $this->assertColor($value, 'color'); - $inverted = $color; - $inverted[1] = 255 - $inverted[1]; - $inverted[2] = 255 - $inverted[2]; - $inverted[3] = 255 - $inverted[3]; - - return $this->libMix([$inverted, $color, $weight]); - } - - // increases opacity by amount - protected static $libOpacify = ['color', 'amount']; - protected function libOpacify($args) - { - $color = $this->assertColor($args[0], 'color'); - $amount = $this->assertNumber($args[1], 'amount'); - - $color[4] = (isset($color[4]) ? $color[4] : 1) + $amount->valueInRangeWithUnit(0, 1, 'amount', ''); - $color[4] = min(1, max(0, $color[4])); - - return $color; - } - - protected static $libFadeIn = ['color', 'amount']; - protected function libFadeIn($args) - { - return $this->libOpacify($args); - } - - // decreases opacity by amount - protected static $libTransparentize = ['color', 'amount']; - protected function libTransparentize($args) - { - $color = $this->assertColor($args[0], 'color'); - $amount = $this->assertNumber($args[1], 'amount'); - - $color[4] = (isset($color[4]) ? $color[4] : 1) - $amount->valueInRangeWithUnit(0, 1, 'amount', ''); - $color[4] = min(1, max(0, $color[4])); - - return $color; - } - - protected static $libFadeOut = ['color', 'amount']; - protected function libFadeOut($args) - { - return $this->libTransparentize($args); - } - - protected static $libUnquote = ['string']; - protected function libUnquote($args) - { - try { - $str = $this->assertString($args[0], 'string'); - } catch (SassScriptException $e) { - $value = $this->compileValue($args[0]); - $fname = $this->getPrettyPath($this->sourceNames[$this->sourceIndex]); - $line = $this->sourceLine; - - $message = "Passing $value, a non-string value, to unquote() -will be an error in future versions of Sass.\n on line $line of $fname"; - - $this->logger->warn($message, true); - - return $args[0]; - } - - $str[1] = ''; - - return $str; - } - - protected static $libQuote = ['string']; - protected function libQuote($args) - { - $value = $this->assertString($args[0], 'string'); - - $value[1] = '"'; - - return $value; - } - - protected static $libPercentage = ['number']; - protected function libPercentage($args) - { - $num = $this->assertNumber($args[0], 'number'); - $num->assertNoUnits('number'); - - return new Number($num->getDimension() * 100, '%'); - } - - protected static $libRound = ['number']; - protected function libRound($args) - { - $num = $this->assertNumber($args[0], 'number'); - - return new Number(round($num->getDimension()), $num->getNumeratorUnits(), $num->getDenominatorUnits()); - } - - protected static $libFloor = ['number']; - protected function libFloor($args) - { - $num = $this->assertNumber($args[0], 'number'); - - return new Number(floor($num->getDimension()), $num->getNumeratorUnits(), $num->getDenominatorUnits()); - } - - protected static $libCeil = ['number']; - protected function libCeil($args) - { - $num = $this->assertNumber($args[0], 'number'); - - return new Number(ceil($num->getDimension()), $num->getNumeratorUnits(), $num->getDenominatorUnits()); - } - - protected static $libAbs = ['number']; - protected function libAbs($args) - { - $num = $this->assertNumber($args[0], 'number'); - - return new Number(abs($num->getDimension()), $num->getNumeratorUnits(), $num->getDenominatorUnits()); - } - - protected static $libMin = ['numbers...']; - protected function libMin($args) - { - /** - * @var Number|null - */ - $min = null; - - foreach ($args[0][2] as $arg) { - $number = $this->assertNumber($arg); - - if (\is_null($min) || $min->greaterThan($number)) { - $min = $number; - } - } - - if (!\is_null($min)) { - return $min; - } - - throw $this->error('At least one argument must be passed.'); - } - - protected static $libMax = ['numbers...']; - protected function libMax($args) - { - /** - * @var Number|null - */ - $max = null; - - foreach ($args[0][2] as $arg) { - $number = $this->assertNumber($arg); - - if (\is_null($max) || $max->lessThan($number)) { - $max = $number; - } - } - - if (!\is_null($max)) { - return $max; - } - - throw $this->error('At least one argument must be passed.'); - } - - protected static $libLength = ['list']; - protected function libLength($args) - { - $list = $this->coerceList($args[0], ',', true); - - return new Number(\count($list[2]), ''); - } - - protected static $libListSeparator = ['list']; - protected function libListSeparator($args) - { - if (! \in_array($args[0][0], [Type::T_LIST, Type::T_MAP])) { - return [Type::T_KEYWORD, 'space']; - } - - $list = $this->coerceList($args[0]); - - if ($list[1] === '' && \count($list[2]) <= 1 && empty($list['enclosing'])) { - return [Type::T_KEYWORD, 'space']; - } - - if ($list[1] === ',') { - return [Type::T_KEYWORD, 'comma']; - } - - if ($list[1] === '/') { - return [Type::T_KEYWORD, 'slash']; - } - - return [Type::T_KEYWORD, 'space']; - } - - protected static $libNth = ['list', 'n']; - protected function libNth($args) - { - $list = $this->coerceList($args[0], ',', false); - $n = $this->assertInteger($args[1]); - - if ($n > 0) { - $n--; - } elseif ($n < 0) { - $n += \count($list[2]); - } - - return isset($list[2][$n]) ? $list[2][$n] : static::$defaultValue; - } - - protected static $libSetNth = ['list', 'n', 'value']; - protected function libSetNth($args) - { - $list = $this->coerceList($args[0]); - $n = $this->assertInteger($args[1]); - - if ($n > 0) { - $n--; - } elseif ($n < 0) { - $n += \count($list[2]); - } - - if (! isset($list[2][$n])) { - throw $this->error('Invalid argument for "n"'); - } - - $list[2][$n] = $args[2]; - - return $list; - } - - protected static $libMapGet = ['map', 'key', 'keys...']; - protected function libMapGet($args) - { - $map = $this->assertMap($args[0], 'map'); - if (!isset($args[2])) { - // BC layer for usages of the function from PHP code rather than from the Sass function - $args[2] = self::$emptyArgumentList; - } - $keys = array_merge([$args[1]], $args[2][2]); - $value = static::$null; - - foreach ($keys as $key) { - if (!\is_array($map) || $map[0] !== Type::T_MAP) { - return static::$null; - } - - $map = $this->mapGet($map, $key); - - if ($map === null) { - return static::$null; - } - - $value = $map; - } - - return $value; - } - - /** - * Gets the value corresponding to that key in the map - * - * @param array $map - * @param Number|array $key - * - * @return Number|array|null - */ - private function mapGet(array $map, $key) - { - $index = $this->mapGetEntryIndex($map, $key); - - if ($index !== null) { - return $map[2][$index]; - } - - return null; - } - - /** - * Gets the index corresponding to that key in the map entries - * - * @param array $map - * @param Number|array $key - * - * @return int|null - */ - private function mapGetEntryIndex(array $map, $key) - { - $key = $this->compileStringContent($this->coerceString($key)); - - for ($i = \count($map[1]) - 1; $i >= 0; $i--) { - if ($key === $this->compileStringContent($this->coerceString($map[1][$i]))) { - return $i; - } - } - - return null; - } - - protected static $libMapKeys = ['map']; - protected function libMapKeys($args) - { - $map = $this->assertMap($args[0], 'map'); - $keys = $map[1]; - - return [Type::T_LIST, ',', $keys]; - } - - protected static $libMapValues = ['map']; - protected function libMapValues($args) - { - $map = $this->assertMap($args[0], 'map'); - $values = $map[2]; - - return [Type::T_LIST, ',', $values]; - } - - protected static $libMapRemove = [ - ['map'], - ['map', 'key', 'keys...'], - ]; - protected function libMapRemove($args) - { - $map = $this->assertMap($args[0], 'map'); - - if (\count($args) === 1) { - return $map; - } - - $keys = []; - $keys[] = $this->compileStringContent($this->coerceString($args[1])); - - foreach ($args[2][2] as $key) { - $keys[] = $this->compileStringContent($this->coerceString($key)); - } - - for ($i = \count($map[1]) - 1; $i >= 0; $i--) { - if (in_array($this->compileStringContent($this->coerceString($map[1][$i])), $keys)) { - array_splice($map[1], $i, 1); - array_splice($map[2], $i, 1); - } - } - - return $map; - } - - protected static $libMapHasKey = ['map', 'key', 'keys...']; - protected function libMapHasKey($args) - { - $map = $this->assertMap($args[0], 'map'); - if (!isset($args[2])) { - // BC layer for usages of the function from PHP code rather than from the Sass function - $args[2] = self::$emptyArgumentList; - } - $keys = array_merge([$args[1]], $args[2][2]); - $lastKey = array_pop($keys); - - foreach ($keys as $key) { - $value = $this->mapGet($map, $key); - - if ($value === null || $value instanceof Number || $value[0] !== Type::T_MAP) { - return self::$false; - } - - $map = $value; - } - - return $this->toBool($this->mapHasKey($map, $lastKey)); - } - - /** - * @param array|Number $keyValue - * - * @return bool - */ - private function mapHasKey(array $map, $keyValue) - { - $key = $this->compileStringContent($this->coerceString($keyValue)); - - for ($i = \count($map[1]) - 1; $i >= 0; $i--) { - if ($key === $this->compileStringContent($this->coerceString($map[1][$i]))) { - return true; - } - } - - return false; - } - - protected static $libMapMerge = [ - ['map1', 'map2'], - ['map-1', 'map-2'], - ['map1', 'args...'] - ]; - protected function libMapMerge($args) - { - $map1 = $this->assertMap($args[0], 'map1'); - $map2 = $args[1]; - $keys = []; - if ($map2[0] === Type::T_LIST && isset($map2[3]) && \is_array($map2[3])) { - // This is an argument list for the variadic signature - if (\count($map2[2]) === 0) { - throw new SassScriptException('Expected $args to contain a key.'); - } - if (\count($map2[2]) === 1) { - throw new SassScriptException('Expected $args to contain a value.'); - } - $keys = $map2[2]; - $map2 = array_pop($keys); - } - $map2 = $this->assertMap($map2, 'map2'); - - return $this->modifyMap($map1, $keys, function ($oldValue) use ($map2) { - $nestedMap = $this->tryMap($oldValue); - - if ($nestedMap === null) { - return $map2; - } - - return $this->mergeMaps($nestedMap, $map2); - }); - } - - /** - * @param array $map - * @param array $keys - * @param callable $modify - * @param bool $addNesting - * - * @return Number|array - * - * @phpstan-param array $keys - * @phpstan-param callable(Number|array): (Number|array) $modify - */ - private function modifyMap(array $map, array $keys, callable $modify, $addNesting = true) - { - if ($keys === []) { - return $modify($map); - } - - return $this->modifyNestedMap($map, $keys, $modify, $addNesting); - } - - /** - * @param array $map - * @param array $keys - * @param callable $modify - * @param bool $addNesting - * - * @return array - * - * @phpstan-param non-empty-array $keys - * @phpstan-param callable(Number|array): (Number|array) $modify - */ - private function modifyNestedMap(array $map, array $keys, callable $modify, $addNesting) - { - $key = array_shift($keys); - - $nestedValueIndex = $this->mapGetEntryIndex($map, $key); - - if ($keys === []) { - if ($nestedValueIndex !== null) { - $map[2][$nestedValueIndex] = $modify($map[2][$nestedValueIndex]); - } else { - $map[1][] = $key; - $map[2][] = $modify(self::$null); - } - - return $map; - } - - $nestedMap = $nestedValueIndex !== null ? $this->tryMap($map[2][$nestedValueIndex]) : null; - - if ($nestedMap === null && !$addNesting) { - return $map; - } - - if ($nestedMap === null) { - $nestedMap = self::$emptyMap; - } - - $newNestedMap = $this->modifyNestedMap($nestedMap, $keys, $modify, $addNesting); - - if ($nestedValueIndex !== null) { - $map[2][$nestedValueIndex] = $newNestedMap; - } else { - $map[1][] = $key; - $map[2][] = $newNestedMap; - } - - return $map; - } - - /** - * Merges 2 Sass maps together - * - * @param array $map1 - * @param array $map2 - * - * @return array - */ - private function mergeMaps(array $map1, array $map2) - { - foreach ($map2[1] as $i2 => $key2) { - $map1EntryIndex = $this->mapGetEntryIndex($map1, $key2); - - if ($map1EntryIndex !== null) { - $map1[2][$map1EntryIndex] = $map2[2][$i2]; - continue; - } - - $map1[1][] = $key2; - $map1[2][] = $map2[2][$i2]; - } - - return $map1; - } - - protected static $libKeywords = ['args']; - protected function libKeywords($args) - { - $value = $args[0]; - - if ($value[0] !== Type::T_LIST || !isset($value[3]) || !\is_array($value[3])) { - $compiledValue = $this->compileValue($value); - - throw SassScriptException::forArgument($compiledValue . ' is not an argument list.', 'args'); - } - - $keys = []; - $values = []; - - foreach ($this->getArgumentListKeywords($value) as $name => $arg) { - $keys[] = [Type::T_KEYWORD, $name]; - $values[] = $arg; - } - - return [Type::T_MAP, $keys, $values]; - } - - protected static $libIsBracketed = ['list']; - protected function libIsBracketed($args) - { - $list = $args[0]; - $this->coerceList($list, ' '); - - if (! empty($list['enclosing']) && $list['enclosing'] === 'bracket') { - return self::$true; - } - - return self::$false; - } - - /** - * @param array $list1 - * @param array|Number|null $sep - * - * @return string - * @throws CompilerException - * - * @deprecated - */ - protected function listSeparatorForJoin($list1, $sep) - { - @trigger_error(sprintf('The "%s" method is deprecated.', __METHOD__), E_USER_DEPRECATED); - - if (! isset($sep)) { - return $list1[1]; - } - - switch ($this->compileValue($sep)) { - case 'comma': - return ','; - - case 'space': - return ' '; - - default: - return $list1[1]; - } - } - - protected static $libJoin = ['list1', 'list2', 'separator:auto', 'bracketed:auto']; - protected function libJoin($args) - { - list($list1, $list2, $sep, $bracketed) = $args; - - $list1 = $this->coerceList($list1, ' ', true); - $list2 = $this->coerceList($list2, ' ', true); - - switch ($this->compileStringContent($this->assertString($sep, 'separator'))) { - case 'comma': - $separator = ','; - break; - - case 'space': - $separator = ' '; - break; - - case 'slash': - $separator = '/'; - break; - - case 'auto': - if ($list1[1] !== '' || count($list1[2]) > 1 || !empty($list1['enclosing']) && $list1['enclosing'] !== 'parent') { - $separator = $list1[1] ?: ' '; - } elseif ($list2[1] !== '' || count($list2[2]) > 1 || !empty($list2['enclosing']) && $list2['enclosing'] !== 'parent') { - $separator = $list2[1] ?: ' '; - } else { - $separator = ' '; - } - break; - - default: - throw SassScriptException::forArgument('Must be "space", "comma", "slash", or "auto".', 'separator'); - } - - if ($bracketed === static::$true) { - $bracketed = true; - } elseif ($bracketed === static::$false) { - $bracketed = false; - } elseif ($bracketed === [Type::T_KEYWORD, 'auto']) { - $bracketed = 'auto'; - } elseif ($bracketed === static::$null) { - $bracketed = false; - } else { - $bracketed = $this->compileValue($bracketed); - $bracketed = ! ! $bracketed; - - if ($bracketed === true) { - $bracketed = true; - } - } - - if ($bracketed === 'auto') { - $bracketed = false; - - if (! empty($list1['enclosing']) && $list1['enclosing'] === 'bracket') { - $bracketed = true; - } - } - - $res = [Type::T_LIST, $separator, array_merge($list1[2], $list2[2])]; - - if ($bracketed) { - $res['enclosing'] = 'bracket'; - } - - return $res; - } - - protected static $libAppend = ['list', 'val', 'separator:auto']; - protected function libAppend($args) - { - list($list1, $value, $sep) = $args; - - $list1 = $this->coerceList($list1, ' ', true); - - switch ($this->compileStringContent($this->assertString($sep, 'separator'))) { - case 'comma': - $separator = ','; - break; - - case 'space': - $separator = ' '; - break; - - case 'slash': - $separator = '/'; - break; - - case 'auto': - $separator = $list1[1] === '' && \count($list1[2]) <= 1 && (empty($list1['enclosing']) || $list1['enclosing'] === 'parent') ? ' ' : $list1[1]; - break; - - default: - throw SassScriptException::forArgument('Must be "space", "comma", "slash", or "auto".', 'separator'); - } - - $res = [Type::T_LIST, $separator, array_merge($list1[2], [$value])]; - - if (isset($list1['enclosing'])) { - $res['enclosing'] = $list1['enclosing']; - } - - return $res; - } - - protected static $libZip = ['lists...']; - protected function libZip($args) - { - $argLists = []; - foreach ($args[0][2] as $arg) { - $argLists[] = $this->coerceList($arg); - } - - $lists = []; - $firstList = array_shift($argLists); - - $result = [Type::T_LIST, ',', $lists]; - if (! \is_null($firstList)) { - foreach ($firstList[2] as $key => $item) { - $list = [Type::T_LIST, ' ', [$item]]; - - foreach ($argLists as $arg) { - if (isset($arg[2][$key])) { - $list[2][] = $arg[2][$key]; - } else { - break 2; - } - } - - $lists[] = $list; - } - - $result[2] = $lists; - } else { - $result['enclosing'] = 'parent'; - } - - return $result; - } - - protected static $libTypeOf = ['value']; - protected function libTypeOf($args) - { - $value = $args[0]; - - return [Type::T_KEYWORD, $this->getTypeOf($value)]; - } - - /** - * @param array|Number $value - * - * @return string - */ - private function getTypeOf($value) - { - switch ($value[0]) { - case Type::T_KEYWORD: - if ($value === static::$true || $value === static::$false) { - return 'bool'; - } - - if ($this->coerceColor($value)) { - return 'color'; - } - - // fall-thru - case Type::T_FUNCTION: - return 'string'; - - case Type::T_FUNCTION_REFERENCE: - return 'function'; - - case Type::T_LIST: - if (isset($value[3]) && \is_array($value[3])) { - return 'arglist'; - } - - // fall-thru - default: - return $value[0]; - } - } - - protected static $libUnit = ['number']; - protected function libUnit($args) - { - $num = $this->assertNumber($args[0], 'number'); - - return [Type::T_STRING, '"', [$num->unitStr()]]; - } - - protected static $libUnitless = ['number']; - protected function libUnitless($args) - { - $value = $this->assertNumber($args[0], 'number'); - - return $this->toBool($value->unitless()); - } - - protected static $libComparable = [ - ['number1', 'number2'], - ['number-1', 'number-2'] - ]; - protected function libComparable($args) - { - list($number1, $number2) = $args; - - if ( - ! $number1 instanceof Number || - ! $number2 instanceof Number - ) { - throw $this->error('Invalid argument(s) for "comparable"'); - } - - return $this->toBool($number1->isComparableTo($number2)); - } - - protected static $libStrIndex = ['string', 'substring']; - protected function libStrIndex($args) - { - $string = $this->assertString($args[0], 'string'); - $stringContent = $this->compileStringContent($string); - - $substring = $this->assertString($args[1], 'substring'); - $substringContent = $this->compileStringContent($substring); - - if (! \strlen($substringContent)) { - $result = 0; - } else { - $result = Util::mbStrpos($stringContent, $substringContent); - } - - return $result === false ? static::$null : new Number($result + 1, ''); - } - - protected static $libStrInsert = ['string', 'insert', 'index']; - protected function libStrInsert($args) - { - $string = $this->assertString($args[0], 'string'); - $stringContent = $this->compileStringContent($string); - - $insert = $this->assertString($args[1], 'insert'); - $insertContent = $this->compileStringContent($insert); - - $index = $this->assertInteger($args[2], 'index'); - if ($index > 0) { - $index = $index - 1; - } - if ($index < 0) { - $index = max(Util::mbStrlen($stringContent) + 1 + $index, 0); - } - - $string[2] = [ - Util::mbSubstr($stringContent, 0, $index), - $insertContent, - Util::mbSubstr($stringContent, $index) - ]; - - return $string; - } - - protected static $libStrLength = ['string']; - protected function libStrLength($args) - { - $string = $this->assertString($args[0], 'string'); - $stringContent = $this->compileStringContent($string); - - return new Number(Util::mbStrlen($stringContent), ''); - } - - protected static $libStrSlice = ['string', 'start-at', 'end-at:-1']; - protected function libStrSlice($args) - { - $string = $this->assertString($args[0], 'string'); - $stringContent = $this->compileStringContent($string); - - $start = $this->assertNumber($args[1], 'start-at'); - $start->assertNoUnits('start-at'); - $startInt = $this->assertInteger($start, 'start-at'); - $end = $this->assertNumber($args[2], 'end-at'); - $end->assertNoUnits('end-at'); - $endInt = $this->assertInteger($end, 'end-at'); - - if ($endInt === 0) { - return [Type::T_STRING, $string[1], []]; - } - - if ($startInt > 0) { - $startInt--; - } - - if ($endInt < 0) { - $endInt = Util::mbStrlen($stringContent) + $endInt; - } else { - $endInt--; - } - - if ($endInt < $startInt) { - return [Type::T_STRING, $string[1], []]; - } - - $length = $endInt - $startInt + 1; // The end of the slice is inclusive - - $string[2] = [Util::mbSubstr($stringContent, $startInt, $length)]; - - return $string; - } - - protected static $libToLowerCase = ['string']; - protected function libToLowerCase($args) - { - $string = $this->assertString($args[0], 'string'); - $stringContent = $this->compileStringContent($string); - - $string[2] = [$this->stringTransformAsciiOnly($stringContent, 'strtolower')]; - - return $string; - } - - protected static $libToUpperCase = ['string']; - protected function libToUpperCase($args) - { - $string = $this->assertString($args[0], 'string'); - $stringContent = $this->compileStringContent($string); - - $string[2] = [$this->stringTransformAsciiOnly($stringContent, 'strtoupper')]; - - return $string; - } - - /** - * Apply a filter on a string content, only on ascii chars - * let extended chars untouched - * - * @param string $stringContent - * @param callable $filter - * @return string - */ - protected function stringTransformAsciiOnly($stringContent, $filter) - { - $mblength = Util::mbStrlen($stringContent); - if ($mblength === strlen($stringContent)) { - return $filter($stringContent); - } - $filteredString = ""; - for ($i = 0; $i < $mblength; $i++) { - $char = Util::mbSubstr($stringContent, $i, 1); - if (strlen($char) > 1) { - $filteredString .= $char; - } else { - $filteredString .= $filter($char); - } - } - - return $filteredString; - } - - protected static $libFeatureExists = ['feature']; - protected function libFeatureExists($args) - { - $string = $this->assertString($args[0], 'feature'); - $name = $this->compileStringContent($string); - - return $this->toBool( - \array_key_exists($name, $this->registeredFeatures) ? $this->registeredFeatures[$name] : false - ); - } - - protected static $libFunctionExists = ['name']; - protected function libFunctionExists($args) - { - $string = $this->assertString($args[0], 'name'); - $name = $this->compileStringContent($string); - - // user defined functions - if ($this->has(static::$namespaces['function'] . $name)) { - return self::$true; - } - - $name = $this->normalizeName($name); - - if (isset($this->userFunctions[$name])) { - return self::$true; - } - - // built-in functions - $f = $this->getBuiltinFunction($name); - - return $this->toBool(\is_callable($f)); - } - - protected static $libGlobalVariableExists = ['name']; - protected function libGlobalVariableExists($args) - { - $string = $this->assertString($args[0], 'name'); - $name = $this->compileStringContent($string); - - return $this->toBool($this->has($name, $this->rootEnv)); - } - - protected static $libMixinExists = ['name']; - protected function libMixinExists($args) - { - $string = $this->assertString($args[0], 'name'); - $name = $this->compileStringContent($string); - - return $this->toBool($this->has(static::$namespaces['mixin'] . $name)); - } - - protected static $libVariableExists = ['name']; - protected function libVariableExists($args) - { - $string = $this->assertString($args[0], 'name'); - $name = $this->compileStringContent($string); - - return $this->toBool($this->has($name)); - } - - protected static $libCounter = ['args...']; - /** - * Workaround IE7's content counter bug. - * - * @param array $args - * - * @return array - */ - protected function libCounter($args) - { - $list = array_map([$this, 'compileValue'], $args[0][2]); - - return [Type::T_STRING, '', ['counter(' . implode(',', $list) . ')']]; - } - - protected static $libRandom = ['limit:null']; - protected function libRandom($args) - { - if (isset($args[0]) && $args[0] !== static::$null) { - $limit = $this->assertNumber($args[0], 'limit'); - - if ($limit->hasUnits()) { - $unitString = $limit->unitStr(); - $message = <<addLocationToMessage($message)); - } - - $n = $this->assertInteger($limit, 'limit'); - - if ($n < 1) { - throw new SassScriptException("\$limit: Must be greater than 0, was $n."); - } - - return new Number(mt_rand(1, $n), ''); - } - - $max = mt_getrandmax(); - return new Number(mt_rand(0, $max - 1) / $max, ''); - } - - protected static $libUniqueId = []; - protected function libUniqueId() - { - static $id; - - if (! isset($id)) { - $id = PHP_INT_SIZE === 4 - ? mt_rand(0, pow(36, 5)) . str_pad(mt_rand(0, pow(36, 5)) % 10000000, 7, '0', STR_PAD_LEFT) - : mt_rand(0, pow(36, 8)); - } - - $id += mt_rand(0, 10) + 1; - - return [Type::T_STRING, '', ['u' . str_pad(base_convert($id, 10, 36), 8, '0', STR_PAD_LEFT)]]; - } - - /** - * @param array|Number $value - * @param bool $force_enclosing_display - * - * @return array - */ - protected function inspectFormatValue($value, $force_enclosing_display = false) - { - if ($value === static::$null) { - $value = [Type::T_KEYWORD, 'null']; - } - - $stringValue = [$value]; - - if ($value instanceof Number) { - return [Type::T_STRING, '', $stringValue]; - } - - if ($value[0] === Type::T_LIST) { - if (end($value[2]) === static::$null) { - array_pop($value[2]); - $value[2][] = [Type::T_STRING, '', ['']]; - $force_enclosing_display = true; - } - - if ( - ! empty($value['enclosing']) && - ($force_enclosing_display || - ($value['enclosing'] === 'bracket') || - ! \count($value[2])) - ) { - $value['enclosing'] = 'forced_' . $value['enclosing']; - $force_enclosing_display = true; - } elseif (! \count($value[2])) { - $value['enclosing'] = 'forced_parent'; - } - - foreach ($value[2] as $k => $listelement) { - $value[2][$k] = $this->inspectFormatValue($listelement, $force_enclosing_display); - } - - $stringValue = [$value]; - } - - return [Type::T_STRING, '', $stringValue]; - } - - protected static $libInspect = ['value']; - protected function libInspect($args) - { - $value = $args[0]; - - return $this->inspectFormatValue($value); - } - - /** - * Preprocess selector args - * - * @param array $arg - * @param string|null $varname - * @param bool $allowParent - * - * @return array - */ - protected function getSelectorArg($arg, $varname = null, $allowParent = false) - { - static $parser = null; - - if (\is_null($parser)) { - $parser = $this->parserFactory(__METHOD__); - } - - if (! $this->checkSelectorArgType($arg)) { - $var_value = $this->compileValue($arg); - throw SassScriptException::forArgument("$var_value is not a valid selector: it must be a string, a list of strings, or a list of lists of strings", $varname); - } - - - if ($arg[0] === Type::T_STRING) { - $arg[1] = ''; - } - $arg = $this->compileValue($arg); - - $parsedSelector = []; - - if ($parser->parseSelector($arg, $parsedSelector, true)) { - $selector = $this->evalSelectors($parsedSelector); - $gluedSelector = $this->glueFunctionSelectors($selector); - - if (! $allowParent) { - foreach ($gluedSelector as $selector) { - foreach ($selector as $s) { - if (in_array(static::$selfSelector, $s)) { - throw SassScriptException::forArgument("Parent selectors aren't allowed here.", $varname); - } - } - } - } - - return $gluedSelector; - } - - throw SassScriptException::forArgument("expected more input, invalid selector.", $varname); - } - - /** - * Check variable type for getSelectorArg() function - * @param array $arg - * @param int $maxDepth - * @return bool - */ - protected function checkSelectorArgType($arg, $maxDepth = 2) - { - if ($arg[0] === Type::T_LIST && $maxDepth > 0) { - foreach ($arg[2] as $elt) { - if (! $this->checkSelectorArgType($elt, $maxDepth - 1)) { - return false; - } - } - return true; - } - if (!in_array($arg[0], [Type::T_STRING, Type::T_KEYWORD])) { - return false; - } - return true; - } - - /** - * Postprocess selector to output in right format - * - * @param array $selectors - * - * @return array - */ - protected function formatOutputSelector($selectors) - { - $selectors = $this->collapseSelectorsAsList($selectors); - - return $selectors; - } - - protected static $libIsSuperselector = ['super', 'sub']; - protected function libIsSuperselector($args) - { - list($super, $sub) = $args; - - $super = $this->getSelectorArg($super, 'super'); - $sub = $this->getSelectorArg($sub, 'sub'); - - return $this->toBool($this->isSuperSelector($super, $sub)); - } - - /** - * Test a $super selector again $sub - * - * @param array $super - * @param array $sub - * - * @return bool - */ - protected function isSuperSelector($super, $sub) - { - // one and only one selector for each arg - if (! $super) { - throw $this->error('Invalid super selector for isSuperSelector()'); - } - - if (! $sub) { - throw $this->error('Invalid sub selector for isSuperSelector()'); - } - - if (count($sub) > 1) { - foreach ($sub as $s) { - if (! $this->isSuperSelector($super, [$s])) { - return false; - } - } - return true; - } - - if (count($super) > 1) { - foreach ($super as $s) { - if ($this->isSuperSelector([$s], $sub)) { - return true; - } - } - return false; - } - - $super = reset($super); - $sub = reset($sub); - - $i = 0; - $nextMustMatch = false; - - foreach ($super as $node) { - $compound = ''; - - array_walk_recursive( - $node, - function ($value, $key) use (&$compound) { - $compound .= $value; - } - ); - - if ($this->isImmediateRelationshipCombinator($compound)) { - if ($node !== $sub[$i]) { - return false; - } - - $nextMustMatch = true; - $i++; - } else { - while ($i < \count($sub) && ! $this->isSuperPart($node, $sub[$i])) { - if ($nextMustMatch) { - return false; - } - - $i++; - } - - if ($i >= \count($sub)) { - return false; - } - - $nextMustMatch = false; - $i++; - } - } - - return true; - } - - /** - * Test a part of super selector again a part of sub selector - * - * @param array $superParts - * @param array $subParts - * - * @return bool - */ - protected function isSuperPart($superParts, $subParts) - { - $i = 0; - - foreach ($superParts as $superPart) { - while ($i < \count($subParts) && $subParts[$i] !== $superPart) { - $i++; - } - - if ($i >= \count($subParts)) { - return false; - } - - $i++; - } - - return true; - } - - protected static $libSelectorAppend = ['selector...']; - protected function libSelectorAppend($args) - { - // get the selector... list - $args = reset($args); - $args = $args[2]; - - if (\count($args) < 1) { - throw $this->error('selector-append() needs at least 1 argument'); - } - - $selectors = []; - foreach ($args as $arg) { - $selectors[] = $this->getSelectorArg($arg, 'selector'); - } - - return $this->formatOutputSelector($this->selectorAppend($selectors)); - } - - /** - * Append parts of the last selector in the list to the previous, recursively - * - * @param array $selectors - * - * @return array - * - * @throws \ScssPhp\ScssPhp\Exception\CompilerException - */ - protected function selectorAppend($selectors) - { - $lastSelectors = array_pop($selectors); - - if (! $lastSelectors) { - throw $this->error('Invalid selector list in selector-append()'); - } - - while (\count($selectors)) { - $previousSelectors = array_pop($selectors); - - if (! $previousSelectors) { - throw $this->error('Invalid selector list in selector-append()'); - } - - // do the trick, happening $lastSelector to $previousSelector - $appended = []; - - foreach ($previousSelectors as $previousSelector) { - foreach ($lastSelectors as $lastSelector) { - $previous = $previousSelector; - foreach ($previousSelector as $j => $previousSelectorParts) { - foreach ($lastSelector as $lastSelectorParts) { - foreach ($lastSelectorParts as $lastSelectorPart) { - $previous[$j][] = $lastSelectorPart; - } - } - } - - $appended[] = $previous; - } - } - - $lastSelectors = $appended; - } - - return $lastSelectors; - } - - protected static $libSelectorExtend = [ - ['selector', 'extendee', 'extender'], - ['selectors', 'extendee', 'extender'] - ]; - protected function libSelectorExtend($args) - { - list($selectors, $extendee, $extender) = $args; - - $selectors = $this->getSelectorArg($selectors, 'selector'); - $extendee = $this->getSelectorArg($extendee, 'extendee'); - $extender = $this->getSelectorArg($extender, 'extender'); - - if (! $selectors || ! $extendee || ! $extender) { - throw $this->error('selector-extend() invalid arguments'); - } - - $extended = $this->extendOrReplaceSelectors($selectors, $extendee, $extender); - - return $this->formatOutputSelector($extended); - } - - protected static $libSelectorReplace = [ - ['selector', 'original', 'replacement'], - ['selectors', 'original', 'replacement'] - ]; - protected function libSelectorReplace($args) - { - list($selectors, $original, $replacement) = $args; - - $selectors = $this->getSelectorArg($selectors, 'selector'); - $original = $this->getSelectorArg($original, 'original'); - $replacement = $this->getSelectorArg($replacement, 'replacement'); - - if (! $selectors || ! $original || ! $replacement) { - throw $this->error('selector-replace() invalid arguments'); - } - - $replaced = $this->extendOrReplaceSelectors($selectors, $original, $replacement, true); - - return $this->formatOutputSelector($replaced); - } - - /** - * Extend/replace in selectors - * used by selector-extend and selector-replace that use the same logic - * - * @param array $selectors - * @param array $extendee - * @param array $extender - * @param bool $replace - * - * @return array - */ - protected function extendOrReplaceSelectors($selectors, $extendee, $extender, $replace = false) - { - $saveExtends = $this->extends; - $saveExtendsMap = $this->extendsMap; - - $this->extends = []; - $this->extendsMap = []; - - foreach ($extendee as $es) { - if (\count($es) !== 1) { - throw $this->error('Can\'t extend complex selector.'); - } - - // only use the first one - $this->pushExtends(reset($es), $extender, null); - } - - $extended = []; - - foreach ($selectors as $selector) { - if (! $replace) { - $extended[] = $selector; - } - - $n = \count($extended); - - $this->matchExtends($selector, $extended); - - // if didnt match, keep the original selector if we are in a replace operation - if ($replace && \count($extended) === $n) { - $extended[] = $selector; - } - } - - $this->extends = $saveExtends; - $this->extendsMap = $saveExtendsMap; - - return $extended; - } - - protected static $libSelectorNest = ['selector...']; - protected function libSelectorNest($args) - { - // get the selector... list - $args = reset($args); - $args = $args[2]; - - if (\count($args) < 1) { - throw $this->error('selector-nest() needs at least 1 argument'); - } - - $selectorsMap = []; - foreach ($args as $arg) { - $selectorsMap[] = $this->getSelectorArg($arg, 'selector', true); - } - - assert(!empty($selectorsMap)); - - $envs = []; - - foreach ($selectorsMap as $selectors) { - $env = new Environment(); - $env->selectors = $selectors; - - $envs[] = $env; - } - - $envs = array_reverse($envs); - $env = $this->extractEnv($envs); - $outputSelectors = $this->multiplySelectors($env); - - return $this->formatOutputSelector($outputSelectors); - } - - protected static $libSelectorParse = [ - ['selector'], - ['selectors'] - ]; - protected function libSelectorParse($args) - { - $selectors = reset($args); - $selectors = $this->getSelectorArg($selectors, 'selector'); - - return $this->formatOutputSelector($selectors); - } - - protected static $libSelectorUnify = ['selectors1', 'selectors2']; - protected function libSelectorUnify($args) - { - list($selectors1, $selectors2) = $args; - - $selectors1 = $this->getSelectorArg($selectors1, 'selectors1'); - $selectors2 = $this->getSelectorArg($selectors2, 'selectors2'); - - if (! $selectors1 || ! $selectors2) { - throw $this->error('selector-unify() invalid arguments'); - } - - // only consider the first compound of each - $compound1 = reset($selectors1); - $compound2 = reset($selectors2); - - // unify them and that's it - $unified = $this->unifyCompoundSelectors($compound1, $compound2); - - return $this->formatOutputSelector($unified); - } - - /** - * The selector-unify magic as its best - * (at least works as expected on test cases) - * - * @param array $compound1 - * @param array $compound2 - * - * @return array - */ - protected function unifyCompoundSelectors($compound1, $compound2) - { - if (! \count($compound1)) { - return $compound2; - } - - if (! \count($compound2)) { - return $compound1; - } - - // check that last part are compatible - $lastPart1 = array_pop($compound1); - $lastPart2 = array_pop($compound2); - $last = $this->mergeParts($lastPart1, $lastPart2); - - if (! $last) { - return [[]]; - } - - $unifiedCompound = [$last]; - $unifiedSelectors = [$unifiedCompound]; - - // do the rest - while (\count($compound1) || \count($compound2)) { - $part1 = end($compound1); - $part2 = end($compound2); - - if ($part1 && ($match2 = $this->matchPartInCompound($part1, $compound2))) { - list($compound2, $part2, $after2) = $match2; - - if ($after2) { - $unifiedSelectors = $this->prependSelectors($unifiedSelectors, $after2); - } - - $c = $this->mergeParts($part1, $part2); - $unifiedSelectors = $this->prependSelectors($unifiedSelectors, [$c]); - - $part1 = $part2 = null; - - array_pop($compound1); - } - - if ($part2 && ($match1 = $this->matchPartInCompound($part2, $compound1))) { - list($compound1, $part1, $after1) = $match1; - - if ($after1) { - $unifiedSelectors = $this->prependSelectors($unifiedSelectors, $after1); - } - - $c = $this->mergeParts($part2, $part1); - $unifiedSelectors = $this->prependSelectors($unifiedSelectors, [$c]); - - $part1 = $part2 = null; - - array_pop($compound2); - } - - $new = []; - - if ($part1 && $part2) { - array_pop($compound1); - array_pop($compound2); - - $s = $this->prependSelectors($unifiedSelectors, [$part2]); - $new = array_merge($new, $this->prependSelectors($s, [$part1])); - $s = $this->prependSelectors($unifiedSelectors, [$part1]); - $new = array_merge($new, $this->prependSelectors($s, [$part2])); - } elseif ($part1) { - array_pop($compound1); - - $new = array_merge($new, $this->prependSelectors($unifiedSelectors, [$part1])); - } elseif ($part2) { - array_pop($compound2); - - $new = array_merge($new, $this->prependSelectors($unifiedSelectors, [$part2])); - } - - if ($new) { - $unifiedSelectors = $new; - } - } - - return $unifiedSelectors; - } - - /** - * Prepend each selector from $selectors with $parts - * - * @param array $selectors - * @param array $parts - * - * @return array - */ - protected function prependSelectors($selectors, $parts) - { - $new = []; - - foreach ($selectors as $compoundSelector) { - array_unshift($compoundSelector, $parts); - - $new[] = $compoundSelector; - } - - return $new; - } - - /** - * Try to find a matching part in a compound: - * - with same html tag name - * - with some class or id or something in common - * - * @param array $part - * @param array $compound - * - * @return array|false - */ - protected function matchPartInCompound($part, $compound) - { - $partTag = $this->findTagName($part); - $before = $compound; - $after = []; - - // try to find a match by tag name first - while (\count($before)) { - $p = array_pop($before); - - if ($partTag && $partTag !== '*' && $partTag == $this->findTagName($p)) { - return [$before, $p, $after]; - } - - $after[] = $p; - } - - // try again matching a non empty intersection and a compatible tagname - $before = $compound; - $after = []; - - while (\count($before)) { - $p = array_pop($before); - - if ($this->checkCompatibleTags($partTag, $this->findTagName($p))) { - if (\count(array_intersect($part, $p))) { - return [$before, $p, $after]; - } - } - - $after[] = $p; - } - - return false; - } - - /** - * Merge two part list taking care that - * - the html tag is coming first - if any - * - the :something are coming last - * - * @param array $parts1 - * @param array $parts2 - * - * @return array - */ - protected function mergeParts($parts1, $parts2) - { - $tag1 = $this->findTagName($parts1); - $tag2 = $this->findTagName($parts2); - $tag = $this->checkCompatibleTags($tag1, $tag2); - - // not compatible tags - if ($tag === false) { - return []; - } - - if ($tag) { - if ($tag1) { - $parts1 = array_diff($parts1, [$tag1]); - } - - if ($tag2) { - $parts2 = array_diff($parts2, [$tag2]); - } - } - - $mergedParts = array_merge($parts1, $parts2); - $mergedOrderedParts = []; - - foreach ($mergedParts as $part) { - if (strpos($part, ':') === 0) { - $mergedOrderedParts[] = $part; - } - } - - $mergedParts = array_diff($mergedParts, $mergedOrderedParts); - $mergedParts = array_merge($mergedParts, $mergedOrderedParts); - - if ($tag) { - array_unshift($mergedParts, $tag); - } - - return $mergedParts; - } - - /** - * Check the compatibility between two tag names: - * if both are defined they should be identical or one has to be '*' - * - * @param string $tag1 - * @param string $tag2 - * - * @return array|false - */ - protected function checkCompatibleTags($tag1, $tag2) - { - $tags = [$tag1, $tag2]; - $tags = array_unique($tags); - $tags = array_filter($tags); - - if (\count($tags) > 1) { - $tags = array_diff($tags, ['*']); - } - - // not compatible nodes - if (\count($tags) > 1) { - return false; - } - - return $tags; - } - - /** - * Find the html tag name in a selector parts list - * - * @param string[] $parts - * - * @return string - */ - protected function findTagName($parts) - { - foreach ($parts as $part) { - if (! preg_match('/^[\[.:#%_-]/', $part)) { - return $part; - } - } - - return ''; - } - - protected static $libSimpleSelectors = ['selector']; - protected function libSimpleSelectors($args) - { - $selector = reset($args); - $selector = $this->getSelectorArg($selector, 'selector'); - - // remove selectors list layer, keeping the first one - $selector = reset($selector); - - // remove parts list layer, keeping the first part - $part = reset($selector); - - $listParts = []; - - foreach ($part as $p) { - $listParts[] = [Type::T_STRING, '', [$p]]; - } - - return [Type::T_LIST, ',', $listParts]; - } - - protected static $libScssphpGlob = ['pattern']; - protected function libScssphpGlob($args) - { - @trigger_error(sprintf('The "scssphp-glob" function is deprecated an will be removed in ScssPhp 2.0. Register your own alternative through "%s::registerFunction', __CLASS__), E_USER_DEPRECATED); - - $this->logger->warn('The "scssphp-glob" function is deprecated an will be removed in ScssPhp 2.0.', true); - - $string = $this->assertString($args[0], 'pattern'); - $pattern = $this->compileStringContent($string); - $matches = glob($pattern); - $listParts = []; - - foreach ($matches as $match) { - if (! is_file($match)) { - continue; - } - - $listParts[] = [Type::T_STRING, '"', [$match]]; - } - - return [Type::T_LIST, ',', $listParts]; - } -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Compiler/CachedResult.php b/plugins/admin/vendor/scssphp/scssphp/src/Compiler/CachedResult.php deleted file mode 100644 index a662919..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/Compiler/CachedResult.php +++ /dev/null @@ -1,77 +0,0 @@ - - */ - private $parsedFiles; - - /** - * @var array - * @phpstan-var list - */ - private $resolvedImports; - - /** - * @param CompilationResult $result - * @param array $parsedFiles - * @param array $resolvedImports - * - * @phpstan-param list $resolvedImports - */ - public function __construct(CompilationResult $result, array $parsedFiles, array $resolvedImports) - { - $this->result = $result; - $this->parsedFiles = $parsedFiles; - $this->resolvedImports = $resolvedImports; - } - - /** - * @return CompilationResult - */ - public function getResult() - { - return $this->result; - } - - /** - * @return array - */ - public function getParsedFiles() - { - return $this->parsedFiles; - } - - /** - * @return array - * - * @phpstan-return list - */ - public function getResolvedImports() - { - return $this->resolvedImports; - } -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Compiler/Environment.php b/plugins/admin/vendor/scssphp/scssphp/src/Compiler/Environment.php deleted file mode 100644 index b205a07..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/Compiler/Environment.php +++ /dev/null @@ -1,68 +0,0 @@ - - * - * @internal - */ -class Environment -{ - /** - * @var \ScssPhp\ScssPhp\Block|null - */ - public $block; - - /** - * @var \ScssPhp\ScssPhp\Compiler\Environment|null - */ - public $parent; - - /** - * @var Environment|null - */ - public $declarationScopeParent; - - /** - * @var Environment|null - */ - public $parentStore; - - /** - * @var array|null - */ - public $selectors; - - /** - * @var string|null - */ - public $marker; - - /** - * @var array - */ - public $store; - - /** - * @var array - */ - public $storeUnreduced; - - /** - * @var int - */ - public $depth; -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Exception/CompilerException.php b/plugins/admin/vendor/scssphp/scssphp/src/Exception/CompilerException.php deleted file mode 100644 index 0b00cf5..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/Exception/CompilerException.php +++ /dev/null @@ -1,24 +0,0 @@ - - * - * @internal - */ -class CompilerException extends \Exception implements SassException -{ -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Exception/ParserException.php b/plugins/admin/vendor/scssphp/scssphp/src/Exception/ParserException.php deleted file mode 100644 index f072669..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/Exception/ParserException.php +++ /dev/null @@ -1,58 +0,0 @@ - - * - * @internal - */ -class ParserException extends \Exception implements SassException -{ - /** - * @var array|null - * @phpstan-var array{string, int, int}|null - */ - private $sourcePosition; - - /** - * Get source position - * - * @api - * - * @return array|null - * @phpstan-return array{string, int, int}|null - */ - public function getSourcePosition() - { - return $this->sourcePosition; - } - - /** - * Set source position - * - * @api - * - * @param array $sourcePosition - * - * @return void - * - * @phpstan-param array{string, int, int} $sourcePosition - */ - public function setSourcePosition($sourcePosition) - { - $this->sourcePosition = $sourcePosition; - } -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Exception/RangeException.php b/plugins/admin/vendor/scssphp/scssphp/src/Exception/RangeException.php deleted file mode 100644 index 4be4dee..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/Exception/RangeException.php +++ /dev/null @@ -1,24 +0,0 @@ - - * - * @internal - */ -class RangeException extends \Exception implements SassException -{ -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Exception/SassException.php b/plugins/admin/vendor/scssphp/scssphp/src/Exception/SassException.php deleted file mode 100644 index 9f62b3c..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/Exception/SassException.php +++ /dev/null @@ -1,7 +0,0 @@ - - * - * @deprecated The Scssphp server should define its own exception instead. - */ -class ServerException extends \Exception implements SassException -{ -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Formatter.php b/plugins/admin/vendor/scssphp/scssphp/src/Formatter.php deleted file mode 100644 index 6137dc6..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/Formatter.php +++ /dev/null @@ -1,377 +0,0 @@ - - * - * @internal - */ -abstract class Formatter -{ - /** - * @var int - */ - public $indentLevel; - - /** - * @var string - */ - public $indentChar; - - /** - * @var string - */ - public $break; - - /** - * @var string - */ - public $open; - - /** - * @var string - */ - public $close; - - /** - * @var string - */ - public $tagSeparator; - - /** - * @var string - */ - public $assignSeparator; - - /** - * @var bool - */ - public $keepSemicolons; - - /** - * @var \ScssPhp\ScssPhp\Formatter\OutputBlock - */ - protected $currentBlock; - - /** - * @var int - */ - protected $currentLine; - - /** - * @var int - */ - protected $currentColumn; - - /** - * @var \ScssPhp\ScssPhp\SourceMap\SourceMapGenerator|null - */ - protected $sourceMapGenerator; - - /** - * @var string - */ - protected $strippedSemicolon; - - /** - * Initialize formatter - * - * @api - */ - abstract public function __construct(); - - /** - * Return indentation (whitespace) - * - * @return string - */ - protected function indentStr() - { - return ''; - } - - /** - * Return property assignment - * - * @api - * - * @param string $name - * @param mixed $value - * - * @return string - */ - public function property($name, $value) - { - return rtrim($name) . $this->assignSeparator . $value . ';'; - } - - /** - * Return custom property assignment - * differs in that you have to keep spaces in the value as is - * - * @api - * - * @param string $name - * @param mixed $value - * - * @return string - */ - public function customProperty($name, $value) - { - return rtrim($name) . trim($this->assignSeparator) . $value . ';'; - } - - /** - * Output lines inside a block - * - * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block - * - * @return void - */ - protected function blockLines(OutputBlock $block) - { - $inner = $this->indentStr(); - $glue = $this->break . $inner; - - $this->write($inner . implode($glue, $block->lines)); - - if (! empty($block->children)) { - $this->write($this->break); - } - } - - /** - * Output block selectors - * - * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block - * - * @return void - */ - protected function blockSelectors(OutputBlock $block) - { - assert(! empty($block->selectors)); - - $inner = $this->indentStr(); - - $this->write($inner - . implode($this->tagSeparator, $block->selectors) - . $this->open . $this->break); - } - - /** - * Output block children - * - * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block - * - * @return void - */ - protected function blockChildren(OutputBlock $block) - { - foreach ($block->children as $child) { - $this->block($child); - } - } - - /** - * Output non-empty block - * - * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block - * - * @return void - */ - protected function block(OutputBlock $block) - { - if (empty($block->lines) && empty($block->children)) { - return; - } - - $this->currentBlock = $block; - - $pre = $this->indentStr(); - - if (! empty($block->selectors)) { - $this->blockSelectors($block); - - $this->indentLevel++; - } - - if (! empty($block->lines)) { - $this->blockLines($block); - } - - if (! empty($block->children)) { - $this->blockChildren($block); - } - - if (! empty($block->selectors)) { - $this->indentLevel--; - - if (! $this->keepSemicolons) { - $this->strippedSemicolon = ''; - } - - if (empty($block->children)) { - $this->write($this->break); - } - - $this->write($pre . $this->close . $this->break); - } - } - - /** - * Test and clean safely empty children - * - * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block - * - * @return bool - */ - protected function testEmptyChildren($block) - { - $isEmpty = empty($block->lines); - - if ($block->children) { - foreach ($block->children as $k => &$child) { - if (! $this->testEmptyChildren($child)) { - $isEmpty = false; - continue; - } - - if ($child->type === Type::T_MEDIA || $child->type === Type::T_DIRECTIVE) { - $child->children = []; - $child->selectors = null; - } - } - } - - return $isEmpty; - } - - /** - * Entry point to formatting a block - * - * @api - * - * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block An abstract syntax tree - * @param \ScssPhp\ScssPhp\SourceMap\SourceMapGenerator|null $sourceMapGenerator Optional source map generator - * - * @return string - */ - public function format(OutputBlock $block, SourceMapGenerator $sourceMapGenerator = null) - { - $this->sourceMapGenerator = null; - - if ($sourceMapGenerator) { - $this->currentLine = 1; - $this->currentColumn = 0; - $this->sourceMapGenerator = $sourceMapGenerator; - } - - $this->testEmptyChildren($block); - - ob_start(); - - try { - $this->block($block); - } catch (\Exception $e) { - ob_end_clean(); - throw $e; - } catch (\Throwable $e) { - ob_end_clean(); - throw $e; - } - - $out = ob_get_clean(); - assert($out !== false); - - return $out; - } - - /** - * Output content - * - * @param string $str - * - * @return void - */ - protected function write($str) - { - if (! empty($this->strippedSemicolon)) { - echo $this->strippedSemicolon; - - $this->strippedSemicolon = ''; - } - - /* - * Maybe Strip semi-colon appended by property(); it's a separator, not a terminator - * will be striped for real before a closing, otherwise displayed unchanged starting the next write - */ - if ( - ! $this->keepSemicolons && - $str && - (strpos($str, ';') !== false) && - (substr($str, -1) === ';') - ) { - $str = substr($str, 0, -1); - - $this->strippedSemicolon = ';'; - } - - if ($this->sourceMapGenerator) { - $lines = explode("\n", $str); - $lastLine = array_pop($lines); - - foreach ($lines as $line) { - // If the written line starts is empty, adding a mapping would add it for - // a non-existent column as we are at the end of the line - if ($line !== '') { - assert($this->currentBlock->sourceLine !== null); - assert($this->currentBlock->sourceName !== null); - $this->sourceMapGenerator->addMapping( - $this->currentLine, - $this->currentColumn, - $this->currentBlock->sourceLine, - //columns from parser are off by one - $this->currentBlock->sourceColumn > 0 ? $this->currentBlock->sourceColumn - 1 : 0, - $this->currentBlock->sourceName - ); - } - - $this->currentLine++; - $this->currentColumn = 0; - } - - if ($lastLine !== '') { - assert($this->currentBlock->sourceLine !== null); - assert($this->currentBlock->sourceName !== null); - $this->sourceMapGenerator->addMapping( - $this->currentLine, - $this->currentColumn, - $this->currentBlock->sourceLine, - //columns from parser are off by one - $this->currentBlock->sourceColumn > 0 ? $this->currentBlock->sourceColumn - 1 : 0, - $this->currentBlock->sourceName - ); - } - - $this->currentColumn += \strlen($lastLine); - } - - echo $str; - } -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Formatter/Compact.php b/plugins/admin/vendor/scssphp/scssphp/src/Formatter/Compact.php deleted file mode 100644 index 22f2268..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/Formatter/Compact.php +++ /dev/null @@ -1,52 +0,0 @@ - - * - * @deprecated since 1.4.0. Use the Compressed formatter instead. - * - * @internal - */ -class Compact extends Formatter -{ - /** - * {@inheritdoc} - */ - public function __construct() - { - @trigger_error('The Compact formatter is deprecated since 1.4.0. Use the Compressed formatter instead.', E_USER_DEPRECATED); - - $this->indentLevel = 0; - $this->indentChar = ''; - $this->break = ''; - $this->open = ' {'; - $this->close = "}\n\n"; - $this->tagSeparator = ','; - $this->assignSeparator = ':'; - $this->keepSemicolons = true; - } - - /** - * {@inheritdoc} - */ - public function indentStr() - { - return ' '; - } -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Formatter/Compressed.php b/plugins/admin/vendor/scssphp/scssphp/src/Formatter/Compressed.php deleted file mode 100644 index 58ebe3f..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/Formatter/Compressed.php +++ /dev/null @@ -1,83 +0,0 @@ - - * - * @internal - */ -class Compressed extends Formatter -{ - /** - * {@inheritdoc} - */ - public function __construct() - { - $this->indentLevel = 0; - $this->indentChar = ' '; - $this->break = ''; - $this->open = '{'; - $this->close = '}'; - $this->tagSeparator = ','; - $this->assignSeparator = ':'; - $this->keepSemicolons = false; - } - - /** - * {@inheritdoc} - */ - public function blockLines(OutputBlock $block) - { - $inner = $this->indentStr(); - - $glue = $this->break . $inner; - - foreach ($block->lines as $index => $line) { - if (substr($line, 0, 2) === '/*' && substr($line, 2, 1) !== '!') { - unset($block->lines[$index]); - } - } - - $this->write($inner . implode($glue, $block->lines)); - - if (! empty($block->children)) { - $this->write($this->break); - } - } - - /** - * Output block selectors - * - * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block - */ - protected function blockSelectors(OutputBlock $block) - { - assert(! empty($block->selectors)); - - $inner = $this->indentStr(); - - $this->write( - $inner - . implode( - $this->tagSeparator, - str_replace([' > ', ' + ', ' ~ '], ['>', '+', '~'], $block->selectors) - ) - . $this->open . $this->break - ); - } -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Formatter/Crunched.php b/plugins/admin/vendor/scssphp/scssphp/src/Formatter/Crunched.php deleted file mode 100644 index 2bc1e92..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/Formatter/Crunched.php +++ /dev/null @@ -1,87 +0,0 @@ - - * - * @deprecated since 1.4.0. Use the Compressed formatter instead. - * - * @internal - */ -class Crunched extends Formatter -{ - /** - * {@inheritdoc} - */ - public function __construct() - { - @trigger_error('The Crunched formatter is deprecated since 1.4.0. Use the Compressed formatter instead.', E_USER_DEPRECATED); - - $this->indentLevel = 0; - $this->indentChar = ' '; - $this->break = ''; - $this->open = '{'; - $this->close = '}'; - $this->tagSeparator = ','; - $this->assignSeparator = ':'; - $this->keepSemicolons = false; - } - - /** - * {@inheritdoc} - */ - public function blockLines(OutputBlock $block) - { - $inner = $this->indentStr(); - - $glue = $this->break . $inner; - - foreach ($block->lines as $index => $line) { - if (substr($line, 0, 2) === '/*') { - unset($block->lines[$index]); - } - } - - $this->write($inner . implode($glue, $block->lines)); - - if (! empty($block->children)) { - $this->write($this->break); - } - } - - /** - * Output block selectors - * - * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block - */ - protected function blockSelectors(OutputBlock $block) - { - assert(! empty($block->selectors)); - - $inner = $this->indentStr(); - - $this->write( - $inner - . implode( - $this->tagSeparator, - str_replace([' > ', ' + ', ' ~ '], ['>', '+', '~'], $block->selectors) - ) - . $this->open . $this->break - ); - } -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Formatter/Debug.php b/plugins/admin/vendor/scssphp/scssphp/src/Formatter/Debug.php deleted file mode 100644 index b3f4422..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/Formatter/Debug.php +++ /dev/null @@ -1,127 +0,0 @@ - - * - * @deprecated since 1.4.0. - * - * @internal - */ -class Debug extends Formatter -{ - /** - * {@inheritdoc} - */ - public function __construct() - { - @trigger_error('The Debug formatter is deprecated since 1.4.0.', E_USER_DEPRECATED); - - $this->indentLevel = 0; - $this->indentChar = ''; - $this->break = "\n"; - $this->open = ' {'; - $this->close = ' }'; - $this->tagSeparator = ', '; - $this->assignSeparator = ': '; - $this->keepSemicolons = true; - } - - /** - * {@inheritdoc} - */ - protected function indentStr() - { - return str_repeat(' ', $this->indentLevel); - } - - /** - * {@inheritdoc} - */ - protected function blockLines(OutputBlock $block) - { - $indent = $this->indentStr(); - - if (empty($block->lines)) { - $this->write("{$indent}block->lines: []\n"); - - return; - } - - foreach ($block->lines as $index => $line) { - $this->write("{$indent}block->lines[{$index}]: $line\n"); - } - } - - /** - * {@inheritdoc} - */ - protected function blockSelectors(OutputBlock $block) - { - $indent = $this->indentStr(); - - if (empty($block->selectors)) { - $this->write("{$indent}block->selectors: []\n"); - - return; - } - - foreach ($block->selectors as $index => $selector) { - $this->write("{$indent}block->selectors[{$index}]: $selector\n"); - } - } - - /** - * {@inheritdoc} - */ - protected function blockChildren(OutputBlock $block) - { - $indent = $this->indentStr(); - - if (empty($block->children)) { - $this->write("{$indent}block->children: []\n"); - - return; - } - - $this->indentLevel++; - - foreach ($block->children as $i => $child) { - $this->block($child); - } - - $this->indentLevel--; - } - - /** - * {@inheritdoc} - */ - protected function block(OutputBlock $block) - { - $indent = $this->indentStr(); - - $this->write("{$indent}block->type: {$block->type}\n" . - "{$indent}block->depth: {$block->depth}\n"); - - $this->currentBlock = $block; - - $this->blockSelectors($block); - $this->blockLines($block); - $this->blockChildren($block); - } -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Formatter/Expanded.php b/plugins/admin/vendor/scssphp/scssphp/src/Formatter/Expanded.php deleted file mode 100644 index 6eb4a0c..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/Formatter/Expanded.php +++ /dev/null @@ -1,72 +0,0 @@ - - * - * @internal - */ -class Expanded extends Formatter -{ - /** - * {@inheritdoc} - */ - public function __construct() - { - $this->indentLevel = 0; - $this->indentChar = ' '; - $this->break = "\n"; - $this->open = ' {'; - $this->close = '}'; - $this->tagSeparator = ', '; - $this->assignSeparator = ': '; - $this->keepSemicolons = true; - } - - /** - * {@inheritdoc} - */ - protected function indentStr() - { - return str_repeat($this->indentChar, $this->indentLevel); - } - - /** - * {@inheritdoc} - */ - protected function blockLines(OutputBlock $block) - { - $inner = $this->indentStr(); - - $glue = $this->break . $inner; - - foreach ($block->lines as $index => $line) { - if (substr($line, 0, 2) === '/*') { - $replacedLine = preg_replace('/\r\n?|\n|\f/', $this->break, $line); - assert($replacedLine !== null); - $block->lines[$index] = $replacedLine; - } - } - - $this->write($inner . implode($glue, $block->lines)); - - if (empty($block->selectors) || ! empty($block->children)) { - $this->write($this->break); - } - } -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Formatter/Nested.php b/plugins/admin/vendor/scssphp/scssphp/src/Formatter/Nested.php deleted file mode 100644 index d5ed85c..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/Formatter/Nested.php +++ /dev/null @@ -1,238 +0,0 @@ - - * - * @deprecated since 1.4.0. Use the Expanded formatter instead. - * - * @internal - */ -class Nested extends Formatter -{ - /** - * @var int - */ - private $depth; - - /** - * {@inheritdoc} - */ - public function __construct() - { - @trigger_error('The Nested formatter is deprecated since 1.4.0. Use the Expanded formatter instead.', E_USER_DEPRECATED); - - $this->indentLevel = 0; - $this->indentChar = ' '; - $this->break = "\n"; - $this->open = ' {'; - $this->close = ' }'; - $this->tagSeparator = ', '; - $this->assignSeparator = ': '; - $this->keepSemicolons = true; - } - - /** - * {@inheritdoc} - */ - protected function indentStr() - { - $n = $this->depth - 1; - - return str_repeat($this->indentChar, max($this->indentLevel + $n, 0)); - } - - /** - * {@inheritdoc} - */ - protected function blockLines(OutputBlock $block) - { - $inner = $this->indentStr(); - $glue = $this->break . $inner; - - foreach ($block->lines as $index => $line) { - if (substr($line, 0, 2) === '/*') { - $replacedLine = preg_replace('/\r\n?|\n|\f/', $this->break, $line); - assert($replacedLine !== null); - $block->lines[$index] = $replacedLine; - } - } - - $this->write($inner . implode($glue, $block->lines)); - } - - /** - * {@inheritdoc} - */ - protected function block(OutputBlock $block) - { - static $depths; - static $downLevel; - static $closeBlock; - static $previousEmpty; - static $previousHasSelector; - - if ($block->type === 'root') { - $depths = [ 0 ]; - $downLevel = ''; - $closeBlock = ''; - $this->depth = 0; - $previousEmpty = false; - $previousHasSelector = false; - } - - $isMediaOrDirective = \in_array($block->type, [Type::T_DIRECTIVE, Type::T_MEDIA]); - $isSupport = ($block->type === Type::T_DIRECTIVE - && $block->selectors && strpos(implode('', $block->selectors), '@supports') !== false); - - while ($block->depth < end($depths) || ($block->depth == 1 && end($depths) == 1)) { - array_pop($depths); - $this->depth--; - - if ( - ! $this->depth && ($block->depth <= 1 || (! $this->indentLevel && $block->type === Type::T_COMMENT)) && - (($block->selectors && ! $isMediaOrDirective) || $previousHasSelector) - ) { - $downLevel = $this->break; - } - - if (empty($block->lines) && empty($block->children)) { - $previousEmpty = true; - } - } - - if (empty($block->lines) && empty($block->children)) { - return; - } - - $this->currentBlock = $block; - - if (! empty($block->lines) || (! empty($block->children) && ($this->depth < 1 || $isSupport))) { - if ($block->depth > end($depths)) { - if (! $previousEmpty || $this->depth < 1) { - $this->depth++; - - $depths[] = $block->depth; - } else { - // keep the current depth unchanged but take the block depth as a new reference for following blocks - array_pop($depths); - - $depths[] = $block->depth; - } - } - } - - $previousEmpty = ($block->type === Type::T_COMMENT); - $previousHasSelector = false; - - if (! empty($block->selectors)) { - if ($closeBlock) { - $this->write($closeBlock); - $closeBlock = ''; - } - - if ($downLevel) { - $this->write($downLevel); - $downLevel = ''; - } - - $this->blockSelectors($block); - - $this->indentLevel++; - } - - if (! empty($block->lines)) { - if ($closeBlock) { - $this->write($closeBlock); - $closeBlock = ''; - } - - if ($downLevel) { - $this->write($downLevel); - $downLevel = ''; - } - - $this->blockLines($block); - - $closeBlock = $this->break; - } - - if (! empty($block->children)) { - if ($this->depth > 0 && ($isMediaOrDirective || ! $this->hasFlatChild($block))) { - array_pop($depths); - - $this->depth--; - $this->blockChildren($block); - $this->depth++; - - $depths[] = $block->depth; - } else { - $this->blockChildren($block); - } - } - - // reclear to not be spoiled by children if T_DIRECTIVE - if ($block->type === Type::T_DIRECTIVE) { - $previousHasSelector = false; - } - - if (! empty($block->selectors)) { - $this->indentLevel--; - - if (! $this->keepSemicolons) { - $this->strippedSemicolon = ''; - } - - $this->write($this->close); - - $closeBlock = $this->break; - - if ($this->depth > 1 && ! empty($block->children)) { - array_pop($depths); - $this->depth--; - } - - if (! $isMediaOrDirective) { - $previousHasSelector = true; - } - } - - if ($block->type === 'root') { - $this->write($this->break); - } - } - - /** - * Block has flat child - * - * @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block - * - * @return bool - */ - private function hasFlatChild($block) - { - foreach ($block->children as $child) { - if (empty($child->selectors)) { - return true; - } - } - - return false; - } -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Formatter/OutputBlock.php b/plugins/admin/vendor/scssphp/scssphp/src/Formatter/OutputBlock.php deleted file mode 100644 index 2799656..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/Formatter/OutputBlock.php +++ /dev/null @@ -1,68 +0,0 @@ - - * - * @internal - */ -class OutputBlock -{ - /** - * @var string|null - */ - public $type; - - /** - * @var int - */ - public $depth; - - /** - * @var array|null - */ - public $selectors; - - /** - * @var string[] - */ - public $lines; - - /** - * @var OutputBlock[] - */ - public $children; - - /** - * @var OutputBlock|null - */ - public $parent; - - /** - * @var string|null - */ - public $sourceName; - - /** - * @var int|null - */ - public $sourceLine; - - /** - * @var int|null - */ - public $sourceColumn; -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Logger/LoggerInterface.php b/plugins/admin/vendor/scssphp/scssphp/src/Logger/LoggerInterface.php deleted file mode 100644 index 7c0a2f7..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/Logger/LoggerInterface.php +++ /dev/null @@ -1,48 +0,0 @@ -stream = $stream; - $this->closeOnDestruct = $closeOnDestruct; - } - - /** - * @internal - */ - public function __destruct() - { - if ($this->closeOnDestruct) { - fclose($this->stream); - } - } - - /** - * @inheritDoc - */ - public function warn($message, $deprecation = false) - { - $prefix = ($deprecation ? 'DEPRECATION ' : '') . 'WARNING: '; - - fwrite($this->stream, $prefix . $message . "\n\n"); - } - - /** - * @inheritDoc - */ - public function debug($message) - { - fwrite($this->stream, $message . "\n"); - } -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Node.php b/plugins/admin/vendor/scssphp/scssphp/src/Node.php deleted file mode 100644 index fcaf8a9..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/Node.php +++ /dev/null @@ -1,43 +0,0 @@ - - * - * @internal - */ -abstract class Node -{ - /** - * @var string - */ - public $type; - - /** - * @var int - */ - public $sourceIndex; - - /** - * @var int|null - */ - public $sourceLine; - - /** - * @var int|null - */ - public $sourceColumn; -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Node/Number.php b/plugins/admin/vendor/scssphp/scssphp/src/Node/Number.php deleted file mode 100644 index 6c04458..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/Node/Number.php +++ /dev/null @@ -1,844 +0,0 @@ - - * - * @template-implements \ArrayAccess - */ -class Number extends Node implements \ArrayAccess, \JsonSerializable -{ - const PRECISION = 10; - - /** - * @var int - * @deprecated use {Number::PRECISION} instead to read the precision. Configuring it is not supported anymore. - */ - public static $precision = self::PRECISION; - - /** - * @see http://www.w3.org/TR/2012/WD-css3-values-20120308/ - * - * @var array - * @phpstan-var array> - */ - protected static $unitTable = [ - 'in' => [ - 'in' => 1, - 'pc' => 6, - 'pt' => 72, - 'px' => 96, - 'cm' => 2.54, - 'mm' => 25.4, - 'q' => 101.6, - ], - 'turn' => [ - 'deg' => 360, - 'grad' => 400, - 'rad' => 6.28318530717958647692528676, // 2 * M_PI - 'turn' => 1, - ], - 's' => [ - 's' => 1, - 'ms' => 1000, - ], - 'Hz' => [ - 'Hz' => 1, - 'kHz' => 0.001, - ], - 'dpi' => [ - 'dpi' => 1, - 'dpcm' => 1 / 2.54, - 'dppx' => 1 / 96, - ], - ]; - - /** - * @var int|float - */ - private $dimension; - - /** - * @var string[] - * @phpstan-var list - */ - private $numeratorUnits; - - /** - * @var string[] - * @phpstan-var list - */ - private $denominatorUnits; - - /** - * Initialize number - * - * @param int|float $dimension - * @param string[]|string $numeratorUnits - * @param string[] $denominatorUnits - * - * @phpstan-param list|string $numeratorUnits - * @phpstan-param list $denominatorUnits - */ - public function __construct($dimension, $numeratorUnits, array $denominatorUnits = []) - { - if (is_string($numeratorUnits)) { - $numeratorUnits = $numeratorUnits ? [$numeratorUnits] : []; - } elseif (isset($numeratorUnits['numerator_units'], $numeratorUnits['denominator_units'])) { - // TODO get rid of this once `$number[2]` is not used anymore - $denominatorUnits = $numeratorUnits['denominator_units']; - $numeratorUnits = $numeratorUnits['numerator_units']; - } - - $this->dimension = $dimension; - $this->numeratorUnits = $numeratorUnits; - $this->denominatorUnits = $denominatorUnits; - } - - /** - * @return float|int - */ - public function getDimension() - { - return $this->dimension; - } - - /** - * @return list - */ - public function getNumeratorUnits() - { - return $this->numeratorUnits; - } - - /** - * @return list - */ - public function getDenominatorUnits() - { - return $this->denominatorUnits; - } - - /** - * @return mixed - */ - #[\ReturnTypeWillChange] - public function jsonSerialize() - { - // Passing a compiler instance makes the method output a Sass representation instead of a CSS one, supporting full units. - return $this->output(new Compiler()); - } - - /** - * @return bool - */ - #[\ReturnTypeWillChange] - public function offsetExists($offset) - { - if ($offset === -3) { - return ! \is_null($this->sourceColumn); - } - - if ($offset === -2) { - return ! \is_null($this->sourceLine); - } - - if ( - $offset === -1 || - $offset === 0 || - $offset === 1 || - $offset === 2 - ) { - return true; - } - - return false; - } - - /** - * @return mixed - */ - #[\ReturnTypeWillChange] - public function offsetGet($offset) - { - switch ($offset) { - case -3: - return $this->sourceColumn; - - case -2: - return $this->sourceLine; - - case -1: - return $this->sourceIndex; - - case 0: - return Type::T_NUMBER; - - case 1: - return $this->dimension; - - case 2: - return array('numerator_units' => $this->numeratorUnits, 'denominator_units' => $this->denominatorUnits); - } - } - - /** - * @return void - */ - #[\ReturnTypeWillChange] - public function offsetSet($offset, $value) - { - throw new \BadMethodCallException('Number is immutable'); - } - - /** - * @return void - */ - #[\ReturnTypeWillChange] - public function offsetUnset($offset) - { - throw new \BadMethodCallException('Number is immutable'); - } - - /** - * Returns true if the number is unitless - * - * @return bool - */ - public function unitless() - { - 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 - * - * @param string $unit - * - * @return bool - */ - public function hasUnit($unit) - { - return \count($this->numeratorUnits) === 1 && \count($this->denominatorUnits) === 0 && $this->numeratorUnits[0] === $unit; - } - - /** - * Returns unit(s) as the product of numerator units divided by the product of denominator units - * - * @return string - */ - public function unitStr() - { - if ($this->unitless()) { - return ''; - } - - return self::getUnitString($this->numeratorUnits, $this->denominatorUnits); - } - - /** - * @param float|int $min - * @param float|int $max - * @param string|null $name - * - * @return float|int - * @throws SassScriptException - */ - public function valueInRange($min, $max, $name = null) - { - 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, $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); - } - } - - /** - * @param string|null $varName - * - * @return void - */ - public function assertNoUnits($varName = null) - { - if ($this->unitless()) { - return; - } - - throw SassScriptException::forArgument(sprintf('Expected %s to have no units.', $this), $varName); - } - - /** - * @param string $unit - * @param string|null $varName - * - * @return void - */ - public function assertUnit($unit, $varName = null) - { - if ($this->hasUnit($unit)) { - return; - } - - throw SassScriptException::forArgument(sprintf('Expected %s to have unit "%s".', $this, $unit), $varName); - } - - /** - * @param Number $other - * - * @return void - */ - public function assertSameUnitOrUnitless(Number $other) - { - if ($other->unitless()) { - return; - } - - if ($this->numeratorUnits === $other->numeratorUnits && $this->denominatorUnits === $other->denominatorUnits) { - return; - } - - throw new SassScriptException(sprintf( - 'Incompatible units %s and %s.', - self::getUnitString($this->numeratorUnits, $this->denominatorUnits), - self::getUnitString($other->numeratorUnits, $other->denominatorUnits) - )); - } - - /** - * Returns a copy of this number, converted to the units represented by $newNumeratorUnits and $newDenominatorUnits. - * - * This does not throw an error if this number is unitless and - * $newNumeratorUnits/$newDenominatorUnits are not empty, or vice versa. Instead, - * it treats all unitless numbers as convertible to and from all units without - * changing the value. - * - * @param string[] $newNumeratorUnits - * @param string[] $newDenominatorUnits - * - * @return Number - * - * @phpstan-param list $newNumeratorUnits - * @phpstan-param list $newDenominatorUnits - * - * @throws SassScriptException if this number's units are not compatible with $newNumeratorUnits and $newDenominatorUnits - */ - public function coerce(array $newNumeratorUnits, array $newDenominatorUnits) - { - return new Number($this->valueInUnits($newNumeratorUnits, $newDenominatorUnits), $newNumeratorUnits, $newDenominatorUnits); - } - - /** - * @param Number $other - * - * @return bool - */ - public function isComparableTo(Number $other) - { - if ($this->unitless() || $other->unitless()) { - return true; - } - - try { - $this->greaterThan($other); - return true; - } catch (SassScriptException $e) { - return false; - } - } - - /** - * @param Number $other - * - * @return bool - */ - public function lessThan(Number $other) - { - return $this->coerceUnits($other, function ($num1, $num2) { - return $num1 < $num2; - }); - } - - /** - * @param Number $other - * - * @return bool - */ - public function lessThanOrEqual(Number $other) - { - return $this->coerceUnits($other, function ($num1, $num2) { - return $num1 <= $num2; - }); - } - - /** - * @param Number $other - * - * @return bool - */ - public function greaterThan(Number $other) - { - return $this->coerceUnits($other, function ($num1, $num2) { - return $num1 > $num2; - }); - } - - /** - * @param Number $other - * - * @return bool - */ - public function greaterThanOrEqual(Number $other) - { - return $this->coerceUnits($other, function ($num1, $num2) { - return $num1 >= $num2; - }); - } - - /** - * @param Number $other - * - * @return Number - */ - public function plus(Number $other) - { - return $this->coerceNumber($other, function ($num1, $num2) { - return $num1 + $num2; - }); - } - - /** - * @param Number $other - * - * @return Number - */ - public function minus(Number $other) - { - return $this->coerceNumber($other, function ($num1, $num2) { - return $num1 - $num2; - }); - } - - /** - * @return Number - */ - public function unaryMinus() - { - return new Number(-$this->dimension, $this->numeratorUnits, $this->denominatorUnits); - } - - /** - * @param Number $other - * - * @return Number - */ - public function modulo(Number $other) - { - return $this->coerceNumber($other, function ($num1, $num2) { - if ($num2 == 0) { - return NAN; - } - - $result = fmod($num1, $num2); - - if ($result == 0) { - return 0; - } - - if ($num2 < 0 xor $num1 < 0) { - $result += $num2; - } - - return $result; - }); - } - - /** - * @param Number $other - * - * @return Number - */ - public function times(Number $other) - { - return $this->multiplyUnits($this->dimension * $other->dimension, $this->numeratorUnits, $this->denominatorUnits, $other->numeratorUnits, $other->denominatorUnits); - } - - /** - * @param Number $other - * - * @return Number - */ - public function dividedBy(Number $other) - { - if ($other->dimension == 0) { - if ($this->dimension == 0) { - $value = NAN; - } elseif ($this->dimension > 0) { - $value = INF; - } else { - $value = -INF; - } - } else { - $value = $this->dimension / $other->dimension; - } - - return $this->multiplyUnits($value, $this->numeratorUnits, $this->denominatorUnits, $other->denominatorUnits, $other->numeratorUnits); - } - - /** - * @param Number $other - * - * @return bool - */ - public function equals(Number $other) - { - // Unitless numbers are convertable to unit numbers, but not equal, so we special-case unitless here. - if ($this->unitless() !== $other->unitless()) { - return false; - } - - // In Sass, neither NaN nor Infinity are equal to themselves, while PHP defines INF==INF - if (is_nan($this->dimension) || is_nan($other->dimension) || !is_finite($this->dimension) || !is_finite($other->dimension)) { - return false; - } - - if ($this->unitless()) { - return round($this->dimension, self::PRECISION) == round($other->dimension, self::PRECISION); - } - - try { - return $this->coerceUnits($other, function ($num1, $num2) { - return round($num1, self::PRECISION) == round($num2, self::PRECISION); - }); - } catch (SassScriptException $e) { - return false; - } - } - - /** - * Output number - * - * @param \ScssPhp\ScssPhp\Compiler $compiler - * - * @return string - */ - public function output(Compiler $compiler = null) - { - $dimension = round($this->dimension, self::PRECISION); - - if (is_nan($dimension)) { - return 'NaN'; - } - - if ($dimension === INF) { - return 'Infinity'; - } - - if ($dimension === -INF) { - return '-Infinity'; - } - - if ($compiler) { - $unit = $this->unitStr(); - } elseif (isset($this->numeratorUnits[0])) { - $unit = $this->numeratorUnits[0]; - } else { - $unit = ''; - } - - $dimension = number_format($dimension, self::PRECISION, '.', ''); - - return rtrim(rtrim($dimension, '0'), '.') . $unit; - } - - /** - * {@inheritdoc} - */ - public function __toString() - { - return $this->output(); - } - - /** - * @param Number $other - * @param callable $operation - * - * @return Number - * - * @phpstan-param callable(int|float, int|float): (int|float) $operation - */ - private function coerceNumber(Number $other, $operation) - { - $result = $this->coerceUnits($other, $operation); - - if (!$this->unitless()) { - return new Number($result, $this->numeratorUnits, $this->denominatorUnits); - } - - return new Number($result, $other->numeratorUnits, $other->denominatorUnits); - } - - /** - * @param Number $other - * @param callable $operation - * - * @return mixed - * - * @phpstan-template T - * @phpstan-param callable(int|float, int|float): T $operation - * @phpstan-return T - */ - private function coerceUnits(Number $other, $operation) - { - if (!$this->unitless()) { - $num1 = $this->dimension; - $num2 = $other->valueInUnits($this->numeratorUnits, $this->denominatorUnits); - } else { - $num1 = $this->valueInUnits($other->numeratorUnits, $other->denominatorUnits); - $num2 = $other->dimension; - } - - return \call_user_func($operation, $num1, $num2); - } - - /** - * @param string[] $numeratorUnits - * @param string[] $denominatorUnits - * - * @return int|float - * - * @phpstan-param list $numeratorUnits - * @phpstan-param list $denominatorUnits - * - * @throws SassScriptException if this number's units are not compatible with $numeratorUnits and $denominatorUnits - */ - private function valueInUnits(array $numeratorUnits, array $denominatorUnits) - { - if ( - $this->unitless() - || (\count($numeratorUnits) === 0 && \count($denominatorUnits) === 0) - || ($this->numeratorUnits === $numeratorUnits && $this->denominatorUnits === $denominatorUnits) - ) { - return $this->dimension; - } - - $value = $this->dimension; - $oldNumerators = $this->numeratorUnits; - - foreach ($numeratorUnits as $newNumerator) { - foreach ($oldNumerators as $key => $oldNumerator) { - $conversionFactor = self::getConversionFactor($newNumerator, $oldNumerator); - - if (\is_null($conversionFactor)) { - continue; - } - - $value *= $conversionFactor; - unset($oldNumerators[$key]); - continue 2; - } - - throw new SassScriptException(sprintf( - 'Incompatible units %s and %s.', - self::getUnitString($this->numeratorUnits, $this->denominatorUnits), - self::getUnitString($numeratorUnits, $denominatorUnits) - )); - } - - $oldDenominators = $this->denominatorUnits; - - foreach ($denominatorUnits as $newDenominator) { - foreach ($oldDenominators as $key => $oldDenominator) { - $conversionFactor = self::getConversionFactor($newDenominator, $oldDenominator); - - if (\is_null($conversionFactor)) { - continue; - } - - $value /= $conversionFactor; - unset($oldDenominators[$key]); - continue 2; - } - - throw new SassScriptException(sprintf( - 'Incompatible units %s and %s.', - self::getUnitString($this->numeratorUnits, $this->denominatorUnits), - self::getUnitString($numeratorUnits, $denominatorUnits) - )); - } - - if (\count($oldNumerators) || \count($oldDenominators)) { - throw new SassScriptException(sprintf( - 'Incompatible units %s and %s.', - self::getUnitString($this->numeratorUnits, $this->denominatorUnits), - self::getUnitString($numeratorUnits, $denominatorUnits) - )); - } - - return $value; - } - - /** - * @param int|float $value - * @param string[] $numerators1 - * @param string[] $denominators1 - * @param string[] $numerators2 - * @param string[] $denominators2 - * - * @return Number - * - * @phpstan-param list $numerators1 - * @phpstan-param list $denominators1 - * @phpstan-param list $numerators2 - * @phpstan-param list $denominators2 - */ - private function multiplyUnits($value, array $numerators1, array $denominators1, array $numerators2, array $denominators2) - { - $newNumerators = array(); - - foreach ($numerators1 as $numerator) { - foreach ($denominators2 as $key => $denominator) { - $conversionFactor = self::getConversionFactor($numerator, $denominator); - - if (\is_null($conversionFactor)) { - continue; - } - - $value /= $conversionFactor; - unset($denominators2[$key]); - continue 2; - } - - $newNumerators[] = $numerator; - } - - foreach ($numerators2 as $numerator) { - foreach ($denominators1 as $key => $denominator) { - $conversionFactor = self::getConversionFactor($numerator, $denominator); - - if (\is_null($conversionFactor)) { - continue; - } - - $value /= $conversionFactor; - unset($denominators1[$key]); - continue 2; - } - - $newNumerators[] = $numerator; - } - - $newDenominators = array_values(array_merge($denominators1, $denominators2)); - - return new Number($value, $newNumerators, $newDenominators); - } - - /** - * Returns the number of [unit1]s per [unit2]. - * - * Equivalently, `1unit1 * conversionFactor(unit1, unit2) = 1unit2`. - * - * @param string $unit1 - * @param string $unit2 - * - * @return float|int|null - */ - private static function getConversionFactor($unit1, $unit2) - { - if ($unit1 === $unit2) { - return 1; - } - - foreach (static::$unitTable as $unitVariants) { - if (isset($unitVariants[$unit1]) && isset($unitVariants[$unit2])) { - return $unitVariants[$unit1] / $unitVariants[$unit2]; - } - } - - return null; - } - - /** - * Returns unit(s) as the product of numerator units divided by the product of denominator units - * - * @param string[] $numerators - * @param string[] $denominators - * - * @phpstan-param list $numerators - * @phpstan-param list $denominators - * - * @return string - */ - private static function getUnitString(array $numerators, array $denominators) - { - if (!\count($numerators)) { - if (\count($denominators) === 0) { - return 'no units'; - } - - if (\count($denominators) === 1) { - return $denominators[0] . '^-1'; - } - - return '(' . implode('*', $denominators) . ')^-1'; - } - - return implode('*', $numerators) . (\count($denominators) ? '/' . implode('*', $denominators) : ''); - } -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/OutputStyle.php b/plugins/admin/vendor/scssphp/scssphp/src/OutputStyle.php deleted file mode 100644 index a1d8b42..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/OutputStyle.php +++ /dev/null @@ -1,62 +0,0 @@ - - * - * @internal - */ -class Parser -{ - const SOURCE_INDEX = -1; - const SOURCE_LINE = -2; - const SOURCE_COLUMN = -3; - - /** - * @var array - */ - protected static $precedence = [ - '=' => 0, - 'or' => 1, - 'and' => 2, - '==' => 3, - '!=' => 3, - '<=' => 4, - '>=' => 4, - '<' => 4, - '>' => 4, - '+' => 5, - '-' => 5, - '*' => 6, - '/' => 6, - '%' => 6, - ]; - - /** - * @var string - */ - protected static $commentPattern; - /** - * @var string - */ - protected static $operatorPattern; - /** - * @var string - */ - protected static $whitePattern; - - /** - * @var Cache|null - */ - protected $cache; - - private $sourceName; - private $sourceIndex; - /** - * @var array - */ - private $sourcePositions; - /** - * The current offset in the buffer - * - * @var int - */ - private $count; - /** - * @var Block|null - */ - private $env; - /** - * @var bool - */ - private $inParens; - /** - * @var bool - */ - private $eatWhiteDefault; - /** - * @var bool - */ - private $discardComments; - private $allowVars; - /** - * @var string - */ - private $buffer; - private $utf8; - /** - * @var string|null - */ - private $encoding; - private $patternModifiers; - private $commentsSeen; - - private $cssOnly; - - /** - * @var LoggerInterface - */ - private $logger; - - /** - * Constructor - * - * @api - * - * @param string|null $sourceName - * @param int $sourceIndex - * @param string|null $encoding - * @param Cache|null $cache - * @param bool $cssOnly - * @param LoggerInterface|null $logger - */ - public function __construct($sourceName, $sourceIndex = 0, $encoding = 'utf-8', Cache $cache = null, $cssOnly = false, LoggerInterface $logger = null) - { - $this->sourceName = $sourceName ?: '(stdin)'; - $this->sourceIndex = $sourceIndex; - $this->utf8 = ! $encoding || strtolower($encoding) === 'utf-8'; - $this->patternModifiers = $this->utf8 ? 'Aisu' : 'Ais'; - $this->commentsSeen = []; - $this->allowVars = true; - $this->cssOnly = $cssOnly; - $this->logger = $logger ?: new QuietLogger(); - - if (empty(static::$operatorPattern)) { - static::$operatorPattern = '([*\/%+-]|[!=]\=|\>\=?|\<\=?|and|or)'; - - $commentSingle = '\/\/'; - $commentMultiLeft = '\/\*'; - $commentMultiRight = '\*\/'; - - static::$commentPattern = $commentMultiLeft . '.*?' . $commentMultiRight; - static::$whitePattern = $this->utf8 - ? '/' . $commentSingle . '[^\n]*\s*|(' . static::$commentPattern . ')\s*|\s+/AisuS' - : '/' . $commentSingle . '[^\n]*\s*|(' . static::$commentPattern . ')\s*|\s+/AisS'; - } - - $this->cache = $cache; - } - - /** - * Get source file name - * - * @api - * - * @return string - */ - public function getSourceName() - { - return $this->sourceName; - } - - /** - * Throw parser error - * - * @api - * - * @param string $msg - * - * @phpstan-return never-return - * - * @throws ParserException - * - * @deprecated use "parseError" and throw the exception in the caller instead. - */ - public function throwParseError($msg = 'parse error') - { - @trigger_error( - 'The method "throwParseError" is deprecated. Use "parseError" and throw the exception in the caller instead', - E_USER_DEPRECATED - ); - - throw $this->parseError($msg); - } - - /** - * Creates a parser error - * - * @api - * - * @param string $msg - * - * @return ParserException - */ - public function parseError($msg = 'parse error') - { - list($line, $column) = $this->getSourcePosition($this->count); - - $loc = empty($this->sourceName) - ? "line: $line, column: $column" - : "$this->sourceName on line $line, at column $column"; - - if ($this->peek('(.*?)(\n|$)', $m, $this->count)) { - $this->restoreEncoding(); - - $e = new ParserException("$msg: failed at `$m[1]` $loc"); - $e->setSourcePosition([$this->sourceName, $line, $column]); - - return $e; - } - - $this->restoreEncoding(); - - $e = new ParserException("$msg: $loc"); - $e->setSourcePosition([$this->sourceName, $line, $column]); - - return $e; - } - - /** - * Parser buffer - * - * @api - * - * @param string $buffer - * - * @return Block - */ - public function parse($buffer) - { - if ($this->cache) { - $cacheKey = $this->sourceName . ':' . md5($buffer); - $parseOptions = [ - 'utf8' => $this->utf8, - ]; - $v = $this->cache->getCache('parse', $cacheKey, $parseOptions); - - if (! \is_null($v)) { - return $v; - } - } - - // strip BOM (byte order marker) - if (substr($buffer, 0, 3) === "\xef\xbb\xbf") { - $buffer = substr($buffer, 3); - } - - $this->buffer = rtrim($buffer, "\x00..\x1f"); - $this->count = 0; - $this->env = null; - $this->inParens = false; - $this->eatWhiteDefault = true; - - $this->saveEncoding(); - $this->extractLineNumbers($buffer); - - if ($this->utf8 && !preg_match('//u', $buffer)) { - $message = $this->sourceName ? 'Invalid UTF-8 file: ' . $this->sourceName : 'Invalid UTF-8 file'; - throw new ParserException($message); - } - - $this->pushBlock(null); // root block - $this->whitespace(); - $this->pushBlock(null); - $this->popBlock(); - - while ($this->parseChunk()) { - ; - } - - if ($this->count !== \strlen($this->buffer)) { - throw $this->parseError(); - } - - if (! empty($this->env->parent)) { - throw $this->parseError('unclosed block'); - } - - $this->restoreEncoding(); - assert($this->env !== null); - - if ($this->cache) { - $this->cache->setCache('parse', $cacheKey, $this->env, $parseOptions); - } - - return $this->env; - } - - /** - * Parse a value or value list - * - * @api - * - * @param string $buffer - * @param mixed $out - * @param-out array|Number $out - * - * @return bool - */ - public function parseValue($buffer, &$out) - { - $this->count = 0; - $this->env = null; - $this->inParens = false; - $this->eatWhiteDefault = true; - $this->buffer = (string) $buffer; - - $this->saveEncoding(); - $this->extractLineNumbers($this->buffer); - - $list = $this->valueList($out); - - if ($this->count !== \strlen($this->buffer)) { - $error = $this->parseError('Expected end of value'); - $message = 'Passing trailing content after the expression when parsing a value is deprecated since Scssphp 1.12.0 and will be an error in 2.0. ' . $error->getMessage(); - - @trigger_error($message, E_USER_DEPRECATED); - } - - $this->restoreEncoding(); - - return $list; - } - - /** - * Parse a selector or selector list - * - * @api - * - * @param string $buffer - * @param array $out - * @param bool $shouldValidate - * - * @return bool - */ - public function parseSelector($buffer, &$out, $shouldValidate = true) - { - $this->count = 0; - $this->env = null; - $this->inParens = false; - $this->eatWhiteDefault = true; - $this->buffer = (string) $buffer; - - $this->saveEncoding(); - $this->extractLineNumbers($this->buffer); - - // discard space/comments at the start - $this->discardComments = true; - $this->whitespace(); - $this->discardComments = false; - - $selector = $this->selectors($out); - - $this->restoreEncoding(); - - if ($shouldValidate && $this->count !== strlen($buffer)) { - throw $this->parseError("`" . substr($buffer, $this->count) . "` is not a valid Selector in `$buffer`"); - } - - return $selector; - } - - /** - * Parse a media Query - * - * @api - * - * @param string $buffer - * @param array $out - * - * @return bool - */ - public function parseMediaQueryList($buffer, &$out) - { - $this->count = 0; - $this->env = null; - $this->inParens = false; - $this->eatWhiteDefault = true; - $this->buffer = (string) $buffer; - $this->discardComments = true; - - $this->saveEncoding(); - $this->extractLineNumbers($this->buffer); - - $this->whitespace(); - - $isMediaQuery = $this->mediaQueryList($out); - - $this->restoreEncoding(); - - return $isMediaQuery; - } - - /** - * Parse a single chunk off the head of the buffer and append it to the - * current parse environment. - * - * Returns false when the buffer is empty, or when there is an error. - * - * This function is called repeatedly until the entire document is - * parsed. - * - * This parser is most similar to a recursive descent parser. Single - * functions represent discrete grammatical rules for the language, and - * they are able to capture the text that represents those rules. - * - * Consider the function Compiler::keyword(). (All parse functions are - * structured the same.) - * - * The function takes a single reference argument. When calling the - * function it will attempt to match a keyword on the head of the buffer. - * If it is successful, it will place the keyword in the referenced - * argument, advance the position in the buffer, and return true. If it - * fails then it won't advance the buffer and it will return false. - * - * All of these parse functions are powered by Compiler::match(), which behaves - * the same way, but takes a literal regular expression. Sometimes it is - * more convenient to use match instead of creating a new function. - * - * Because of the format of the functions, to parse an entire string of - * grammatical rules, you can chain them together using &&. - * - * But, if some of the rules in the chain succeed before one fails, then - * the buffer position will be left at an invalid state. In order to - * avoid this, Compiler::seek() is used to remember and set buffer positions. - * - * Before parsing a chain, use $s = $this->count to remember the current - * position into $s. Then if a chain fails, use $this->seek($s) to - * go back where we started. - * - * @return bool - */ - protected function parseChunk() - { - $s = $this->count; - - // the directives - if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] === '@') { - if ( - $this->literal('@at-root', 8) && - ($this->selectors($selector) || true) && - ($this->map($with) || true) && - (($this->matchChar('(') && - $this->interpolation($with) && - $this->matchChar(')')) || true) && - $this->matchChar('{', false) - ) { - ! $this->cssOnly || $this->assertPlainCssValid(false, $s); - - $atRoot = new AtRootBlock(); - $this->registerPushedBlock($atRoot, $s); - $atRoot->selector = $selector; - $atRoot->with = $with; - - return true; - } - - $this->seek($s); - - if ( - $this->literal('@media', 6) && - $this->mediaQueryList($mediaQueryList) && - $this->matchChar('{', false) - ) { - $media = new MediaBlock(); - $this->registerPushedBlock($media, $s); - $media->queryList = $mediaQueryList[2]; - - return true; - } - - $this->seek($s); - - if ( - $this->literal('@mixin', 6) && - $this->keyword($mixinName) && - ($this->argumentDef($args) || true) && - $this->matchChar('{', false) - ) { - ! $this->cssOnly || $this->assertPlainCssValid(false, $s); - - $mixin = new CallableBlock(Type::T_MIXIN); - $this->registerPushedBlock($mixin, $s); - $mixin->name = $mixinName; - $mixin->args = $args; - - return true; - } - - $this->seek($s); - - if ( - ($this->literal('@include', 8) && - $this->keyword($mixinName) && - ($this->matchChar('(') && - ($this->argValues($argValues) || true) && - $this->matchChar(')') || true) && - ($this->end()) || - ($this->literal('using', 5) && - $this->argumentDef($argUsing) && - ($this->end() || $this->matchChar('{') && $hasBlock = true)) || - $this->matchChar('{') && $hasBlock = true) - ) { - ! $this->cssOnly || $this->assertPlainCssValid(false, $s); - - $child = [ - Type::T_INCLUDE, - $mixinName, - isset($argValues) ? $argValues : null, - null, - isset($argUsing) ? $argUsing : null - ]; - - if (! empty($hasBlock)) { - $include = new ContentBlock(); - $this->registerPushedBlock($include, $s); - $include->child = $child; - } else { - $this->append($child, $s); - } - - return true; - } - - $this->seek($s); - - if ( - $this->literal('@scssphp-import-once', 20) && - $this->valueList($importPath) && - $this->end() - ) { - ! $this->cssOnly || $this->assertPlainCssValid(false, $s); - - list($line, $column) = $this->getSourcePosition($s); - $file = $this->sourceName; - $this->logger->warn("The \"@scssphp-import-once\" directive is deprecated and will be removed in ScssPhp 2.0, in \"$file\", line $line, column $column.", true); - - $this->append([Type::T_SCSSPHP_IMPORT_ONCE, $importPath], $s); - - return true; - } - - $this->seek($s); - - if ( - $this->literal('@import', 7) && - $this->valueList($importPath) && - $importPath[0] !== Type::T_FUNCTION_CALL && - $this->end() - ) { - if ($this->cssOnly) { - $this->assertPlainCssValid([Type::T_IMPORT, $importPath], $s); - $this->append([Type::T_COMMENT, rtrim(substr($this->buffer, $s, $this->count - $s))]); - return true; - } - - $this->append([Type::T_IMPORT, $importPath], $s); - - return true; - } - - $this->seek($s); - - if ( - $this->literal('@import', 7) && - $this->url($importPath) && - $this->end() - ) { - if ($this->cssOnly) { - $this->assertPlainCssValid([Type::T_IMPORT, $importPath], $s); - $this->append([Type::T_COMMENT, rtrim(substr($this->buffer, $s, $this->count - $s))]); - return true; - } - - $this->append([Type::T_IMPORT, $importPath], $s); - - return true; - } - - $this->seek($s); - - if ( - $this->literal('@extend', 7) && - $this->selectors($selectors) && - $this->end() - ) { - ! $this->cssOnly || $this->assertPlainCssValid(false, $s); - - // check for '!flag' - $optional = $this->stripOptionalFlag($selectors); - $this->append([Type::T_EXTEND, $selectors, $optional], $s); - - return true; - } - - $this->seek($s); - - if ( - $this->literal('@function', 9) && - $this->keyword($fnName) && - $this->argumentDef($args) && - $this->matchChar('{', false) - ) { - ! $this->cssOnly || $this->assertPlainCssValid(false, $s); - - $func = new CallableBlock(Type::T_FUNCTION); - $this->registerPushedBlock($func, $s); - $func->name = $fnName; - $func->args = $args; - - return true; - } - - $this->seek($s); - - if ( - $this->literal('@return', 7) && - ($this->valueList($retVal) || true) && - $this->end() - ) { - ! $this->cssOnly || $this->assertPlainCssValid(false, $s); - - $this->append([Type::T_RETURN, isset($retVal) ? $retVal : [Type::T_NULL]], $s); - - return true; - } - - $this->seek($s); - - if ( - $this->literal('@each', 5) && - $this->genericList($varNames, 'variable', ',', false) && - $this->literal('in', 2) && - $this->valueList($list) && - $this->matchChar('{', false) - ) { - ! $this->cssOnly || $this->assertPlainCssValid(false, $s); - - $each = new EachBlock(); - $this->registerPushedBlock($each, $s); - - foreach ($varNames[2] as $varName) { - $each->vars[] = $varName[1]; - } - - $each->list = $list; - - return true; - } - - $this->seek($s); - - if ( - $this->literal('@while', 6) && - $this->expression($cond) && - $this->matchChar('{', false) - ) { - ! $this->cssOnly || $this->assertPlainCssValid(false, $s); - - while ( - $cond[0] === Type::T_LIST && - ! empty($cond['enclosing']) && - $cond['enclosing'] === 'parent' && - \count($cond[2]) == 1 - ) { - $cond = reset($cond[2]); - } - - $while = new WhileBlock(); - $this->registerPushedBlock($while, $s); - $while->cond = $cond; - - return true; - } - - $this->seek($s); - - if ( - $this->literal('@for', 4) && - $this->variable($varName) && - $this->literal('from', 4) && - $this->expression($start) && - ($this->literal('through', 7) || - ($forUntil = true && $this->literal('to', 2))) && - $this->expression($end) && - $this->matchChar('{', false) - ) { - ! $this->cssOnly || $this->assertPlainCssValid(false, $s); - - $for = new ForBlock(); - $this->registerPushedBlock($for, $s); - $for->var = $varName[1]; - $for->start = $start; - $for->end = $end; - $for->until = isset($forUntil); - - return true; - } - - $this->seek($s); - - if ( - $this->literal('@if', 3) && - $this->functionCallArgumentsList($cond, false, '{', false) - ) { - ! $this->cssOnly || $this->assertPlainCssValid(false, $s); - - $if = new IfBlock(); - $this->registerPushedBlock($if, $s); - - while ( - $cond[0] === Type::T_LIST && - ! empty($cond['enclosing']) && - $cond['enclosing'] === 'parent' && - \count($cond[2]) == 1 - ) { - $cond = reset($cond[2]); - } - - $if->cond = $cond; - $if->cases = []; - - return true; - } - - $this->seek($s); - - if ( - $this->literal('@debug', 6) && - $this->functionCallArgumentsList($value, false) - ) { - ! $this->cssOnly || $this->assertPlainCssValid(false, $s); - - $this->append([Type::T_DEBUG, $value], $s); - - return true; - } - - $this->seek($s); - - if ( - $this->literal('@warn', 5) && - $this->functionCallArgumentsList($value, false) - ) { - ! $this->cssOnly || $this->assertPlainCssValid(false, $s); - - $this->append([Type::T_WARN, $value], $s); - - return true; - } - - $this->seek($s); - - if ( - $this->literal('@error', 6) && - $this->functionCallArgumentsList($value, false) - ) { - ! $this->cssOnly || $this->assertPlainCssValid(false, $s); - - $this->append([Type::T_ERROR, $value], $s); - - return true; - } - - $this->seek($s); - - if ( - $this->literal('@content', 8) && - ($this->end() || - $this->matchChar('(') && - $this->argValues($argContent) && - $this->matchChar(')') && - $this->end()) - ) { - ! $this->cssOnly || $this->assertPlainCssValid(false, $s); - - $this->append([Type::T_MIXIN_CONTENT, isset($argContent) ? $argContent : null], $s); - - return true; - } - - $this->seek($s); - - $last = $this->last(); - - if (isset($last) && $last[0] === Type::T_IF) { - list(, $if) = $last; - assert($if instanceof IfBlock); - - if ($this->literal('@else', 5)) { - if ($this->matchChar('{', false)) { - $else = new ElseBlock(); - } elseif ( - $this->literal('if', 2) && - $this->functionCallArgumentsList($cond, false, '{', false) - ) { - $else = new ElseifBlock(); - $else->cond = $cond; - } - - if (isset($else)) { - $this->registerPushedBlock($else, $s); - $if->cases[] = $else; - - return true; - } - } - - $this->seek($s); - } - - // only retain the first @charset directive encountered - if ( - $this->literal('@charset', 8) && - $this->valueList($charset) && - $this->end() - ) { - return true; - } - - $this->seek($s); - - if ( - $this->literal('@supports', 9) && - ($t1 = $this->supportsQuery($supportQuery)) && - ($t2 = $this->matchChar('{', false)) - ) { - $directive = new DirectiveBlock(); - $this->registerPushedBlock($directive, $s); - $directive->name = 'supports'; - $directive->value = $supportQuery; - - return true; - } - - $this->seek($s); - - // doesn't match built in directive, do generic one - if ( - $this->matchChar('@', false) && - $this->mixedKeyword($dirName) && - $this->directiveValue($dirValue, '{') - ) { - if (count($dirName) === 1 && is_string(reset($dirName))) { - $dirName = reset($dirName); - } else { - $dirName = [Type::T_STRING, '', $dirName]; - } - if ($dirName === 'media') { - $directive = new MediaBlock(); - } else { - $directive = new DirectiveBlock(); - $directive->name = $dirName; - } - $this->registerPushedBlock($directive, $s); - - if (isset($dirValue)) { - ! $this->cssOnly || ($dirValue = $this->assertPlainCssValid($dirValue)); - $directive->value = $dirValue; - } - - return true; - } - - $this->seek($s); - - // maybe it's a generic blockless directive - if ( - $this->matchChar('@', false) && - $this->mixedKeyword($dirName) && - ! $this->isKnownGenericDirective($dirName) && - ($this->end(false) || ($this->directiveValue($dirValue, '') && $this->end(false))) - ) { - if (\count($dirName) === 1 && \is_string(\reset($dirName))) { - $dirName = \reset($dirName); - } else { - $dirName = [Type::T_STRING, '', $dirName]; - } - if ( - ! empty($this->env->parent) && - $this->env->type && - ! \in_array($this->env->type, [Type::T_DIRECTIVE, Type::T_MEDIA]) - ) { - $plain = \trim(\substr($this->buffer, $s, $this->count - $s)); - throw $this->parseError( - "Unknown directive `{$plain}` not allowed in `" . $this->env->type . "` block" - ); - } - // blockless directives with a blank line after keeps their blank lines after - // sass-spec compliance purpose - $s = $this->count; - $hasBlankLine = false; - if ($this->match('\s*?\n\s*\n', $out, false)) { - $hasBlankLine = true; - $this->seek($s); - } - $isNotRoot = ! empty($this->env->parent); - $this->append([Type::T_DIRECTIVE, [$dirName, $dirValue, $hasBlankLine, $isNotRoot]], $s); - $this->whitespace(); - - return true; - } - - $this->seek($s); - - return false; - } - - $inCssSelector = null; - if ($this->cssOnly) { - $inCssSelector = (! empty($this->env->parent) && - ! in_array($this->env->type, [Type::T_DIRECTIVE, Type::T_MEDIA])); - } - // custom properties : right part is static - if (($this->customProperty($name) ) && $this->matchChar(':', false)) { - $start = $this->count; - - // but can be complex and finish with ; or } - foreach ([';','}'] as $ending) { - if ( - $this->openString($ending, $stringValue, '(', ')', false) && - $this->end() - ) { - $end = $this->count; - $value = $stringValue; - - // check if we have only a partial value due to nested [] or { } to take in account - $nestingPairs = [['[', ']'], ['{', '}']]; - - foreach ($nestingPairs as $nestingPair) { - $p = strpos($this->buffer, $nestingPair[0], $start); - - if ($p && $p < $end) { - $this->seek($start); - - if ( - $this->openString($ending, $stringValue, $nestingPair[0], $nestingPair[1], false) && - $this->end() && - $this->count > $end - ) { - $end = $this->count; - $value = $stringValue; - } - } - } - - $this->seek($end); - $this->append([Type::T_CUSTOM_PROPERTY, $name, $value], $s); - - return true; - } - } - - // TODO: output an error here if nothing found according to sass spec - } - - $this->seek($s); - - // property shortcut - // captures most properties before having to parse a selector - if ( - $this->keyword($name, false) && - $this->literal(': ', 2) && - $this->valueList($value) && - $this->end() - ) { - $name = [Type::T_STRING, '', [$name]]; - $this->append([Type::T_ASSIGN, $name, $value], $s); - - return true; - } - - $this->seek($s); - - // variable assigns - if ( - $this->variable($name) && - $this->matchChar(':') && - $this->valueList($value) && - $this->end() - ) { - ! $this->cssOnly || $this->assertPlainCssValid(false, $s); - - // check for '!flag' - $assignmentFlags = $this->stripAssignmentFlags($value); - $this->append([Type::T_ASSIGN, $name, $value, $assignmentFlags], $s); - - return true; - } - - $this->seek($s); - - // opening css block - if ( - $this->selectors($selectors) && - $this->matchChar('{', false) - ) { - ! $this->cssOnly || ! $inCssSelector || $this->assertPlainCssValid(false); - - $this->pushBlock($selectors, $s); - - if ($this->eatWhiteDefault) { - $this->whitespace(); - $this->append(null); // collect comments at the beginning if needed - } - - return true; - } - - $this->seek($s); - - // property assign, or nested assign - if ( - $this->propertyName($name) && - $this->matchChar(':') - ) { - $foundSomething = false; - - if ($this->valueList($value)) { - if (empty($this->env->parent)) { - throw $this->parseError('expected "{"'); - } - - $this->append([Type::T_ASSIGN, $name, $value], $s); - $foundSomething = true; - } - - if ($this->matchChar('{', false)) { - ! $this->cssOnly || $this->assertPlainCssValid(false); - - $propBlock = new NestedPropertyBlock(); - $this->registerPushedBlock($propBlock, $s); - $propBlock->prefix = $name; - $propBlock->hasValue = $foundSomething; - - $foundSomething = true; - } elseif ($foundSomething) { - $foundSomething = $this->end(); - } - - if ($foundSomething) { - return true; - } - } - - $this->seek($s); - - // closing a block - if ($this->matchChar('}', false)) { - $block = $this->popBlock(); - - if (! isset($block->type) || $block->type !== Type::T_IF) { - assert($this->env !== null); - - if ($this->env->parent) { - $this->append(null); // collect comments before next statement if needed - } - } - - if ($block instanceof ContentBlock) { - $include = $block->child; - assert(\is_array($include)); - unset($block->child); - $include[3] = $block; - $this->append($include, $s); - } elseif (!$block instanceof ElseBlock && !$block instanceof ElseifBlock) { - $type = isset($block->type) ? $block->type : Type::T_BLOCK; - $this->append([$type, $block], $s); - } - - // collect comments just after the block closing if needed - if ($this->eatWhiteDefault) { - $this->whitespace(); - assert($this->env !== null); - - if ($this->env->comments) { - $this->append(null); - } - } - - return true; - } - - // extra stuff - if ($this->matchChar(';')) { - return true; - } - - return false; - } - - /** - * Push block onto parse tree - * - * @param array|null $selectors - * @param int $pos - * - * @return Block - */ - protected function pushBlock($selectors, $pos = 0) - { - $b = new Block(); - $b->selectors = $selectors; - - $this->registerPushedBlock($b, $pos); - - return $b; - } - - /** - * @param Block $b - * @param int $pos - * - * @return void - */ - private function registerPushedBlock(Block $b, $pos) - { - list($line, $column) = $this->getSourcePosition($pos); - - $b->sourceName = $this->sourceName; - $b->sourceLine = $line; - $b->sourceColumn = $column; - $b->sourceIndex = $this->sourceIndex; - $b->comments = []; - $b->parent = $this->env; - - if (! $this->env) { - $b->children = []; - } elseif (empty($this->env->children)) { - $this->env->children = $this->env->comments; - $b->children = []; - $this->env->comments = []; - } else { - $b->children = $this->env->comments; - $this->env->comments = []; - } - - $this->env = $b; - - // collect comments at the beginning of a block if needed - if ($this->eatWhiteDefault) { - $this->whitespace(); - assert($this->env !== null); - - if ($this->env->comments) { - $this->append(null); - } - } - } - - /** - * Push special (named) block onto parse tree - * - * @deprecated - * - * @param string $type - * @param int $pos - * - * @return Block - */ - protected function pushSpecialBlock($type, $pos) - { - $block = $this->pushBlock(null, $pos); - $block->type = $type; - - return $block; - } - - /** - * Pop scope and return last block - * - * @return Block - * - * @throws \Exception - */ - protected function popBlock() - { - assert($this->env !== null); - - // collect comments ending just before of a block closing - if ($this->env->comments) { - $this->append(null); - } - - // pop the block - $block = $this->env; - - if (empty($block->parent)) { - throw $this->parseError('unexpected }'); - } - - if ($block->type == Type::T_AT_ROOT) { - // keeps the parent in case of self selector & - $block->selfParent = $block->parent; - } - - $this->env = $block->parent; - - unset($block->parent); - - return $block; - } - - /** - * Peek input stream - * - * @param string $regex - * @param array $out - * @param int $from - * - * @return int - */ - protected function peek($regex, &$out, $from = null) - { - if (! isset($from)) { - $from = $this->count; - } - - $r = '/' . $regex . '/' . $this->patternModifiers; - $result = preg_match($r, $this->buffer, $out, 0, $from); - - return $result; - } - - /** - * Seek to position in input stream (or return current position in input stream) - * - * @param int $where - * - * @return void - */ - protected function seek($where) - { - $this->count = $where; - } - - /** - * Assert a parsed part is plain CSS Valid - * - * @param array|Number|false $parsed - * @param int $startPos - * - * @return array|Number - * - * @throws ParserException - */ - protected function assertPlainCssValid($parsed, $startPos = null) - { - $type = ''; - if ($parsed) { - $type = $parsed[0]; - $parsed = $this->isPlainCssValidElement($parsed); - } - if (! $parsed) { - if (! \is_null($startPos)) { - $plain = rtrim(substr($this->buffer, $startPos, $this->count - $startPos)); - $message = "Error : `{$plain}` isn't allowed in plain CSS"; - } else { - $message = 'Error: SCSS syntax not allowed in CSS file'; - } - if ($type) { - $message .= " ($type)"; - } - throw $this->parseError($message); - } - - return $parsed; - } - - /** - * Check a parsed element is plain CSS Valid - * - * @param array|Number|string $parsed - * @param bool $allowExpression - * - * @return ($parsed is string ? string : ($parsed is Number ? Number : array|false)) - */ - protected function isPlainCssValidElement($parsed, $allowExpression = false) - { - // keep string as is - if (is_string($parsed)) { - return $parsed; - } - - if ($parsed instanceof Number) { - return $parsed; - } - - if ( - \in_array($parsed[0], [Type::T_FUNCTION, Type::T_FUNCTION_CALL]) && - !\in_array($parsed[1], [ - 'alpha', - 'attr', - 'calc', - 'cubic-bezier', - 'env', - 'grayscale', - 'hsl', - 'hsla', - 'hwb', - 'invert', - 'linear-gradient', - 'min', - 'max', - 'radial-gradient', - 'repeating-linear-gradient', - 'repeating-radial-gradient', - 'rgb', - 'rgba', - 'rotate', - 'saturate', - 'var', - ]) && - Compiler::isNativeFunction($parsed[1]) - ) { - return false; - } - - switch ($parsed[0]) { - case Type::T_BLOCK: - case Type::T_KEYWORD: - case Type::T_NULL: - case Type::T_NUMBER: - case Type::T_MEDIA: - return $parsed; - - case Type::T_COMMENT: - if (isset($parsed[2])) { - return false; - } - return $parsed; - - case Type::T_DIRECTIVE: - if (\is_array($parsed[1])) { - $parsed[1][1] = $this->isPlainCssValidElement($parsed[1][1]); - if (! $parsed[1][1]) { - return false; - } - } - - return $parsed; - - case Type::T_IMPORT: - if ($parsed[1][0] === Type::T_LIST) { - return false; - } - $parsed[1] = $this->isPlainCssValidElement($parsed[1]); - if ($parsed[1] === false) { - return false; - } - return $parsed; - - case Type::T_STRING: - foreach ($parsed[2] as $k => $substr) { - if (\is_array($substr)) { - $parsed[2][$k] = $this->isPlainCssValidElement($substr); - if (! $parsed[2][$k]) { - return false; - } - } - } - return $parsed; - - case Type::T_LIST: - if (!empty($parsed['enclosing'])) { - return false; - } - foreach ($parsed[2] as $k => $listElement) { - $parsed[2][$k] = $this->isPlainCssValidElement($listElement); - if (! $parsed[2][$k]) { - return false; - } - } - return $parsed; - - case Type::T_ASSIGN: - foreach ([1, 2, 3] as $k) { - if (! empty($parsed[$k])) { - $parsed[$k] = $this->isPlainCssValidElement($parsed[$k]); - if (! $parsed[$k]) { - return false; - } - } - } - return $parsed; - - case Type::T_EXPRESSION: - list( ,$op, $lhs, $rhs, $inParens, $whiteBefore, $whiteAfter) = $parsed; - if (! $allowExpression && ! \in_array($op, ['and', 'or', '/'])) { - return false; - } - $lhs = $this->isPlainCssValidElement($lhs, true); - if (! $lhs) { - return false; - } - $rhs = $this->isPlainCssValidElement($rhs, true); - if (! $rhs) { - return false; - } - - return [ - Type::T_STRING, - '', [ - $this->inParens ? '(' : '', - $lhs, - ($whiteBefore ? ' ' : '') . $op . ($whiteAfter ? ' ' : ''), - $rhs, - $this->inParens ? ')' : '' - ] - ]; - - case Type::T_CUSTOM_PROPERTY: - case Type::T_UNARY: - $parsed[2] = $this->isPlainCssValidElement($parsed[2]); - if (! $parsed[2]) { - return false; - } - return $parsed; - - case Type::T_FUNCTION: - $argsList = $parsed[2]; - foreach ($argsList[2] as $argElement) { - if (! $this->isPlainCssValidElement($argElement)) { - return false; - } - } - return $parsed; - - case Type::T_FUNCTION_CALL: - $parsed[0] = Type::T_FUNCTION; - $argsList = [Type::T_LIST, ',', []]; - foreach ($parsed[2] as $arg) { - if ($arg[0] || ! empty($arg[2])) { - // no named arguments possible in a css function call - // nor ... argument - return false; - } - $arg = $this->isPlainCssValidElement($arg[1], $parsed[1] === 'calc'); - if (! $arg) { - return false; - } - $argsList[2][] = $arg; - } - $parsed[2] = $argsList; - return $parsed; - } - - return false; - } - - /** - * Match string looking for either ending delim, escape, or string interpolation - * - * {@internal This is a workaround for preg_match's 250K string match limit. }} - * - * @param array $m Matches (passed by reference) - * @param string $delim Delimiter - * - * @return bool True if match; false otherwise - * - * @phpstan-impure - */ - protected function matchString(&$m, $delim) - { - $token = null; - - $end = \strlen($this->buffer); - - // look for either ending delim, escape, or string interpolation - foreach (['#{', '\\', "\r", $delim] as $lookahead) { - $pos = strpos($this->buffer, $lookahead, $this->count); - - if ($pos !== false && $pos < $end) { - $end = $pos; - $token = $lookahead; - } - } - - if (! isset($token)) { - return false; - } - - $match = substr($this->buffer, $this->count, $end - $this->count); - $m = [ - $match . $token, - $match, - $token - ]; - $this->count = $end + \strlen($token); - - return true; - } - - /** - * Try to match something on head of buffer - * - * @param string $regex - * @param array $out - * @param bool $eatWhitespace - * - * @return bool - * - * @phpstan-impure - */ - protected function match($regex, &$out, $eatWhitespace = null) - { - $r = '/' . $regex . '/' . $this->patternModifiers; - - if (! preg_match($r, $this->buffer, $out, 0, $this->count)) { - return false; - } - - $this->count += \strlen($out[0]); - - if (! isset($eatWhitespace)) { - $eatWhitespace = $this->eatWhiteDefault; - } - - if ($eatWhitespace) { - $this->whitespace(); - } - - return true; - } - - /** - * Match a single string - * - * @param string $char - * @param bool $eatWhitespace - * - * @return bool - * - * @phpstan-impure - */ - protected function matchChar($char, $eatWhitespace = null) - { - if (! isset($this->buffer[$this->count]) || $this->buffer[$this->count] !== $char) { - return false; - } - - $this->count++; - - if (! isset($eatWhitespace)) { - $eatWhitespace = $this->eatWhiteDefault; - } - - if ($eatWhitespace) { - $this->whitespace(); - } - - return true; - } - - /** - * Match literal string - * - * @param string $what - * @param int $len - * @param bool $eatWhitespace - * - * @return bool - * - * @phpstan-impure - */ - protected function literal($what, $len, $eatWhitespace = null) - { - if (strcasecmp(substr($this->buffer, $this->count, $len), $what) !== 0) { - return false; - } - - $this->count += $len; - - if (! isset($eatWhitespace)) { - $eatWhitespace = $this->eatWhiteDefault; - } - - if ($eatWhitespace) { - $this->whitespace(); - } - - return true; - } - - /** - * Match some whitespace - * - * @return bool - * - * @phpstan-impure - */ - protected function whitespace() - { - $gotWhite = false; - - while (preg_match(static::$whitePattern, $this->buffer, $m, 0, $this->count)) { - if (isset($m[1]) && empty($this->commentsSeen[$this->count])) { - // comment that are kept in the output CSS - $comment = []; - $startCommentCount = $this->count; - $endCommentCount = $this->count + \strlen($m[1]); - - // find interpolations in comment - $p = strpos($this->buffer, '#{', $this->count); - - while ($p !== false && $p < $endCommentCount) { - $c = substr($this->buffer, $this->count, $p - $this->count); - $comment[] = $c; - $this->count = $p; - $out = null; - - if ($this->interpolation($out)) { - // keep right spaces in the following string part - if ($out[3]) { - while ($this->buffer[$this->count - 1] !== '}') { - $this->count--; - } - - $out[3] = ''; - } - - $comment[] = [Type::T_COMMENT, substr($this->buffer, $p, $this->count - $p), $out]; - } else { - list($line, $column) = $this->getSourcePosition($this->count); - $file = $this->sourceName; - if (!$this->discardComments) { - $this->logger->warn("Unterminated interpolations in multiline comments are deprecated and will be removed in ScssPhp 2.0, in \"$file\", line $line, column $column.", true); - } - $comment[] = substr($this->buffer, $this->count, 2); - - $this->count += 2; - } - - $p = strpos($this->buffer, '#{', $this->count); - } - - // remaining part - $c = substr($this->buffer, $this->count, $endCommentCount - $this->count); - - if (! $comment) { - // single part static comment - $commentStatement = [Type::T_COMMENT, $c]; - } else { - $comment[] = $c; - $staticComment = substr($this->buffer, $startCommentCount, $endCommentCount - $startCommentCount); - $commentStatement = [Type::T_COMMENT, $staticComment, [Type::T_STRING, '', $comment]]; - } - - list($line, $column) = $this->getSourcePosition($startCommentCount); - $commentStatement[self::SOURCE_LINE] = $line; - $commentStatement[self::SOURCE_COLUMN] = $column; - $commentStatement[self::SOURCE_INDEX] = $this->sourceIndex; - - $this->appendComment($commentStatement); - - $this->commentsSeen[$startCommentCount] = true; - $this->count = $endCommentCount; - } else { - // comment that are ignored and not kept in the output css - $this->count += \strlen($m[0]); - // silent comments are not allowed in plain CSS files - ! $this->cssOnly - || ! \strlen(trim($m[0])) - || $this->assertPlainCssValid(false, $this->count - \strlen($m[0])); - } - - $gotWhite = true; - } - - return $gotWhite; - } - - /** - * Append comment to current block - * - * @param array $comment - * - * @return void - */ - protected function appendComment($comment) - { - if (! $this->discardComments) { - assert($this->env !== null); - - $this->env->comments[] = $comment; - } - } - - /** - * Append statement to current block - * - * @param array|null $statement - * @param int $pos - * - * @return void - */ - protected function append($statement, $pos = null) - { - assert($this->env !== null); - - if (! \is_null($statement)) { - ! $this->cssOnly || ($statement = $this->assertPlainCssValid($statement, $pos)); - - if (! \is_null($pos)) { - list($line, $column) = $this->getSourcePosition($pos); - - $statement[static::SOURCE_LINE] = $line; - $statement[static::SOURCE_COLUMN] = $column; - $statement[static::SOURCE_INDEX] = $this->sourceIndex; - } - - $this->env->children[] = $statement; - } - - $comments = $this->env->comments; - - if ($comments) { - $this->env->children = array_merge($this->env->children, $comments); - $this->env->comments = []; - } - } - - /** - * Returns last child was appended - * - * @return array|null - */ - protected function last() - { - assert($this->env !== null); - - $i = \count($this->env->children) - 1; - - if (isset($this->env->children[$i])) { - return $this->env->children[$i]; - } - - return null; - } - - /** - * Parse media query list - * - * @param array $out - * - * @return bool - */ - protected function mediaQueryList(&$out) - { - return $this->genericList($out, 'mediaQuery', ',', false); - } - - /** - * Parse media query - * - * @param array $out - * - * @return bool - */ - protected function mediaQuery(&$out) - { - $expressions = null; - $parts = []; - - if ( - ($this->literal('only', 4) && ($only = true) || - $this->literal('not', 3) && ($not = true) || true) && - $this->mixedKeyword($mediaType) - ) { - $prop = [Type::T_MEDIA_TYPE]; - - if (isset($only)) { - $prop[] = [Type::T_KEYWORD, 'only']; - } - - if (isset($not)) { - $prop[] = [Type::T_KEYWORD, 'not']; - } - - $media = [Type::T_LIST, '', []]; - - foreach ((array) $mediaType as $type) { - if (\is_array($type)) { - $media[2][] = $type; - } else { - $media[2][] = [Type::T_KEYWORD, $type]; - } - } - - $prop[] = $media; - $parts[] = $prop; - } - - if (empty($parts) || $this->literal('and', 3)) { - $this->genericList($expressions, 'mediaExpression', 'and', false); - - if (\is_array($expressions)) { - $parts = array_merge($parts, $expressions[2]); - } - } - - $out = $parts; - - return true; - } - - /** - * Parse supports query - * - * @param array $out - * - * @return bool - */ - protected function supportsQuery(&$out) - { - $expressions = null; - $parts = []; - - $s = $this->count; - - $not = false; - - if ( - ($this->literal('not', 3) && ($not = true) || true) && - $this->matchChar('(') && - ($this->expression($property)) && - $this->literal(': ', 2) && - $this->valueList($value) && - $this->matchChar(')') - ) { - $support = [Type::T_STRING, '', [[Type::T_KEYWORD, ($not ? 'not ' : '') . '(']]]; - $support[2][] = $property; - $support[2][] = [Type::T_KEYWORD, ': ']; - $support[2][] = $value; - $support[2][] = [Type::T_KEYWORD, ')']; - - $parts[] = $support; - $s = $this->count; - } else { - $this->seek($s); - } - - if ( - $this->matchChar('(') && - $this->supportsQuery($subQuery) && - $this->matchChar(')') - ) { - $parts[] = [Type::T_STRING, '', [[Type::T_KEYWORD, '('], $subQuery, [Type::T_KEYWORD, ')']]]; - $s = $this->count; - } else { - $this->seek($s); - } - - if ( - $this->literal('not', 3) && - $this->supportsQuery($subQuery) - ) { - $parts[] = [Type::T_STRING, '', [[Type::T_KEYWORD, 'not '], $subQuery]]; - $s = $this->count; - } else { - $this->seek($s); - } - - if ( - $this->literal('selector(', 9) && - $this->selector($selector) && - $this->matchChar(')') - ) { - $support = [Type::T_STRING, '', [[Type::T_KEYWORD, 'selector(']]]; - - $selectorList = [Type::T_LIST, '', []]; - - foreach ($selector as $sc) { - $compound = [Type::T_STRING, '', []]; - - foreach ($sc as $scp) { - if (\is_array($scp)) { - $compound[2][] = $scp; - } else { - $compound[2][] = [Type::T_KEYWORD, $scp]; - } - } - - $selectorList[2][] = $compound; - } - - $support[2][] = $selectorList; - $support[2][] = [Type::T_KEYWORD, ')']; - $parts[] = $support; - $s = $this->count; - } else { - $this->seek($s); - } - - if ($this->variable($var) or $this->interpolation($var)) { - $parts[] = $var; - $s = $this->count; - } else { - $this->seek($s); - } - - if ( - $this->literal('and', 3) && - $this->genericList($expressions, 'supportsQuery', ' and', false) - ) { - array_unshift($expressions[2], [Type::T_STRING, '', $parts]); - - $parts = [$expressions]; - $s = $this->count; - } else { - $this->seek($s); - } - - if ( - $this->literal('or', 2) && - $this->genericList($expressions, 'supportsQuery', ' or', false) - ) { - array_unshift($expressions[2], [Type::T_STRING, '', $parts]); - - $parts = [$expressions]; - $s = $this->count; - } else { - $this->seek($s); - } - - if (\count($parts)) { - if ($this->eatWhiteDefault) { - $this->whitespace(); - } - - $out = [Type::T_STRING, '', $parts]; - - return true; - } - - return false; - } - - - /** - * Parse media expression - * - * @param array $out - * - * @return bool - */ - protected function mediaExpression(&$out) - { - $s = $this->count; - $value = null; - - if ( - $this->matchChar('(') && - $this->expression($feature) && - ($this->matchChar(':') && - $this->expression($value) || true) && - $this->matchChar(')') - ) { - $out = [Type::T_MEDIA_EXPRESSION, $feature]; - - if ($value) { - $out[] = $value; - } - - return true; - } - - $this->seek($s); - - return false; - } - - /** - * Parse argument values - * - * @param array $out - * - * @return bool - */ - protected function argValues(&$out) - { - $discardComments = $this->discardComments; - $this->discardComments = true; - - if ($this->genericList($list, 'argValue', ',', false)) { - $out = $list[2]; - - $this->discardComments = $discardComments; - - return true; - } - - $this->discardComments = $discardComments; - - return false; - } - - /** - * Parse argument value - * - * @param array $out - * - * @return bool - */ - protected function argValue(&$out) - { - $s = $this->count; - - $keyword = null; - - if (! $this->variable($keyword) || ! $this->matchChar(':')) { - $this->seek($s); - - $keyword = null; - } - - if ($this->genericList($value, 'expression', '', true)) { - $out = [$keyword, $value, false]; - $s = $this->count; - - if ($this->literal('...', 3)) { - $out[2] = true; - } else { - $this->seek($s); - } - - return true; - } - - return false; - } - - /** - * Check if a generic directive is known to be able to allow almost any syntax or not - * @param mixed $directiveName - * @return bool - */ - protected function isKnownGenericDirective($directiveName) - { - if (\is_array($directiveName) && \is_string(reset($directiveName))) { - $directiveName = reset($directiveName); - } - if (! \is_string($directiveName)) { - return false; - } - if ( - \in_array($directiveName, [ - 'at-root', - 'media', - 'mixin', - 'include', - 'scssphp-import-once', - 'import', - 'extend', - 'function', - 'break', - 'continue', - 'return', - 'each', - 'while', - 'for', - 'if', - 'debug', - 'warn', - 'error', - 'content', - 'else', - 'charset', - 'supports', - // Todo - 'use', - 'forward', - ]) - ) { - return true; - } - return false; - } - - /** - * Parse directive value list that considers $vars as keyword - * - * @param mixed $out - * @param string|false $endChar - * @param-out array|Number $out - * - * @return bool - * - * @phpstan-impure - */ - protected function directiveValue(&$out, $endChar = false) - { - $s = $this->count; - - if ($this->variable($out)) { - if ($endChar && $this->matchChar($endChar, false)) { - return true; - } - - if (! $endChar && $this->end()) { - return true; - } - } - - $this->seek($s); - - if (\is_string($endChar) && $this->openString($endChar ? $endChar : ';', $out, null, null, true, ";}{")) { - if ($endChar && $this->matchChar($endChar, false)) { - return true; - } - $ss = $this->count; - if (!$endChar && $this->end()) { - $this->seek($ss); - return true; - } - } - - $this->seek($s); - - $allowVars = $this->allowVars; - $this->allowVars = false; - - $res = $this->genericList($out, 'spaceList', ','); - $this->allowVars = $allowVars; - - if ($res) { - if ($endChar && $this->matchChar($endChar, false)) { - return true; - } - - if (! $endChar && $this->end()) { - return true; - } - } - - $this->seek($s); - - if ($endChar && $this->matchChar($endChar, false)) { - return true; - } - - return false; - } - - /** - * Parse comma separated value list - * - * @param mixed $out - * @param-out array|Number $out - * - * @return bool - */ - protected function valueList(&$out) - { - $discardComments = $this->discardComments; - $this->discardComments = true; - $res = $this->genericList($out, 'spaceList', ','); - $this->discardComments = $discardComments; - - return $res; - } - - /** - * Parse a function call, where externals () are part of the call - * and not of the value list - * - * @param mixed $out - * @param bool $mandatoryEnclos - * @param null|string $charAfter - * @param null|bool $eatWhiteSp - * @param-out array|Number $out - * - * @return bool - */ - protected function functionCallArgumentsList(&$out, $mandatoryEnclos = true, $charAfter = null, $eatWhiteSp = null) - { - $s = $this->count; - - if ( - $this->matchChar('(') && - $this->valueList($out) && - $this->matchChar(')') && - ($charAfter ? $this->matchChar($charAfter, $eatWhiteSp) : $this->end()) - ) { - return true; - } - - if (! $mandatoryEnclos) { - $this->seek($s); - - if ( - $this->valueList($out) && - ($charAfter ? $this->matchChar($charAfter, $eatWhiteSp) : $this->end()) - ) { - return true; - } - } - - $this->seek($s); - - return false; - } - - /** - * Parse space separated value list - * - * @param mixed $out - * @param-out array|Number $out - * - * @return bool - */ - protected function spaceList(&$out) - { - return $this->genericList($out, 'expression'); - } - - /** - * Parse generic list - * - * @param mixed $out - * @param string $parseItem The name of the method used to parse items - * @param string $delim - * @param bool $flatten - * @param-out ($flatten is false ? array : array|Number) $out - * - * @return bool - */ - protected function genericList(&$out, $parseItem, $delim = '', $flatten = true) - { - $s = $this->count; - $items = []; - /** @var array|Number|null $value */ - $value = null; - - while ($this->$parseItem($value)) { - $trailing_delim = false; - $items[] = $value; - - if ($delim) { - if (! $this->literal($delim, \strlen($delim))) { - break; - } - - $trailing_delim = true; - } else { - assert(\is_array($value) || $value instanceof Number); - // if no delim watch that a keyword didn't eat the single/double quote - // from the following starting string - if ($value[0] === Type::T_KEYWORD) { - assert(\is_array($value)); - /** @var string $word */ - $word = $value[1]; - - $last_char = substr($word, -1); - - if ( - strlen($word) > 1 && - in_array($last_char, [ "'", '"']) && - substr($word, -2, 1) !== '\\' - ) { - // if there is a non escaped opening quote in the keyword, this seems unlikely a mistake - $word = str_replace('\\' . $last_char, '\\\\', $word); - if (strpos($word, $last_char) < strlen($word) - 1) { - continue; - } - - $currentCount = $this->count; - - // let's try to rewind to previous char and try a parse - $this->count--; - // in case the keyword also eat spaces - while (substr($this->buffer, $this->count, 1) !== $last_char) { - $this->count--; - } - - /** @var array|Number|null $nextValue */ - $nextValue = null; - if ($this->$parseItem($nextValue)) { - assert(\is_array($nextValue) || $nextValue instanceof Number); - if ($nextValue[0] === Type::T_KEYWORD && $nextValue[1] === $last_char) { - // bad try, forget it - $this->seek($currentCount); - continue; - } - if ($nextValue[0] !== Type::T_STRING) { - // bad try, forget it - $this->seek($currentCount); - continue; - } - - // OK it was a good idea - $value[1] = substr($value[1], 0, -1); - array_pop($items); - $items[] = $value; - $items[] = $nextValue; - } else { - // bad try, forget it - $this->seek($currentCount); - continue; - } - } - } - } - } - - if (! $items) { - $this->seek($s); - - return false; - } - - if ($trailing_delim) { - $items[] = [Type::T_NULL]; - } - - if ($flatten && \count($items) === 1) { - $out = $items[0]; - } else { - $out = [Type::T_LIST, $delim, $items]; - } - - return true; - } - - /** - * Parse expression - * - * @param mixed $out - * @param bool $listOnly - * @param bool $lookForExp - * @param-out array|Number $out - * - * @return bool - * - * @phpstan-impure - */ - protected function expression(&$out, $listOnly = false, $lookForExp = true) - { - $s = $this->count; - $discard = $this->discardComments; - $this->discardComments = true; - $allowedTypes = ($listOnly ? [Type::T_LIST] : [Type::T_LIST, Type::T_MAP]); - - if ($this->matchChar('(')) { - if ($this->enclosedExpression($lhs, $s, ')', $allowedTypes)) { - if ($lookForExp) { - $out = $this->expHelper($lhs, 0); - } else { - $out = $lhs; - } - - $this->discardComments = $discard; - - return true; - } - - $this->seek($s); - } - - if (\in_array(Type::T_LIST, $allowedTypes) && $this->matchChar('[')) { - if ($this->enclosedExpression($lhs, $s, ']', [Type::T_LIST])) { - if ($lookForExp) { - $out = $this->expHelper($lhs, 0); - } else { - $out = $lhs; - } - - $this->discardComments = $discard; - - return true; - } - - $this->seek($s); - } - - if (! $listOnly && $this->value($lhs)) { - if ($lookForExp) { - $out = $this->expHelper($lhs, 0); - } else { - $out = $lhs; - } - - $this->discardComments = $discard; - - return true; - } - - $this->discardComments = $discard; - - return false; - } - - /** - * Parse expression specifically checking for lists in parenthesis or brackets - * - * @param mixed $out - * @param int $s - * @param string $closingParen - * @param string[] $allowedTypes - * @param-out array|Number $out - * - * @return bool - * - * @phpstan-param array $allowedTypes - */ - protected function enclosedExpression(&$out, $s, $closingParen = ')', $allowedTypes = [Type::T_LIST, Type::T_MAP]) - { - if ($this->matchChar($closingParen) && \in_array(Type::T_LIST, $allowedTypes)) { - $out = [Type::T_LIST, '', []]; - - switch ($closingParen) { - case ')': - $out['enclosing'] = 'parent'; // parenthesis list - break; - - case ']': - $out['enclosing'] = 'bracket'; // bracketed list - break; - } - - return true; - } - - if ( - $this->valueList($out) && - $this->matchChar($closingParen) && ! ($closingParen === ')' && - \in_array($out[0], [Type::T_EXPRESSION, Type::T_UNARY])) && - \in_array(Type::T_LIST, $allowedTypes) - ) { - if ($out[0] !== Type::T_LIST || ! empty($out['enclosing'])) { - $out = [Type::T_LIST, '', [$out]]; - } - - switch ($closingParen) { - case ')': - $out['enclosing'] = 'parent'; // parenthesis list - break; - - case ']': - $out['enclosing'] = 'bracket'; // bracketed list - break; - } - - return true; - } - - $this->seek($s); - - if (\in_array(Type::T_MAP, $allowedTypes) && $this->map($out)) { - return true; - } - - return false; - } - - /** - * Parse left-hand side of subexpression - * - * @param array|Number $lhs - * @param int $minP - * - * @return array|Number - */ - protected function expHelper($lhs, $minP) - { - $operators = static::$operatorPattern; - - $ss = $this->count; - $whiteBefore = isset($this->buffer[$this->count - 1]) && - ctype_space($this->buffer[$this->count - 1]); - - while ($this->match($operators, $m, false) && static::$precedence[strtolower($m[1])] >= $minP) { - $whiteAfter = isset($this->buffer[$this->count]) && - ctype_space($this->buffer[$this->count]); - $varAfter = isset($this->buffer[$this->count]) && - $this->buffer[$this->count] === '$'; - - $this->whitespace(); - - $op = $m[1]; - - // don't turn negative numbers into expressions - if ($op === '-' && $whiteBefore && ! $whiteAfter && ! $varAfter) { - break; - } - - if (! $this->value($rhs) && ! $this->expression($rhs, true, false)) { - break; - } - - if ($op === '-' && ! $whiteAfter && $rhs[0] === Type::T_KEYWORD) { - break; - } - - // consume higher-precedence operators on the right-hand side - $rhs = $this->expHelper($rhs, static::$precedence[strtolower($op)] + 1); - - $lhs = [Type::T_EXPRESSION, $op, $lhs, $rhs, $this->inParens, $whiteBefore, $whiteAfter]; - - $ss = $this->count; - $whiteBefore = isset($this->buffer[$this->count - 1]) && - ctype_space($this->buffer[$this->count - 1]); - } - - $this->seek($ss); - - return $lhs; - } - - /** - * Parse value - * - * @param mixed $out - * @param-out array|Number $out - * - * @return bool - */ - protected function value(&$out) - { - if (! isset($this->buffer[$this->count])) { - return false; - } - - $s = $this->count; - $char = $this->buffer[$this->count]; - - if ( - $this->literal('url(', 4) && - $this->match('data:([a-z]+)\/([a-z0-9.+-]+);base64,', $m, false) - ) { - $len = strspn( - $this->buffer, - 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwyxz0123456789+/=', - $this->count - ); - - $this->count += $len; - - if ($this->matchChar(')')) { - $content = substr($this->buffer, $s, $this->count - $s); - $out = [Type::T_KEYWORD, $content]; - - return true; - } - } - - $this->seek($s); - - if ( - $this->literal('url(', 4, false) && - $this->match('\s*(\/\/[^\s\)]+)\s*', $m) - ) { - $content = 'url(' . $m[1]; - - if ($this->matchChar(')')) { - $content .= ')'; - $out = [Type::T_KEYWORD, $content]; - - return true; - } - } - - $this->seek($s); - - // not - if ($char === 'n' && $this->literal('not', 3, false)) { - if ( - $this->whitespace() && - $this->value($inner) - ) { - $out = [Type::T_UNARY, 'not', $inner, $this->inParens]; - - return true; - } - - $this->seek($s); - - if ($this->parenValue($inner)) { - $out = [Type::T_UNARY, 'not', $inner, $this->inParens]; - - return true; - } - - $this->seek($s); - } - - // addition - if ($char === '+') { - $this->count++; - - $follow_white = $this->whitespace(); - - if ($this->value($inner)) { - $out = [Type::T_UNARY, '+', $inner, $this->inParens]; - - return true; - } - - if ($follow_white) { - $out = [Type::T_KEYWORD, $char]; - return true; - } - - $this->seek($s); - - return false; - } - - // negation - if ($char === '-') { - if ($this->customProperty($out)) { - return true; - } - - $this->count++; - - $follow_white = $this->whitespace(); - - if ($this->variable($inner) || $this->unit($inner) || $this->parenValue($inner)) { - $out = [Type::T_UNARY, '-', $inner, $this->inParens]; - - return true; - } - - if ( - $this->keyword($inner) && - ! $this->func($inner, $out) - ) { - $out = [Type::T_UNARY, '-', $inner, $this->inParens]; - - return true; - } - - if ($follow_white) { - $out = [Type::T_KEYWORD, $char]; - - return true; - } - - $this->seek($s); - } - - // paren - if ($char === '(' && $this->parenValue($out)) { - return true; - } - - if ($char === '#') { - if ($this->interpolation($out) || $this->color($out)) { - return true; - } - - $this->count++; - - if ($this->keyword($keyword)) { - $out = [Type::T_KEYWORD, '#' . $keyword]; - - return true; - } - - $this->count--; - } - - if ($this->matchChar('&', true)) { - $out = [Type::T_SELF]; - - return true; - } - - if ($char === '$' && $this->variable($out)) { - return true; - } - - if ($char === 'p' && $this->progid($out)) { - return true; - } - - if (($char === '"' || $char === "'") && $this->string($out)) { - return true; - } - - if ($this->unit($out)) { - return true; - } - - // unicode range with wildcards - if ( - $this->literal('U+', 2) && - $this->match('\?+|([0-9A-F]+(\?+|(-[0-9A-F]+))?)', $m, false) - ) { - $unicode = explode('-', $m[0]); - if (strlen(reset($unicode)) <= 6 && strlen(end($unicode)) <= 6) { - $out = [Type::T_KEYWORD, 'U+' . $m[0]]; - - return true; - } - $this->count -= strlen($m[0]) + 2; - } - - if ($this->keyword($keyword, false)) { - if ($this->func($keyword, $out)) { - return true; - } - - $this->whitespace(); - - if ($keyword === 'null') { - $out = [Type::T_NULL]; - } else { - $out = [Type::T_KEYWORD, $keyword]; - } - - return true; - } - - return false; - } - - /** - * Parse parenthesized value - * - * @param mixed $out - * @param-out array|Number $out - * - * @return bool - */ - protected function parenValue(&$out) - { - $s = $this->count; - - $inParens = $this->inParens; - - if ($this->matchChar('(')) { - if ($this->matchChar(')')) { - $out = [Type::T_LIST, '', []]; - - return true; - } - - $this->inParens = true; - - if ( - $this->expression($exp) && - $this->matchChar(')') - ) { - $out = $exp; - $this->inParens = $inParens; - - return true; - } - } - - $this->inParens = $inParens; - $this->seek($s); - - return false; - } - - /** - * Parse "progid:" - * - * @param array $out - * - * @return bool - */ - protected function progid(&$out) - { - $s = $this->count; - - if ( - $this->literal('progid:', 7, false) && - $this->openString('(', $fn) && - $this->matchChar('(') - ) { - $this->openString(')', $args, '('); - - if ($this->matchChar(')')) { - $out = [Type::T_STRING, '', [ - 'progid:', $fn, '(', $args, ')' - ]]; - - return true; - } - } - - $this->seek($s); - - return false; - } - - /** - * Parse function call - * - * @param string $name - * @param mixed $func - * @param-out array $func - * - * @return bool - */ - protected function func($name, &$func) - { - $s = $this->count; - - if ($this->matchChar('(')) { - if ($name === 'alpha' && $this->argumentList($args)) { - $func = [Type::T_FUNCTION, $name, [Type::T_STRING, '', $args]]; - - return true; - } - - if ($name !== 'expression' && ! preg_match('/^(-[a-z]+-)?calc$/', $name)) { - $ss = $this->count; - - if ( - $this->argValues($args) && - $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]; - - return true; - } - - $this->seek($ss); - } - - if ( - ($this->openString(')', $str, '(') || true) && - $this->matchChar(')') - ) { - $args = []; - - if (! empty($str)) { - $args[] = [null, [Type::T_STRING, '', [$str]]]; - } - - $func = [Type::T_FUNCTION_CALL, $name, $args]; - - return true; - } - } - - $this->seek($s); - - return false; - } - - /** - * Parse function call argument list - * - * @param array $out - * - * @return bool - */ - protected function argumentList(&$out) - { - $s = $this->count; - $this->matchChar('('); - - $args = []; - - while ($this->keyword($var)) { - if ( - $this->matchChar('=') && - $this->expression($exp) - ) { - $args[] = [Type::T_STRING, '', [$var . '=']]; - $arg = $exp; - } else { - break; - } - - $args[] = $arg; - - if (! $this->matchChar(',')) { - break; - } - - $args[] = [Type::T_STRING, '', [', ']]; - } - - if (! $this->matchChar(')') || ! $args) { - $this->seek($s); - - return false; - } - - $out = $args; - - return true; - } - - /** - * Parse mixin/function definition argument list - * - * @param mixed $out - * @param-out list $out - * - * @return bool - */ - protected function argumentDef(&$out) - { - $s = $this->count; - $this->matchChar('('); - - $args = []; - - while ($this->variable($var)) { - $arg = [$var[1], null, false]; - - $ss = $this->count; - - if ( - $this->matchChar(':') && - $this->genericList($defaultVal, 'expression', '', true) - ) { - $arg[1] = $defaultVal; - } else { - $this->seek($ss); - } - - $ss = $this->count; - - if ($this->literal('...', 3)) { - $sss = $this->count; - - if (! $this->matchChar(')')) { - throw $this->parseError('... has to be after the final argument'); - } - - $arg[2] = true; - - $this->seek($sss); - } else { - $this->seek($ss); - } - - $args[] = $arg; - - if (! $this->matchChar(',')) { - break; - } - } - - if (! $this->matchChar(')')) { - $this->seek($s); - - return false; - } - - $out = $args; - - return true; - } - - /** - * Parse map - * - * @param mixed $out - * @param-out array $out - * - * @return bool - */ - protected function map(&$out) - { - $s = $this->count; - - if (! $this->matchChar('(')) { - return false; - } - - $keys = []; - $values = []; - - while ( - $this->genericList($key, 'expression', '', true) && - $this->matchChar(':') && - $this->genericList($value, 'expression', '', true) - ) { - $keys[] = $key; - $values[] = $value; - - if (! $this->matchChar(',')) { - break; - } - } - - if (! $keys || ! $this->matchChar(')')) { - $this->seek($s); - - return false; - } - - $out = [Type::T_MAP, $keys, $values]; - - return true; - } - - /** - * Parse color - * - * @param mixed $out - * @param-out array $out - * - * @return bool - */ - protected function color(&$out) - { - $s = $this->count; - - if ($this->match('(#([0-9a-f]+)\b)', $m)) { - if (\in_array(\strlen($m[2]), [3,4,6,8])) { - $out = [Type::T_KEYWORD, $m[0]]; - - return true; - } - - $this->seek($s); - - return false; - } - - return false; - } - - /** - * Parse number with unit - * - * @param mixed $unit - * @param-out Number $unit - * - * @return bool - */ - protected function unit(&$unit) - { - $s = $this->count; - - if ($this->match('([0-9]*(\.)?[0-9]+)([%a-zA-Z]+)?', $m, false)) { - if (\strlen($this->buffer) === $this->count || ! ctype_digit($this->buffer[$this->count])) { - $this->whitespace(); - - $unit = new Node\Number($m[1], empty($m[3]) ? '' : $m[3]); - - return true; - } - - $this->seek($s); - } - - return false; - } - - /** - * Parse string - * - * @param array $out - * @param bool $keepDelimWithInterpolation - * - * @return bool - */ - protected function string(&$out, $keepDelimWithInterpolation = false) - { - $s = $this->count; - - if ($this->matchChar('"', false)) { - $delim = '"'; - } elseif ($this->matchChar("'", false)) { - $delim = "'"; - } else { - return false; - } - - $content = []; - $oldWhite = $this->eatWhiteDefault; - $this->eatWhiteDefault = false; - $hasInterpolation = false; - - while ($this->matchString($m, $delim)) { - if ($m[1] !== '') { - $content[] = $m[1]; - } - - if ($m[2] === '#{') { - $this->count -= \strlen($m[2]); - - if ($this->interpolation($inter, false)) { - $content[] = $inter; - $hasInterpolation = true; - } else { - $this->count += \strlen($m[2]); - $content[] = '#{'; // ignore it - } - } elseif ($m[2] === "\r") { - $content[] = chr(10); - // TODO : warning - # DEPRECATION WARNING on line x, column y of zzz: - # Unescaped multiline strings are deprecated and will be removed in a future version of Sass. - # To include a newline in a string, use "\a" or "\a " as in CSS. - if ($this->matchChar("\n", false)) { - $content[] = ' '; - } - } elseif ($m[2] === '\\') { - if ( - $this->literal("\r\n", 2, false) || - $this->matchChar("\r", false) || - $this->matchChar("\n", false) || - $this->matchChar("\f", false) - ) { - // this is a continuation escaping, to be ignored - } elseif ($this->matchEscapeCharacter($c)) { - $content[] = $c; - } else { - throw $this->parseError('Unterminated escape sequence'); - } - } else { - $this->count -= \strlen($delim); - break; // delim - } - } - - $this->eatWhiteDefault = $oldWhite; - - if ($this->literal($delim, \strlen($delim))) { - if ($hasInterpolation && ! $keepDelimWithInterpolation) { - $delim = '"'; - } - - $out = [Type::T_STRING, $delim, $content]; - - return true; - } - - $this->seek($s); - - return false; - } - - /** - * @param string $out - * @param bool $inKeywords - * - * @return bool - */ - protected function matchEscapeCharacter(&$out, $inKeywords = false) - { - $s = $this->count; - if ($this->match('[a-f0-9]', $m, false)) { - $hex = $m[0]; - - for ($i = 5; $i--;) { - if ($this->match('[a-f0-9]', $m, false)) { - $hex .= $m[0]; - } else { - break; - } - } - - // CSS allows Unicode escape sequences to be followed by a delimiter space - // (necessary in some cases for shorter sequences to disambiguate their end) - $this->matchChar(' ', false); - - $value = hexdec($hex); - - if (!$inKeywords && ($value == 0 || ($value >= 0xD800 && $value <= 0xDFFF) || $value >= 0x10FFFF)) { - $out = "\xEF\xBF\xBD"; // "\u{FFFD}" but with a syntax supported on PHP 5 - } elseif ($value < 0x20) { - $out = Util::mbChr($value); - } else { - $out = Util::mbChr($value); - } - - return true; - } - - if ($this->match('.', $m, false)) { - if ($inKeywords && in_array($m[0], ["'",'"','@','&',' ','\\',':','/','%'])) { - $this->seek($s); - return false; - } - $out = $m[0]; - - return true; - } - - return false; - } - - /** - * Parse keyword or interpolation - * - * @param array $out - * @param bool $restricted - * - * @return bool - */ - protected function mixedKeyword(&$out, $restricted = false) - { - $parts = []; - - $oldWhite = $this->eatWhiteDefault; - $this->eatWhiteDefault = false; - - for (;;) { - if ($restricted ? $this->restrictedKeyword($key) : $this->keyword($key)) { - $parts[] = $key; - continue; - } - - if ($this->interpolation($inter)) { - $parts[] = $inter; - continue; - } - - break; - } - - $this->eatWhiteDefault = $oldWhite; - - if (! $parts) { - return false; - } - - if ($this->eatWhiteDefault) { - $this->whitespace(); - } - - $out = $parts; - - return true; - } - - /** - * Parse an unbounded string stopped by $end - * - * @param string $end - * @param mixed $out - * @param string $nestOpen - * @param string $nestClose - * @param bool $rtrim - * @param string $disallow - * @param-out array $out - * - * @return bool - */ - protected function openString($end, &$out, $nestOpen = null, $nestClose = null, $rtrim = true, $disallow = null) - { - $oldWhite = $this->eatWhiteDefault; - $this->eatWhiteDefault = false; - - if ($nestOpen && ! $nestClose) { - $nestClose = $end; - } - - $patt = ($disallow ? '[^' . $this->pregQuote($disallow) . ']' : '.'); - $patt = '(' . $patt . '*?)([\'"]|#\{|' - . $this->pregQuote($end) . '|' - . (($nestClose && $nestClose !== $end) ? $this->pregQuote($nestClose) . '|' : '') - . static::$commentPattern . ')'; - - $nestingLevel = 0; - - $content = []; - - while ($this->match($patt, $m, false)) { - if (isset($m[1]) && $m[1] !== '') { - $content[] = $m[1]; - - if ($nestOpen) { - $nestingLevel += substr_count($m[1], $nestOpen); - } - } - - $tok = $m[2]; - - $this->count -= \strlen($tok); - - if ($tok === $end && ! $nestingLevel) { - break; - } - - if ($tok === $nestClose) { - $nestingLevel--; - } - - if (($tok === "'" || $tok === '"') && $this->string($str, true)) { - $content[] = $str; - continue; - } - - if ($tok === '#{' && $this->interpolation($inter)) { - $content[] = $inter; - continue; - } - - $content[] = $tok; - $this->count += \strlen($tok); - } - - $this->eatWhiteDefault = $oldWhite; - - if (! $content || $tok !== $end) { - return false; - } - - // trim the end - if ($rtrim && \is_string(end($content))) { - $content[\count($content) - 1] = rtrim(end($content)); - } - - $out = [Type::T_STRING, '', $content]; - - return true; - } - - /** - * Parser interpolation - * - * @param mixed $out - * @param bool $lookWhite save information about whitespace before and after - * @param-out array $out - * - * @return bool - */ - protected function interpolation(&$out, $lookWhite = true) - { - $oldWhite = $this->eatWhiteDefault; - $allowVars = $this->allowVars; - $this->allowVars = true; - $this->eatWhiteDefault = true; - - $s = $this->count; - - if ( - $this->literal('#{', 2) && - $this->valueList($value) && - $this->matchChar('}', false) - ) { - if ($value === [Type::T_SELF]) { - $out = $value; - } else { - if ($lookWhite) { - $left = ($s > 0 && preg_match('/\s/', $this->buffer[$s - 1])) ? ' ' : ''; - $right = ( - ! empty($this->buffer[$this->count]) && - preg_match('/\s/', $this->buffer[$this->count]) - ) ? ' ' : ''; - } else { - $left = $right = false; - } - - $out = [Type::T_INTERPOLATE, $value, $left, $right]; - } - - $this->eatWhiteDefault = $oldWhite; - $this->allowVars = $allowVars; - - if ($this->eatWhiteDefault) { - $this->whitespace(); - } - - return true; - } - - $this->seek($s); - - $this->eatWhiteDefault = $oldWhite; - $this->allowVars = $allowVars; - - return false; - } - - /** - * Parse property name (as an array of parts or a string) - * - * @param array $out - * - * @return bool - */ - protected function propertyName(&$out) - { - $parts = []; - - $oldWhite = $this->eatWhiteDefault; - $this->eatWhiteDefault = false; - - for (;;) { - if ($this->interpolation($inter)) { - $parts[] = $inter; - continue; - } - - if ($this->keyword($text)) { - $parts[] = $text; - continue; - } - - if (! $parts && $this->match('[:.#]', $m, false)) { - // css hacks - $parts[] = $m[0]; - continue; - } - - break; - } - - $this->eatWhiteDefault = $oldWhite; - - if (! $parts) { - return false; - } - - // match comment hack - if (preg_match(static::$whitePattern, $this->buffer, $m, 0, $this->count)) { - if (! empty($m[0])) { - $parts[] = $m[0]; - $this->count += \strlen($m[0]); - } - } - - $this->whitespace(); // get any extra whitespace - - $out = [Type::T_STRING, '', $parts]; - - return true; - } - - /** - * Parse custom property name (as an array of parts or a string) - * - * @param array $out - * - * @return bool - */ - protected function customProperty(&$out) - { - $s = $this->count; - - if (! $this->literal('--', 2, false)) { - return false; - } - - $parts = ['--']; - - $oldWhite = $this->eatWhiteDefault; - $this->eatWhiteDefault = false; - - for (;;) { - if ($this->interpolation($inter)) { - $parts[] = $inter; - continue; - } - - if ($this->matchChar('&', false)) { - $parts[] = [Type::T_SELF]; - continue; - } - - if ($this->variable($var)) { - $parts[] = $var; - continue; - } - - if ($this->keyword($text)) { - $parts[] = $text; - continue; - } - - break; - } - - $this->eatWhiteDefault = $oldWhite; - - if (\count($parts) == 1) { - $this->seek($s); - - return false; - } - - $this->whitespace(); // get any extra whitespace - - $out = [Type::T_STRING, '', $parts]; - - return true; - } - - /** - * Parse comma separated selector list - * - * @param array $out - * @param string|bool $subSelector - * - * @return bool - */ - protected function selectors(&$out, $subSelector = false) - { - $s = $this->count; - $selectors = []; - - while ($this->selector($sel, $subSelector)) { - $selectors[] = $sel; - - if (! $this->matchChar(',', true)) { - break; - } - - while ($this->matchChar(',', true)) { - ; // ignore extra - } - } - - if (! $selectors) { - $this->seek($s); - - return false; - } - - $out = $selectors; - - return true; - } - - /** - * Parse whitespace separated selector list - * - * @param array $out - * @param string|bool $subSelector - * - * @return bool - */ - protected function selector(&$out, $subSelector = false) - { - $selector = []; - - $discardComments = $this->discardComments; - $this->discardComments = true; - - for (;;) { - $s = $this->count; - - if ($this->match('[>+~]+', $m, true)) { - if ( - $subSelector && \is_string($subSelector) && strpos($subSelector, 'nth-') === 0 && - $m[0] === '+' && $this->match("(\d+|n\b)", $counter) - ) { - $this->seek($s); - } else { - $selector[] = [$m[0]]; - continue; - } - } - - if ($this->selectorSingle($part, $subSelector)) { - $selector[] = $part; - $this->whitespace(); - continue; - } - - break; - } - - $this->discardComments = $discardComments; - - if (! $selector) { - return false; - } - - $out = $selector; - - return true; - } - - /** - * parsing escaped chars in selectors: - * - escaped single chars are kept escaped in the selector but in a normalized form - * (if not in 0-9a-f range as this would be ambigous) - * - other escaped sequences (multibyte chars or 0-9a-f) are kept in their initial escaped form, - * normalized to lowercase - * - * TODO: this is a fallback solution. Ideally escaped chars in selectors should be encoded as the genuine chars, - * and escaping added when printing in the Compiler, where/if it's mandatory - * - but this require a better formal selector representation instead of the array we have now - * - * @param string $out - * @param bool $keepEscapedNumber - * - * @return bool - */ - protected function matchEscapeCharacterInSelector(&$out, $keepEscapedNumber = false) - { - $s_escape = $this->count; - if ($this->match('\\\\', $m)) { - $out = '\\' . $m[0]; - return true; - } - - if ($this->matchEscapeCharacter($escapedout, true)) { - if (strlen($escapedout) === 1) { - if (!preg_match(",\w,", $escapedout)) { - $out = '\\' . $escapedout; - return true; - } elseif (! $keepEscapedNumber || ! \is_numeric($escapedout)) { - $out = $escapedout; - return true; - } - } - $escape_sequence = rtrim(substr($this->buffer, $s_escape, $this->count - $s_escape)); - if (strlen($escape_sequence) < 6) { - $escape_sequence .= ' '; - } - $out = '\\' . strtolower($escape_sequence); - return true; - } - if ($this->match('\\S', $m)) { - $out = '\\' . $m[0]; - return true; - } - - - return false; - } - - /** - * Parse the parts that make up a selector - * - * {@internal - * div[yes=no]#something.hello.world:nth-child(-2n+1)%placeholder - * }} - * - * @param array $out - * @param string|bool $subSelector - * - * @return bool - */ - protected function selectorSingle(&$out, $subSelector = false) - { - $oldWhite = $this->eatWhiteDefault; - $this->eatWhiteDefault = false; - - $parts = []; - - if ($this->matchChar('*', false)) { - $parts[] = '*'; - } - - for (;;) { - if (! isset($this->buffer[$this->count])) { - break; - } - - $s = $this->count; - $char = $this->buffer[$this->count]; - - // see if we can stop early - if ($char === '{' || $char === ',' || $char === ';' || $char === '}' || $char === '@') { - break; - } - - // parsing a sub selector in () stop with the closing ) - if ($subSelector && $char === ')') { - break; - } - - //self - switch ($char) { - case '&': - $parts[] = Compiler::$selfSelector; - $this->count++; - ! $this->cssOnly || $this->assertPlainCssValid(false, $s); - continue 2; - - case '.': - $parts[] = '.'; - $this->count++; - continue 2; - - case '|': - $parts[] = '|'; - $this->count++; - continue 2; - } - - // handling of escaping in selectors : get the escaped char - if ($char === '\\') { - $this->count++; - if ($this->matchEscapeCharacterInSelector($escaped, true)) { - $parts[] = $escaped; - continue; - } - $this->count--; - } - - if ($char === '%') { - $this->count++; - - if ($this->placeholder($placeholder)) { - $parts[] = '%'; - $parts[] = $placeholder; - ! $this->cssOnly || $this->assertPlainCssValid(false, $s); - continue; - } - - break; - } - - if ($char === '#') { - if ($this->interpolation($inter)) { - $parts[] = $inter; - ! $this->cssOnly || $this->assertPlainCssValid(false, $s); - continue; - } - - $parts[] = '#'; - $this->count++; - continue; - } - - // a pseudo selector - if ($char === ':') { - if ($this->buffer[$this->count + 1] === ':') { - $this->count += 2; - $part = '::'; - } else { - $this->count++; - $part = ':'; - } - - if ($this->mixedKeyword($nameParts, true)) { - $parts[] = $part; - - foreach ($nameParts as $sub) { - $parts[] = $sub; - } - - $ss = $this->count; - - if ( - $nameParts === ['not'] || - $nameParts === ['is'] || - $nameParts === ['has'] || - $nameParts === ['where'] || - $nameParts === ['slotted'] || - $nameParts === ['nth-child'] || - $nameParts === ['nth-last-child'] || - $nameParts === ['nth-of-type'] || - $nameParts === ['nth-last-of-type'] - ) { - if ( - $this->matchChar('(', true) && - ($this->selectors($subs, reset($nameParts)) || true) && - $this->matchChar(')') - ) { - $parts[] = '('; - - while ($sub = array_shift($subs)) { - while ($ps = array_shift($sub)) { - foreach ($ps as &$p) { - $parts[] = $p; - } - - if (\count($sub) && reset($sub)) { - $parts[] = ' '; - } - } - - if (\count($subs) && reset($subs)) { - $parts[] = ', '; - } - } - - $parts[] = ')'; - } else { - $this->seek($ss); - } - } elseif ( - $this->matchChar('(', true) && - ($this->openString(')', $str, '(') || true) && - $this->matchChar(')') - ) { - $parts[] = '('; - - if (! empty($str)) { - $parts[] = $str; - } - - $parts[] = ')'; - } else { - $this->seek($ss); - } - - continue; - } - } - - $this->seek($s); - - // 2n+1 - if ($subSelector && \is_string($subSelector) && strpos($subSelector, 'nth-') === 0) { - if ($this->match("(\s*(\+\s*|\-\s*)?(\d+|n|\d+n))+", $counter)) { - $parts[] = $counter[0]; - //$parts[] = str_replace(' ', '', $counter[0]); - continue; - } - } - - $this->seek($s); - - // attribute selector - if ( - $char === '[' && - $this->matchChar('[') && - ($this->openString(']', $str, '[') || true) && - $this->matchChar(']') - ) { - $parts[] = '['; - - if (! empty($str)) { - $parts[] = $str; - } - - $parts[] = ']'; - continue; - } - - $this->seek($s); - - // for keyframes - if ($this->unit($unit)) { - $parts[] = $unit; - continue; - } - - if ($this->restrictedKeyword($name, false, true)) { - $parts[] = $name; - continue; - } - - break; - } - - $this->eatWhiteDefault = $oldWhite; - - if (! $parts) { - return false; - } - - $out = $parts; - - return true; - } - - /** - * Parse a variable - * - * @param mixed $out - * @param-out array{Type::*, string} $out - * - * @return bool - */ - protected function variable(&$out) - { - $s = $this->count; - - if ( - $this->matchChar('$', false) && - $this->keyword($name) - ) { - if ($this->allowVars) { - $out = [Type::T_VARIABLE, $name]; - } else { - $out = [Type::T_KEYWORD, '$' . $name]; - } - - return true; - } - - $this->seek($s); - - return false; - } - - /** - * Parse a keyword - * - * @param mixed $word - * @param bool $eatWhitespace - * @param bool $inSelector - * @param-out string $word - * - * @return bool - */ - protected function keyword(&$word, $eatWhitespace = null, $inSelector = false) - { - $s = $this->count; - $match = $this->match( - $this->utf8 - ? '(([\pL\w\x{00A0}-\x{10FFFF}_\-\*!"\']|\\\\[a-f0-9]{6} ?|\\\\[a-f0-9]{1,5}(?![a-f0-9]) ?|[\\\\].)([\pL\w\x{00A0}-\x{10FFFF}\-_"\']|\\\\[a-f0-9]{6} ?|\\\\[a-f0-9]{1,5}(?![a-f0-9]) ?|[\\\\].)*)' - : '(([\w_\-\*!"\']|\\\\[a-f0-9]{6} ?|\\\\[a-f0-9]{1,5}(?![a-f0-9]) ?|[\\\\].)([\w\-_"\']|\\\\[a-f0-9]{6} ?|\\\\[a-f0-9]{1,5}(?![a-f0-9]) ?|[\\\\].)*)', - $m, - false - ); - - if ($match) { - $word = $m[1]; - - // handling of escaping in keyword : get the escaped char - if (strpos($word, '\\') !== false) { - $send = $this->count; - $escapedWord = []; - $this->seek($s); - $previousEscape = false; - while ($this->count < $send) { - $char = $this->buffer[$this->count]; - $this->count++; - if ( - $this->count < $send - && $char === '\\' - && !$previousEscape - && ( - $inSelector ? - $this->matchEscapeCharacterInSelector($out) - : - $this->matchEscapeCharacter($out, true) - ) - ) { - $escapedWord[] = $out; - } else { - if ($previousEscape) { - $previousEscape = false; - } elseif ($char === '\\') { - $previousEscape = true; - } - $escapedWord[] = $char; - } - } - - $word = implode('', $escapedWord); - } - - if (is_null($eatWhitespace) ? $this->eatWhiteDefault : $eatWhitespace) { - $this->whitespace(); - } - - return true; - } - - return false; - } - - /** - * Parse a keyword that should not start with a number - * - * @param string $word - * @param bool $eatWhitespace - * @param bool $inSelector - * - * @return bool - */ - protected function restrictedKeyword(&$word, $eatWhitespace = null, $inSelector = false) - { - $s = $this->count; - - if ($this->keyword($word, $eatWhitespace, $inSelector) && (\ord($word[0]) > 57 || \ord($word[0]) < 48)) { - return true; - } - - $this->seek($s); - - return false; - } - - /** - * Parse a placeholder - * - * @param string|array $placeholder - * - * @return bool - */ - protected function placeholder(&$placeholder) - { - $match = $this->match( - $this->utf8 - ? '([\pL\w\-_]+)' - : '([\w\-_]+)', - $m - ); - - if ($match) { - $placeholder = $m[1]; - - return true; - } - - if ($this->interpolation($placeholder)) { - return true; - } - - return false; - } - - /** - * Parse a url - * - * @param mixed $out - * @param-out array $out - * - * @return bool - */ - protected function url(&$out) - { - if ($this->literal('url(', 4)) { - $s = $this->count; - - if ( - ($this->string($inner) || $this->spaceList($inner)) && - $this->matchChar(')') - ) { - $out = [Type::T_STRING, '', ['url(', $inner, ')']]; - - return true; - } - - $this->seek($s); - - if ( - $this->openString(')', $out) && - $this->matchChar(')') - ) { - $out = [Type::T_STRING, '', ['url(', $out, ')']]; - - return true; - } - } - - return false; - } - - /** - * Consume an end of statement delimiter - * @param bool $eatWhitespace - * - * @return bool - */ - protected function end($eatWhitespace = null) - { - if ($this->matchChar(';', $eatWhitespace)) { - return true; - } - - if ($this->count === \strlen($this->buffer) || $this->buffer[$this->count] === '}') { - // if there is end of file or a closing block next then we don't need a ; - return true; - } - - return false; - } - - /** - * Strip assignment flag from the list - * - * @param array|Number $value - * - * @return string[] - */ - protected function stripAssignmentFlags(&$value) - { - $flags = []; - - for ($token = &$value; $token[0] === Type::T_LIST && ($s = \count($token[2])); $token = &$lastNode) { - $lastNode = &$token[2][$s - 1]; - - while ($lastNode[0] === Type::T_KEYWORD && \in_array($lastNode[1], ['!default', '!global'])) { - array_pop($token[2]); - - $node = end($token[2]); - $token = $this->flattenList($token); - $flags[] = $lastNode[1]; - $lastNode = $node; - } - } - - return $flags; - } - - /** - * Strip optional flag from selector list - * - * @param array $selectors - * - * @return bool - */ - protected function stripOptionalFlag(&$selectors) - { - $optional = false; - $selector = end($selectors); - $part = end($selector); - - if ($part === ['!optional']) { - array_pop($selectors[\count($selectors) - 1]); - - $optional = true; - } - - return $optional; - } - - /** - * Turn list of length 1 into value type - * - * @param array $value - * - * @return array - */ - protected function flattenList($value) - { - if ($value[0] === Type::T_LIST && \count($value[2]) === 1) { - return $this->flattenList($value[2][0]); - } - - return $value; - } - - /** - * Quote regular expression - * - * @param string $what - * - * @return string - */ - private function pregQuote($what) - { - return preg_quote($what, '/'); - } - - /** - * Extract line numbers from buffer - * - * @param string $buffer - * - * @return void - */ - private function extractLineNumbers($buffer) - { - $this->sourcePositions = [0 => 0]; - $prev = 0; - - while (($pos = strpos($buffer, "\n", $prev)) !== false) { - $this->sourcePositions[] = $pos; - $prev = $pos + 1; - } - - $this->sourcePositions[] = \strlen($buffer); - - if (substr($buffer, -1) !== "\n") { - $this->sourcePositions[] = \strlen($buffer) + 1; - } - } - - /** - * Get source line number and column (given character position in the buffer) - * - * @param int $pos - * - * @return array - * @phpstan-return array{int, int} - */ - private function getSourcePosition($pos) - { - $low = 0; - $high = \count($this->sourcePositions); - - while ($low < $high) { - $mid = (int) (($high + $low) / 2); - - if ($pos < $this->sourcePositions[$mid]) { - $high = $mid - 1; - continue; - } - - if ($pos >= $this->sourcePositions[$mid + 1]) { - $low = $mid + 1; - continue; - } - - return [$mid + 1, $pos - $this->sourcePositions[$mid]]; - } - - return [$low + 1, $pos - $this->sourcePositions[$low]]; - } - - /** - * Save internal encoding of mbstring - * - * When mbstring.func_overload is used to replace the standard PHP string functions, - * this method configures the internal encoding to a single-byte one so that the - * behavior matches the normal behavior of PHP string functions while using the parser. - * The existing internal encoding is saved and will be restored when calling {@see restoreEncoding}. - * - * If mbstring.func_overload is not used (or does not override string functions), this method is a no-op. - * - * @return void - */ - private function saveEncoding() - { - if (\PHP_VERSION_ID < 80000 && \extension_loaded('mbstring') && (2 & (int) ini_get('mbstring.func_overload')) > 0) { - $this->encoding = mb_internal_encoding(); - - mb_internal_encoding('iso-8859-1'); - } - } - - /** - * Restore internal encoding - * - * @return void - */ - private function restoreEncoding() - { - if (\extension_loaded('mbstring') && $this->encoding) { - mb_internal_encoding($this->encoding); - } - } -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/SourceMap/Base64.php b/plugins/admin/vendor/scssphp/scssphp/src/SourceMap/Base64.php deleted file mode 100644 index 00b6b45..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/SourceMap/Base64.php +++ /dev/null @@ -1,187 +0,0 @@ - - * - * @internal - */ -class Base64 -{ - /** - * @var array - */ - private static $encodingMap = [ - 0 => 'A', - 1 => 'B', - 2 => 'C', - 3 => 'D', - 4 => 'E', - 5 => 'F', - 6 => 'G', - 7 => 'H', - 8 => 'I', - 9 => 'J', - 10 => 'K', - 11 => 'L', - 12 => 'M', - 13 => 'N', - 14 => 'O', - 15 => 'P', - 16 => 'Q', - 17 => 'R', - 18 => 'S', - 19 => 'T', - 20 => 'U', - 21 => 'V', - 22 => 'W', - 23 => 'X', - 24 => 'Y', - 25 => 'Z', - 26 => 'a', - 27 => 'b', - 28 => 'c', - 29 => 'd', - 30 => 'e', - 31 => 'f', - 32 => 'g', - 33 => 'h', - 34 => 'i', - 35 => 'j', - 36 => 'k', - 37 => 'l', - 38 => 'm', - 39 => 'n', - 40 => 'o', - 41 => 'p', - 42 => 'q', - 43 => 'r', - 44 => 's', - 45 => 't', - 46 => 'u', - 47 => 'v', - 48 => 'w', - 49 => 'x', - 50 => 'y', - 51 => 'z', - 52 => '0', - 53 => '1', - 54 => '2', - 55 => '3', - 56 => '4', - 57 => '5', - 58 => '6', - 59 => '7', - 60 => '8', - 61 => '9', - 62 => '+', - 63 => '/', - ]; - - /** - * @var array - */ - private static $decodingMap = [ - 'A' => 0, - 'B' => 1, - 'C' => 2, - 'D' => 3, - 'E' => 4, - 'F' => 5, - 'G' => 6, - 'H' => 7, - 'I' => 8, - 'J' => 9, - 'K' => 10, - 'L' => 11, - 'M' => 12, - 'N' => 13, - 'O' => 14, - 'P' => 15, - 'Q' => 16, - 'R' => 17, - 'S' => 18, - 'T' => 19, - 'U' => 20, - 'V' => 21, - 'W' => 22, - 'X' => 23, - 'Y' => 24, - 'Z' => 25, - 'a' => 26, - 'b' => 27, - 'c' => 28, - 'd' => 29, - 'e' => 30, - 'f' => 31, - 'g' => 32, - 'h' => 33, - 'i' => 34, - 'j' => 35, - 'k' => 36, - 'l' => 37, - 'm' => 38, - 'n' => 39, - 'o' => 40, - 'p' => 41, - 'q' => 42, - 'r' => 43, - 's' => 44, - 't' => 45, - 'u' => 46, - 'v' => 47, - 'w' => 48, - 'x' => 49, - 'y' => 50, - 'z' => 51, - 0 => 52, - 1 => 53, - 2 => 54, - 3 => 55, - 4 => 56, - 5 => 57, - 6 => 58, - 7 => 59, - 8 => 60, - 9 => 61, - '+' => 62, - '/' => 63, - ]; - - /** - * Convert to base64 - * - * @param int $value - * - * @return string - */ - public static function encode($value) - { - return self::$encodingMap[$value]; - } - - /** - * Convert from base64 - * - * @param string $value - * - * @return int - */ - public static function decode($value) - { - return self::$decodingMap[$value]; - } -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/SourceMap/Base64VLQ.php b/plugins/admin/vendor/scssphp/scssphp/src/SourceMap/Base64VLQ.php deleted file mode 100644 index 2a5210c..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/SourceMap/Base64VLQ.php +++ /dev/null @@ -1,151 +0,0 @@ - - * @author Anthon Pang - * - * @internal - */ -class Base64VLQ -{ - // A Base64 VLQ digit can represent 5 bits, so it is base-32. - const VLQ_BASE_SHIFT = 5; - - // A mask of bits for a VLQ digit (11111), 31 decimal. - const VLQ_BASE_MASK = 31; - - // The continuation bit is the 6th bit. - const VLQ_CONTINUATION_BIT = 32; - - /** - * Returns the VLQ encoded value. - * - * @param int $value - * - * @return string - */ - public static function encode($value) - { - $encoded = ''; - $vlq = self::toVLQSigned($value); - - do { - $digit = $vlq & self::VLQ_BASE_MASK; - - //$vlq >>>= self::VLQ_BASE_SHIFT; // unsigned right shift - $vlq = (($vlq >> 1) & PHP_INT_MAX) >> (self::VLQ_BASE_SHIFT - 1); - - if ($vlq > 0) { - $digit |= self::VLQ_CONTINUATION_BIT; - } - - $encoded .= Base64::encode($digit); - } while ($vlq > 0); - - return $encoded; - } - - /** - * Decodes VLQValue. - * - * @param string $str - * @param int $index - * - * @return int - */ - public static function decode($str, &$index) - { - $result = 0; - $shift = 0; - - do { - $c = $str[$index++]; - $digit = Base64::decode($c); - $continuation = ($digit & self::VLQ_CONTINUATION_BIT) != 0; - $digit &= self::VLQ_BASE_MASK; - $result = $result + ($digit << $shift); - $shift = $shift + self::VLQ_BASE_SHIFT; - } while ($continuation); - - return self::fromVLQSigned($result); - } - - /** - * Converts from a two-complement value to a value where the sign bit is - * is placed in the least significant bit. For example, as decimals: - * 1 becomes 2 (10 binary), -1 becomes 3 (11 binary) - * 2 becomes 4 (100 binary), -2 becomes 5 (101 binary) - * - * @param int $value - * - * @return int - */ - private static function toVLQSigned($value) - { - if ($value < 0) { - return ((-$value) << 1) + 1; - } - - return ($value << 1) + 0; - } - - /** - * Converts to a two-complement value from a value where the sign bit is - * is placed in the least significant bit. For example, as decimals: - * 2 (10 binary) becomes 1, 3 (11 binary) becomes -1 - * 4 (100 binary) becomes 2, 5 (101 binary) becomes -2 - * - * @param int $value - * - * @return int - */ - private static function fromVLQSigned($value) - { - $negate = ($value & 1) === 1; - - //$value >>>= 1; // unsigned right shift - $value = ($value >> 1) & PHP_INT_MAX; - - if (! $negate) { - return $value; - } - - // We need to OR 0x80000000 here to ensure the 32nd bit (the sign bit) is - // always set for negative numbers. If `value` were 1, (meaning `negate` is - // true and all other bits were zeros), `value` would now be 0. -0 is just - // 0, and doesn't flip the 32nd bit as intended. All positive numbers will - // successfully flip the 32nd bit without issue, so it's a noop for them. - return -$value | 0x80000000; - } -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/SourceMap/SourceMapGenerator.php b/plugins/admin/vendor/scssphp/scssphp/src/SourceMap/SourceMapGenerator.php deleted file mode 100644 index ccd4f02..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/SourceMap/SourceMapGenerator.php +++ /dev/null @@ -1,390 +0,0 @@ - - * @author Nicolas FRANÇOIS - * - * @internal - */ -class SourceMapGenerator -{ - /** - * What version of source map does the generator generate? - */ - const VERSION = 3; - - /** - * Array of default options - * - * @var array - * @phpstan-var array{sourceRoot: string, sourceMapFilename: string|null, sourceMapURL: string|null, sourceMapWriteTo: string|null, outputSourceFiles: bool, sourceMapRootpath: string, sourceMapBasepath: string} - */ - protected $defaultOptions = [ - // an optional source root, useful for relocating source files - // on a server or removing repeated values in the 'sources' entry. - // This value is prepended to the individual entries in the 'source' field. - 'sourceRoot' => '', - - // an optional name of the generated code that this source map is associated with. - 'sourceMapFilename' => null, - - // url of the map - 'sourceMapURL' => null, - - // absolute path to a file to write the map to - 'sourceMapWriteTo' => null, - - // output source contents? - 'outputSourceFiles' => false, - - // base path for filename normalization - 'sourceMapRootpath' => '', - - // base path for filename normalization - 'sourceMapBasepath' => '' - ]; - - /** - * The base64 VLQ encoder - * - * @var \ScssPhp\ScssPhp\SourceMap\Base64VLQ - */ - protected $encoder; - - /** - * Array of mappings - * - * @var array - * @phpstan-var list - */ - protected $mappings = []; - - /** - * Array of contents map - * - * @var array - */ - protected $contentsMap = []; - - /** - * File to content map - * - * @var array - */ - protected $sources = []; - - /** - * @var array - */ - protected $sourceKeys = []; - - /** - * @var array - * @phpstan-var array{sourceRoot: string, sourceMapFilename: string|null, sourceMapURL: string|null, sourceMapWriteTo: string|null, outputSourceFiles: bool, sourceMapRootpath: string, sourceMapBasepath: string} - */ - private $options; - - /** - * @phpstan-param array{sourceRoot?: string, sourceMapFilename?: string|null, sourceMapURL?: string|null, sourceMapWriteTo?: string|null, outputSourceFiles?: bool, sourceMapRootpath?: string, sourceMapBasepath?: string} $options - */ - public function __construct(array $options = []) - { - $this->options = array_replace($this->defaultOptions, $options); - $this->encoder = new Base64VLQ(); - } - - /** - * Adds a mapping - * - * @param int $generatedLine The line number in generated file - * @param int $generatedColumn The column number in generated file - * @param int $originalLine The line number in original file - * @param int $originalColumn The column number in original file - * @param string $sourceFile The original source file - * - * @return void - */ - public function addMapping($generatedLine, $generatedColumn, $originalLine, $originalColumn, $sourceFile) - { - $this->mappings[] = [ - 'generated_line' => $generatedLine, - 'generated_column' => $generatedColumn, - 'original_line' => $originalLine, - 'original_column' => $originalColumn, - 'source_file' => $sourceFile - ]; - - $this->sources[$sourceFile] = $sourceFile; - } - - /** - * Saves the source map to a file - * - * @param string $content The content to write - * - * @return string|null - * - * @throws \ScssPhp\ScssPhp\Exception\CompilerException If the file could not be saved - * @deprecated - */ - public function saveMap($content) - { - $file = $this->options['sourceMapWriteTo']; - assert($file !== null); - $dir = \dirname($file); - - // directory does not exist - if (! is_dir($dir)) { - // FIXME: create the dir automatically? - throw new CompilerException( - sprintf('The directory "%s" does not exist. Cannot save the source map.', $dir) - ); - } - - // FIXME: proper saving, with dir write check! - if (file_put_contents($file, $content) === false) { - throw new CompilerException(sprintf('Cannot save the source map to "%s"', $file)); - } - - return $this->options['sourceMapURL']; - } - - /** - * Generates the JSON source map - * - * @param string $prefix A prefix added in the output file, which needs to shift mappings - * - * @return string - * - * @see https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit# - */ - public function generateJson($prefix = '') - { - $sourceMap = []; - $mappings = $this->generateMappings($prefix); - - // File version (always the first entry in the object) and must be a positive integer. - $sourceMap['version'] = self::VERSION; - - // An optional name of the generated code that this source map is associated with. - $file = $this->options['sourceMapFilename']; - - if ($file) { - $sourceMap['file'] = $file; - } - - // An optional source root, useful for relocating source files on a server or removing repeated values in the - // 'sources' entry. This value is prepended to the individual entries in the 'source' field. - $root = $this->options['sourceRoot']; - - if ($root) { - $sourceMap['sourceRoot'] = $root; - } - - // A list of original sources used by the 'mappings' entry. - $sourceMap['sources'] = []; - - foreach ($this->sources as $sourceFilename) { - $sourceMap['sources'][] = $this->normalizeFilename($sourceFilename); - } - - // A list of symbol names used by the 'mappings' entry. - $sourceMap['names'] = []; - - // A string with the encoded mapping data. - $sourceMap['mappings'] = $mappings; - - if ($this->options['outputSourceFiles']) { - // An optional list of source content, useful when the 'source' can't be hosted. - // The contents are listed in the same order as the sources above. - // 'null' may be used if some original sources should be retrieved by name. - $sourceMap['sourcesContent'] = $this->getSourcesContent(); - } - - // less.js compat fixes - if (\count($sourceMap['sources']) && empty($sourceMap['sourceRoot'])) { - unset($sourceMap['sourceRoot']); - } - - $jsonSourceMap = json_encode($sourceMap, JSON_UNESCAPED_SLASHES); - - if (json_last_error() !== JSON_ERROR_NONE) { - throw new \RuntimeException(json_last_error_msg()); - } - - assert($jsonSourceMap !== false); - - return $jsonSourceMap; - } - - /** - * Returns the sources contents - * - * @return string[]|null - */ - protected function getSourcesContent() - { - if (empty($this->sources)) { - return null; - } - - $content = []; - - foreach ($this->sources as $sourceFile) { - $content[] = file_get_contents($sourceFile); - } - - return $content; - } - - /** - * Generates the mappings string - * - * @param string $prefix A prefix added in the output file, which needs to shift mappings - * - * @return string - */ - public function generateMappings($prefix = '') - { - if (! \count($this->mappings)) { - return ''; - } - - $prefixLines = substr_count($prefix, "\n"); - $lastPrefixNewLine = strrpos($prefix, "\n"); - $lastPrefixLineStart = false === $lastPrefixNewLine ? 0 : $lastPrefixNewLine + 1; - $prefixColumn = strlen($prefix) - $lastPrefixLineStart; - - $this->sourceKeys = array_flip(array_keys($this->sources)); - - // group mappings by generated line number. - $groupedMap = $groupedMapEncoded = []; - - foreach ($this->mappings as $m) { - $groupedMap[$m['generated_line']][] = $m; - } - - ksort($groupedMap); - - $lastGeneratedLine = $lastOriginalIndex = $lastOriginalLine = $lastOriginalColumn = 0; - - foreach ($groupedMap as $lineNumber => $lineMap) { - if ($lineNumber > 1) { - // The prefix only impacts the column for the first line of the original output - $prefixColumn = 0; - } - $lineNumber += $prefixLines; - - while (++$lastGeneratedLine < $lineNumber) { - $groupedMapEncoded[] = ';'; - } - - $lineMapEncoded = []; - $lastGeneratedColumn = 0; - - foreach ($lineMap as $m) { - $generatedColumn = $m['generated_column'] + $prefixColumn; - - $mapEncoded = $this->encoder->encode($generatedColumn - $lastGeneratedColumn); - $lastGeneratedColumn = $generatedColumn; - - // find the index - if ($m['source_file']) { - $index = $this->findFileIndex($m['source_file']); - - if ($index !== false) { - $mapEncoded .= $this->encoder->encode($index - $lastOriginalIndex); - $lastOriginalIndex = $index; - // lines are stored 0-based in SourceMap spec version 3 - $mapEncoded .= $this->encoder->encode($m['original_line'] - 1 - $lastOriginalLine); - $lastOriginalLine = $m['original_line'] - 1; - $mapEncoded .= $this->encoder->encode($m['original_column'] - $lastOriginalColumn); - $lastOriginalColumn = $m['original_column']; - } - } - - $lineMapEncoded[] = $mapEncoded; - } - - $groupedMapEncoded[] = implode(',', $lineMapEncoded) . ';'; - } - - return rtrim(implode($groupedMapEncoded), ';'); - } - - /** - * Finds the index for the filename - * - * @param string $filename - * - * @return int|false - */ - protected function findFileIndex($filename) - { - return $this->sourceKeys[$filename]; - } - - /** - * Normalize filename - * - * @param string $filename - * - * @return string - */ - protected function normalizeFilename($filename) - { - $filename = $this->fixWindowsPath($filename); - $rootpath = $this->options['sourceMapRootpath']; - $basePath = $this->options['sourceMapBasepath']; - - // "Trim" the 'sourceMapBasepath' from the output filename. - if (\strlen($basePath) && strpos($filename, $basePath) === 0) { - $filename = substr($filename, \strlen($basePath)); - } - - // Remove extra leading path separators. - if (strpos($filename, '\\') === 0 || strpos($filename, '/') === 0) { - $filename = substr($filename, 1); - } - - return $rootpath . $filename; - } - - /** - * Fix windows paths - * - * @param string $path - * @param bool $addEndSlash - * - * @return string - */ - public function fixWindowsPath($path, $addEndSlash = false) - { - $slash = ($addEndSlash) ? '/' : ''; - - if (! empty($path)) { - $path = str_replace('\\', '/', $path); - $path = rtrim($path, '/') . $slash; - } - - return $path; - } -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Type.php b/plugins/admin/vendor/scssphp/scssphp/src/Type.php deleted file mode 100644 index 2f8ab65..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/Type.php +++ /dev/null @@ -1,211 +0,0 @@ - - */ -class Type -{ - /** - * @internal - */ - const T_ASSIGN = 'assign'; - /** - * @internal - */ - const T_AT_ROOT = 'at-root'; - /** - * @internal - */ - const T_BLOCK = 'block'; - /** - * @deprecated - * @internal - */ - const T_BREAK = 'break'; - /** - * @internal - */ - const T_CHARSET = 'charset'; - const T_COLOR = 'color'; - /** - * @internal - */ - const T_COMMENT = 'comment'; - /** - * @deprecated - * @internal - */ - const T_CONTINUE = 'continue'; - /** - * @deprecated - * @internal - */ - const T_CONTROL = 'control'; - /** - * @internal - */ - const T_CUSTOM_PROPERTY = 'custom'; - /** - * @internal - */ - const T_DEBUG = 'debug'; - /** - * @internal - */ - const T_DIRECTIVE = 'directive'; - /** - * @internal - */ - const T_EACH = 'each'; - /** - * @internal - */ - const T_ELSE = 'else'; - /** - * @internal - */ - const T_ELSEIF = 'elseif'; - /** - * @internal - */ - const T_ERROR = 'error'; - /** - * @internal - */ - const T_EXPRESSION = 'exp'; - /** - * @internal - */ - const T_EXTEND = 'extend'; - /** - * @internal - */ - const T_FOR = 'for'; - /** - * @internal - */ - const T_FUNCTION = 'function'; - /** - * @internal - */ - const T_FUNCTION_REFERENCE = 'function-reference'; - /** - * @internal - */ - const T_FUNCTION_CALL = 'fncall'; - /** - * @internal - */ - const T_HSL = 'hsl'; - /** - * @internal - */ - const T_HWB = 'hwb'; - /** - * @internal - */ - const T_IF = 'if'; - /** - * @internal - */ - const T_IMPORT = 'import'; - /** - * @internal - */ - const T_INCLUDE = 'include'; - /** - * @internal - */ - const T_INTERPOLATE = 'interpolate'; - /** - * @internal - */ - const T_INTERPOLATED = 'interpolated'; - /** - * @internal - */ - const T_KEYWORD = 'keyword'; - const T_LIST = 'list'; - const T_MAP = 'map'; - /** - * @internal - */ - const T_MEDIA = 'media'; - /** - * @internal - */ - const T_MEDIA_EXPRESSION = 'mediaExp'; - /** - * @internal - */ - const T_MEDIA_TYPE = 'mediaType'; - /** - * @internal - */ - const T_MEDIA_VALUE = 'mediaValue'; - /** - * @internal - */ - const T_MIXIN = 'mixin'; - /** - * @internal - */ - const T_MIXIN_CONTENT = 'mixin_content'; - /** - * @internal - */ - const T_NESTED_PROPERTY = 'nestedprop'; - /** - * @internal - */ - const T_NOT = 'not'; - const T_NULL = 'null'; - const T_NUMBER = 'number'; - /** - * @internal - */ - const T_RETURN = 'return'; - /** - * @internal - */ - const T_ROOT = 'root'; - /** - * @internal - */ - const T_SCSSPHP_IMPORT_ONCE = 'scssphp-import-once'; - /** - * @internal - */ - const T_SELF = 'self'; - const T_STRING = 'string'; - /** - * @internal - */ - const T_UNARY = 'unary'; - /** - * @internal - */ - const T_VARIABLE = 'var'; - /** - * @internal - */ - const T_WARN = 'warn'; - /** - * @internal - */ - const T_WHILE = 'while'; -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Util.php b/plugins/admin/vendor/scssphp/scssphp/src/Util.php deleted file mode 100644 index ad608ce..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/Util.php +++ /dev/null @@ -1,184 +0,0 @@ - - * - * @internal - */ -class Util -{ - /** - * Asserts that `value` falls within `range` (inclusive), leaving - * room for slight floating-point errors. - * - * @param string $name The name of the value. Used in the error message. - * @param Range $range Range of values. - * @param array|Number $value The value to check. - * @param string $unit The unit of the value. Used in error reporting. - * - * @return mixed `value` adjusted to fall within range, if it was outside by a floating-point margin. - * - * @throws \ScssPhp\ScssPhp\Exception\RangeException - */ - public static function checkRange($name, Range $range, $value, $unit = '') - { - $val = $value[1]; - $grace = new Range(-0.00001, 0.00001); - - if (! \is_numeric($val)) { - throw new RangeException("$name {$val} is not a number."); - } - - if ($range->includes($val)) { - return $val; - } - - if ($grace->includes($val - $range->first)) { - return $range->first; - } - - if ($grace->includes($val - $range->last)) { - return $range->last; - } - - throw new RangeException("$name {$val} must be between {$range->first} and {$range->last}$unit"); - } - - /** - * Encode URI component - * - * @param string $string - * - * @return string - */ - public static function encodeURIComponent($string) - { - $revert = ['%21' => '!', '%2A' => '*', '%27' => "'", '%28' => '(', '%29' => ')']; - - return strtr(rawurlencode($string), $revert); - } - - /** - * mb_chr() wrapper - * - * @param int $code - * - * @return string - */ - public static function mbChr($code) - { - // Use the native implementation if available, but not on PHP 7.2 as mb_chr(0) is buggy there - if (\PHP_VERSION_ID > 70300 && \function_exists('mb_chr')) { - return mb_chr($code, 'UTF-8'); - } - - if (0x80 > $code %= 0x200000) { - $s = \chr($code); - } elseif (0x800 > $code) { - $s = \chr(0xC0 | $code >> 6) . \chr(0x80 | $code & 0x3F); - } elseif (0x10000 > $code) { - $s = \chr(0xE0 | $code >> 12) . \chr(0x80 | $code >> 6 & 0x3F) . \chr(0x80 | $code & 0x3F); - } else { - $s = \chr(0xF0 | $code >> 18) . \chr(0x80 | $code >> 12 & 0x3F) - . \chr(0x80 | $code >> 6 & 0x3F) . \chr(0x80 | $code & 0x3F); - } - - return $s; - } - - /** - * mb_strlen() wrapper - * - * @param string $string - * @return int - */ - public static function mbStrlen($string) - { - // Use the native implementation if available. - if (\function_exists('mb_strlen')) { - return mb_strlen($string, 'UTF-8'); - } - - if (\function_exists('iconv_strlen')) { - return (int) @iconv_strlen($string, 'UTF-8'); - } - - throw new \LogicException('Either mbstring (recommended) or iconv is necessary to use Scssphp.'); - } - - /** - * mb_substr() wrapper - * @param string $string - * @param int $start - * @param null|int $length - * @return string - */ - public static function mbSubstr($string, $start, $length = null) - { - // Use the native implementation if available. - if (\function_exists('mb_substr')) { - return mb_substr($string, $start, $length, 'UTF-8'); - } - - if (\function_exists('iconv_substr')) { - if ($start < 0) { - $start = static::mbStrlen($string) + $start; - if ($start < 0) { - $start = 0; - } - } - - if (null === $length) { - $length = 2147483647; - } elseif ($length < 0) { - $length = static::mbStrlen($string) + $length - $start; - if ($length < 0) { - return ''; - } - } - - return (string)iconv_substr($string, $start, $length, 'UTF-8'); - } - - throw new \LogicException('Either mbstring (recommended) or iconv is necessary to use Scssphp.'); - } - - /** - * mb_strpos wrapper - * @param string $haystack - * @param string $needle - * @param int $offset - * - * @return int|false - */ - public static function mbStrpos($haystack, $needle, $offset = 0) - { - if (\function_exists('mb_strpos')) { - return mb_strpos($haystack, $needle, $offset, 'UTF-8'); - } - - if (\function_exists('iconv_strpos')) { - return iconv_strpos($haystack, $needle, $offset, 'UTF-8'); - } - - throw new \LogicException('Either mbstring (recommended) or iconv is necessary to use Scssphp.'); - } -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Util/Path.php b/plugins/admin/vendor/scssphp/scssphp/src/Util/Path.php deleted file mode 100644 index f399e41..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/Util/Path.php +++ /dev/null @@ -1,77 +0,0 @@ -parseValue($source, $value)) { - throw new \InvalidArgumentException(sprintf('Invalid value source "%s".', $source)); - } - - return $value; - } - - /** - * Converts a PHP value to a Sass value - * - * The returned value is guaranteed to be supported by the - * Compiler methods for registering custom variables. No other - * guarantee about it is provided. It should be considered - * opaque values by the caller. - * - * @param mixed $value - * - * @return mixed - */ - public static function fromPhp($value) - { - if ($value instanceof Number) { - return $value; - } - - if (is_array($value) && isset($value[0]) && \in_array($value[0], [Type::T_NULL, Type::T_COLOR, Type::T_KEYWORD, Type::T_LIST, Type::T_MAP, Type::T_STRING])) { - return $value; - } - - if ($value === null) { - return Compiler::$null; - } - - if ($value === true) { - return Compiler::$true; - } - - if ($value === false) { - return Compiler::$false; - } - - if ($value === '') { - return Compiler::$emptyString; - } - - if (\is_int($value) || \is_float($value)) { - return new Number($value, ''); - } - - if (\is_string($value)) { - return [Type::T_STRING, '"', [$value]]; - } - - throw new \InvalidArgumentException(sprintf('Cannot convert the value of type "%s" to a Sass value.', gettype($value))); - } -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Version.php b/plugins/admin/vendor/scssphp/scssphp/src/Version.php deleted file mode 100644 index 45fc983..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/Version.php +++ /dev/null @@ -1,23 +0,0 @@ - - */ -class Version -{ - const VERSION = '1.13.0'; -} diff --git a/plugins/admin/vendor/scssphp/scssphp/src/Warn.php b/plugins/admin/vendor/scssphp/scssphp/src/Warn.php deleted file mode 100644 index 592b44c..0000000 --- a/plugins/admin/vendor/scssphp/scssphp/src/Warn.php +++ /dev/null @@ -1,84 +0,0 @@ -original_width = $size[0]; - $this->original_height = $size[1]; - - if (preg_match('/jpe?g/', $extension)) { - $this->image = imagecreatefromjpeg($source); - $this->format = 'JPEG'; - } else if ($extension == 'png') { - $this->image = imagecreatefrompng($source); - $this->format = 'PNG'; - } - - return $this; - } - - /** - * Gets the image format - * @return string - Either 'JPEG' or 'PNG' - */ - public function getFormat() - { - return $this->format; - } - - /** - * Resizes the image to the specified dimensions - * @param float $width - * @param float $height - * @return GDAdapter - Returns $this - */ - public function resize($width, $height) - { - $this->target = imagecreatetruecolor($width, $height); - $format = $this->getFormat(); - - if ($format == 'PNG') { - $transparent = imagecolorallocatealpha($this->target, 255, 255, 255, 127); - - imagealphablending($this->target, false); - imagesavealpha($this->target, true); - imagefilledrectangle($this->target, 0, 0, $width, $height, $transparent); - } - - imagecopyresampled($this->target, $this->image, 0, 0, 0, 0, $width, $height, $this->original_width, $this->original_height); - - return $this; - } - - /** - * Sets JPEG quality of target image - * @param int $quality - * @return GDAdapter - Returns $this - */ - public function setQuality($quality) - { - $this->quality = $quality; - - return $this; - } - - /** - * Generates image and saves it to disk - * @param string $filename - Target filename for image - * @return bool - Returns true if successful, false otherwise - */ - public function save($filename) - { - $format = $this->getFormat(); - - if ($format == 'JPEG') { - $result = imagejpeg($this->target, $filename, $this->quality); - } else if ($format == 'PNG') { - $result = imagepng($this->target, $filename, 9); - } - - imagedestroy($this->image); - imagedestroy($this->target); - - return $result; - } -} diff --git a/plugins/automagic-images/adapters/imagick.php b/plugins/automagic-images/adapters/imagick.php deleted file mode 100644 index 92dac8d..0000000 --- a/plugins/automagic-images/adapters/imagick.php +++ /dev/null @@ -1,82 +0,0 @@ -image = new \Imagick($source); - $this->format = strtolower($this->image->getImageFormat()); - - return $this; - } - - /** - * Gets the image format - * @return string - Either 'JPEG' or 'PNG' - */ - public function getFormat() - { - return $this->format; - } - - /** - * Resizes the image to the specified dimensions - * @param float $width - * @param float $height - * @return ImagickAdapter - Returns $this - */ - public function resize($width, $height) - { - $this->image->resizeImage($width, $height, \Imagick::FILTER_LANCZOS, 1); - - return $this; - } - - /** - * Sets JPEG quality of target image - * @param int $quality - * @return ImagickAdapter - Returns $this - */ - public function setQuality($quality) - { - $this->image->setImageCompressionQuality($quality); - - return $this; - } - - /** - * Generates image and saves it to disk - * @param string $filename - Target filename for image - * @return bool - Returns true if successful, false otherwise - */ - public function save($filename) - { - $format = $this->getFormat(); - - if ($format == 'jpeg') { - $this->image->setImageCompression(\Imagick::COMPRESSION_JPEG); - } else if ($format == 'png') { - $this->image->setImageCompression(\Imagick::COMPRESSION_ZIP); - } - - $result = $this->image->writeImage($filename); - $this->image->clear(); - - return (bool) $result; - } -} diff --git a/plugins/automagic-images/adapters/interface.php b/plugins/automagic-images/adapters/interface.php deleted file mode 100644 index 986bda1..0000000 --- a/plugins/automagic-images/adapters/interface.php +++ /dev/null @@ -1,15 +0,0 @@ - ['onAdminSave', 0], - 'onOutputGenerated' => ['onOutputGenerated', 0] - ]; - } - - /** - * Determine whether a particular dependency is installed. - * @param string $adapter Either 'gd' or 'imagick' - * @return bool - */ - protected function dependencyCheck($adapter = 'gd') - { - if ($adapter === 'gd') { - return extension_loaded('gd'); - } - - if ($adapter === 'imagick') { - return class_exists('\Imagick'); - } - } - - /** - * Determine which adapter is preferred and whether or not it's available. - * Construct an instance of that adapter and return it. - * @param string $source - Source image path - * @return mixed - Either an instance of ImagickAdapter, GDAdapter or false if none of the extensions were available - */ - protected function getImageAdapter($source) - { - $imagick_exists = $this->dependencyCheck('imagick'); - $gd_exists = $this->dependencyCheck('gd'); - - if ($this->adapter === 'imagick') { - if ($imagick_exists) { - return new ImagickAdapter($source); - } else if ($gd_exists) { - return new GDAdapter($source); - } - } else if ($this->adapter === 'gd') { - if ($gd_exists) { - return new GDAdapter($source); - } else if ($imagick_exists) { - return new ImagickAdapter($source); - } - } - } - - /** - * Resizes an image using either Imagick or GD - * @param string $source - Source image path - * @param string $target - Target image path - * @param float $width - Target width - * @param float $height - Target height - * @param int [$quality=95] - Compression quality for target image - * @return bool - Returns true on success, otherwise false - */ - protected function resizeImage($source, $target, $width, $height, $quality = 95) - { - $adapter = $this->getImageAdapter($source); - $adapter->resize($width, $height); - $adapter->setQuality($quality); - - return $adapter->save($target); - } - - /** - * Called when a page is saved from the admin plugin. Will generate - * responsive image alternatives for images that don't have any. - */ - public function onAdminSave($event) - { - $page = $event['object']; - - if (!($page instanceof Page || $page instanceof PageObject)) { - return false; - } - - if (!$this->dependencyCheck('imagick') && !$this->dependencyCheck('gd')) { - $this->grav['admin']->setMessage('Neither Imagick nor GD seem to be installed. Automagic Images needs one of them to work.', 'warning'); - return; - } - - $this->sizes = (array) $this->config->get('plugins.automagic-images.sizes'); - $this->adapter = $this->config->get('plugins.automagic-images.adapter', 'imagick'); - - foreach ($page->media()->images() as $filename => $medium) { - $srcset = $medium->srcset(false); - - if ($srcset != '') { - dump($srcset); - continue; - } - - // We can't rely on the path returned from the image's own path - // method, since it points to the directory where the image is saved - // rather than where the original is stored. This means it could - // point to the global image cache directory. - $page_path = $page->path(); - $source_path = "$page_path/$filename"; - $info = pathinfo($source_path); - $count = 0; - - foreach ($this->sizes as $i => $size) { - if ($size['width'] >= $medium->width) { - continue; - } - - $count++; - $basename = str_replace(" ", "-", $info['filename']); - $ext = strtolower($info['extension']); - $dest_path = "{$info['dirname']}/{$basename}@{$count}x.{$ext}"; - $width = $size['width']; - $quality = $size['quality']; - $height = ($width / $medium->width) * $medium->height; - - $this->resizeImage($source_path, $dest_path, $width, $height, $quality, $medium->width, $medium->height); - } - - $remove_original = $this->config->get('plugins.automagic-images.remove_original'); - - if ($count > 0) { - $original_index = $count + 1; - - if ($remove_original) { - unlink($source_path); - } else { - rename($source_path, "{$info['dirname']}/{$basename}@{$original_index}x.{$ext}"); - } - - $fixed_source = str_replace($info['filename'], $basename, $source_path); - $fixed_source = str_replace($info['extension'], $ext, $fixed_source); - rename("{$info['dirname']}/{$basename}@1x.{$ext}", $fixed_source); - } - - $message = "Resized $filename $count times"; - - if ($remove_original) { - $message .= ' (and removed the original image)'; - } - - $this->grav['admin']->setMessage($message, 'info'); - } - } - - /** - * Iterates over images in page content that was generated via twig and adds - * sizes attribute (not cacheable) - * - * @return void - */ - public function onOutputGenerated() - { - if ($this->isAdmin()) { - return; - } - $config = (array) $this->config->get('plugins.automagic-images'); - $page = $this->grav['page']; - $config = $this->mergeConfig($page); - if ($config['enabled'] && $page->templateFormat() === 'html') { - include __DIR__ . '/vendor/autoload.php'; - $dom = new Dom; - $opt = new Options(); - // clashes with no clean up for some reason, so the doctype needs to be added in at the end - $opt->setPreserveLineBreaks(true); - $dom->loadStr($this->grav->output, $opt); - $images = $dom->find('img'); - $arrClasses = []; - foreach ($config['sizesattr'] as $array) { - $arrClasses[$array['class']] = $array['directive']; - } - foreach ($images as $image) { - $sizesattr = ""; - $classes = explode(" ", $image->getAttribute('class')); - foreach ($classes as $class) { - if (array_key_exists($class, $arrClasses)) { - $sizesattr = $arrClasses[$class]; - } - } - if ($sizesattr == "") { - if (array_key_exists('default', $arrClasses)) { - $sizesattr = $arrClasses['default']; - } - } - if ($sizesattr != "") { - $image->setAttribute('sizes', $sizesattr); - } - } - $this->grav->output = ''.$dom->outerHtml; - } - } -} diff --git a/plugins/automagic-images/automagic-images.yaml b/plugins/automagic-images/automagic-images.yaml deleted file mode 100644 index 42847ae..0000000 --- a/plugins/automagic-images/automagic-images.yaml +++ /dev/null @@ -1,27 +0,0 @@ -enabled: '1' -adapter: imagick -remove_original: '0' -sizes: - - - width: 640 - quality: 92 - - - width: 1000 - quality: 90 - - - width: 1500 - quality: 87 - - - width: 2500 - quality: 85 - - - width: 3500 - quality: 82 - -sizesattr: - - - class: 'default' - directive: '100vw' - - - class: 'example' - directive: '(min-width: 20em) 33%, 100vw' \ No newline at end of file diff --git a/plugins/automagic-images/blueprints.yaml b/plugins/automagic-images/blueprints.yaml deleted file mode 100644 index 254c3f6..0000000 --- a/plugins/automagic-images/blueprints.yaml +++ /dev/null @@ -1,76 +0,0 @@ -name: Automagic Images -version: 1.1.1 -description: Generate responsive versions of images as they are uploaded, and add sizes directives per CSS class. -icon: picture-o -author: - name: Netzhexe - email: ak@netzhexe.de -homepage: https://github.com/skinofthesoul/grav-plugin-automagic-images -keywords: images, responsive, srcset, sizes -bugs: https://github.com/skinofthesoul/grav-plugin-automagic-images/issues -docs: https://github.com/skinofthesoul/grav-plugin-automagic-images/blob/master/README.md -license: MIT - -form: - validation: strict - fields: - enabled: - type: toggle - label: PLUGIN_ADMIN.PLUGIN_STATUS - highlight: 1 - default: 0 - options: - 1: PLUGIN_ADMIN.ENABLED - 0: PLUGIN_ADMIN.DISABLED - validate: - type: bool - adapter: - type: select - label: PLUGIN_AUTOMAGIC_IMAGES.LABEL_ADAPTER - help: PLUGIN_AUTOMAGIC_IMAGES.HELP_ADAPTER - default: imagick - options: - imagick: Imagick - gd: GD - remove_original: - type: toggle - label: PLUGIN_AUTOMAGIC_IMAGES.LABEL_REMOVE_ORIGINAL - help: PLUGIN_AUTOMAGIC_IMAGES.HELP_REMOVE_ORIGINAL - highlight: 0 - default: 0 - options: - 1: Enabled - 0: Disabled - validate: - type: bool - sizes: - type: list - label: PLUGIN_AUTOMAGIC_IMAGES.LABEL_SIZES - btnLabel: PLUGIN_AUTOMAGIC_IMAGES.BTNLABEL_ADD_SIZE - - fields: - .width: - type: number - label: PLUGIN_AUTOMAGIC_IMAGES.LABEL_WIDTH - placeholder: 1280 - min: 1 - .quality: - type: number - label: PLUGIN_AUTOMAGIC_IMAGES.LABEL_QUALITY - placeholder: 82 - min: 0 - max: 100 - default: 82 - - sizesattr: - type: list - label: PLUGIN_AUTOMAGIC_IMAGES.LABEL_SIZESATTR - btnLabel: PLUGIN_AUTOMAGIC_IMAGES.BTNLABEL_SIZESATTR - - fields: - .class: - type: text - label: PLUGIN_AUTOMAGIC_IMAGES.LABEL_CLASS - .directive: - type: text - label: PLUGIN_AUTOMAGIC_IMAGES.LABEL_DIRECTIVE diff --git a/plugins/automagic-images/composer.json b/plugins/automagic-images/composer.json deleted file mode 100644 index 35a3307..0000000 --- a/plugins/automagic-images/composer.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "require": { - "paquettg/php-html-parser": "^3.1.1" - } -} diff --git a/plugins/automagic-images/composer.lock b/plugins/automagic-images/composer.lock deleted file mode 100644 index 9b3f4e2..0000000 --- a/plugins/automagic-images/composer.lock +++ /dev/null @@ -1,698 +0,0 @@ -{ - "_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#installing-dependencies", - "This file is @generated automatically" - ], - "content-hash": "69fdec62fcc07c25d68a76eaed5f7c8f", - "packages": [ - { - "name": "guzzlehttp/guzzle", - "version": "7.3.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/guzzle.git", - "reference": "7008573787b430c1c1f650e3722d9bba59967628" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/7008573787b430c1c1f650e3722d9bba59967628", - "reference": "7008573787b430c1c1f650e3722d9bba59967628", - "shasum": "" - }, - "require": { - "ext-json": "*", - "guzzlehttp/promises": "^1.4", - "guzzlehttp/psr7": "^1.7 || ^2.0", - "php": "^7.2.5 || ^8.0", - "psr/http-client": "^1.0" - }, - "provide": { - "psr/http-client-implementation": "1.0" - }, - "require-dev": { - "bamarni/composer-bin-plugin": "^1.4.1", - "ext-curl": "*", - "php-http/client-integration-tests": "^3.0", - "phpunit/phpunit": "^8.5.5 || ^9.3.5", - "psr/log": "^1.1" - }, - "suggest": { - "ext-curl": "Required for CURL handler support", - "ext-intl": "Required for Internationalized Domain Name (IDN) support", - "psr/log": "Required for using the Log middleware" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "7.3-dev" - } - }, - "autoload": { - "psr-4": { - "GuzzleHttp\\": "src/" - }, - "files": [ - "src/functions_include.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - }, - { - "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com", - "homepage": "https://sagikazarmark.hu" - } - ], - "description": "Guzzle is a PHP HTTP client library", - "homepage": "http://guzzlephp.org/", - "keywords": [ - "client", - "curl", - "framework", - "http", - "http client", - "psr-18", - "psr-7", - "rest", - "web service" - ], - "support": { - "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/7.3.0" - }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://github.com/Nyholm", - "type": "github" - }, - { - "url": "https://github.com/alexeyshockov", - "type": "github" - }, - { - "url": "https://github.com/gmponos", - "type": "github" - } - ], - "time": "2021-03-23T11:33:13+00:00" - }, - { - "name": "guzzlehttp/promises", - "version": "1.4.1", - "source": { - "type": "git", - "url": "https://github.com/guzzle/promises.git", - "reference": "8e7d04f1f6450fef59366c399cfad4b9383aa30d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/8e7d04f1f6450fef59366c399cfad4b9383aa30d", - "reference": "8e7d04f1f6450fef59366c399cfad4b9383aa30d", - "shasum": "" - }, - "require": { - "php": ">=5.5" - }, - "require-dev": { - "symfony/phpunit-bridge": "^4.4 || ^5.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4-dev" - } - }, - "autoload": { - "psr-4": { - "GuzzleHttp\\Promise\\": "src/" - }, - "files": [ - "src/functions_include.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "description": "Guzzle promises library", - "keywords": [ - "promise" - ], - "support": { - "issues": "https://github.com/guzzle/promises/issues", - "source": "https://github.com/guzzle/promises/tree/1.4.1" - }, - "time": "2021-03-07T09:25:29+00:00" - }, - { - "name": "guzzlehttp/psr7", - "version": "1.8.2", - "source": { - "type": "git", - "url": "https://github.com/guzzle/psr7.git", - "reference": "dc960a912984efb74d0a90222870c72c87f10c91" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/dc960a912984efb74d0a90222870c72c87f10c91", - "reference": "dc960a912984efb74d0a90222870c72c87f10c91", - "shasum": "" - }, - "require": { - "php": ">=5.4.0", - "psr/http-message": "~1.0", - "ralouphie/getallheaders": "^2.0.5 || ^3.0.0" - }, - "provide": { - "psr/http-message-implementation": "1.0" - }, - "require-dev": { - "ext-zlib": "*", - "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10" - }, - "suggest": { - "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.7-dev" - } - }, - "autoload": { - "psr-4": { - "GuzzleHttp\\Psr7\\": "src/" - }, - "files": [ - "src/functions_include.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - }, - { - "name": "Tobias Schultze", - "homepage": "https://github.com/Tobion" - } - ], - "description": "PSR-7 message implementation that also provides common utility methods", - "keywords": [ - "http", - "message", - "psr-7", - "request", - "response", - "stream", - "uri", - "url" - ], - "support": { - "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/1.8.2" - }, - "time": "2021-04-26T09:17:50+00:00" - }, - { - "name": "myclabs/php-enum", - "version": "1.8.0", - "source": { - "type": "git", - "url": "https://github.com/myclabs/php-enum.git", - "reference": "46cf3d8498b095bd33727b13fd5707263af99421" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/php-enum/zipball/46cf3d8498b095bd33727b13fd5707263af99421", - "reference": "46cf3d8498b095bd33727b13fd5707263af99421", - "shasum": "" - }, - "require": { - "ext-json": "*", - "php": "^7.3 || ^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.5", - "squizlabs/php_codesniffer": "1.*", - "vimeo/psalm": "^4.5.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "MyCLabs\\Enum\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP Enum contributors", - "homepage": "https://github.com/myclabs/php-enum/graphs/contributors" - } - ], - "description": "PHP Enum implementation", - "homepage": "http://github.com/myclabs/php-enum", - "keywords": [ - "enum" - ], - "support": { - "issues": "https://github.com/myclabs/php-enum/issues", - "source": "https://github.com/myclabs/php-enum/tree/1.8.0" - }, - "funding": [ - { - "url": "https://github.com/mnapoli", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/myclabs/php-enum", - "type": "tidelift" - } - ], - "time": "2021-02-15T16:11:48+00:00" - }, - { - "name": "paquettg/php-html-parser", - "version": "3.1.1", - "source": { - "type": "git", - "url": "https://github.com/paquettg/php-html-parser.git", - "reference": "4e01a438ad5961cc2d7427eb9798d213c8a12629" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/paquettg/php-html-parser/zipball/4e01a438ad5961cc2d7427eb9798d213c8a12629", - "reference": "4e01a438ad5961cc2d7427eb9798d213c8a12629", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "ext-mbstring": "*", - "ext-zlib": "*", - "guzzlehttp/guzzle": "^7.0", - "guzzlehttp/psr7": "^1.6", - "myclabs/php-enum": "^1.7", - "paquettg/string-encode": "~1.0.0", - "php": ">=7.2", - "php-http/httplug": "^2.1" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^2.16", - "infection/infection": "^0.13.4", - "mockery/mockery": "^1.2", - "phan/phan": "^2.4", - "phpunit/phpunit": "^7.5.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "PHPHtmlParser\\": "src/PHPHtmlParser" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Gilles Paquette", - "email": "paquettg@gmail.com", - "homepage": "http://gillespaquette.ca" - } - ], - "description": "An HTML DOM parser. It allows you to manipulate HTML. Find tags on an HTML page with selectors just like jQuery.", - "homepage": "https://github.com/paquettg/php-html-parser", - "keywords": [ - "dom", - "html", - "parser" - ], - "support": { - "issues": "https://github.com/paquettg/php-html-parser/issues", - "source": "https://github.com/paquettg/php-html-parser/tree/3.1.1" - }, - "funding": [ - { - "url": "https://tidelift.com/funding/github/packagist/paquettg/php-html-parser", - "type": "tidelift" - } - ], - "time": "2020-11-01T20:34:43+00:00" - }, - { - "name": "paquettg/string-encode", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/paquettg/string-encoder.git", - "reference": "a8708e9fac9d5ddfc8fc2aac6004e2cd05d80fee" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/paquettg/string-encoder/zipball/a8708e9fac9d5ddfc8fc2aac6004e2cd05d80fee", - "reference": "a8708e9fac9d5ddfc8fc2aac6004e2cd05d80fee", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.5.1" - }, - "type": "library", - "autoload": { - "psr-0": { - "stringEncode": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Gilles Paquette", - "email": "paquettg@gmail.com", - "homepage": "http://gillespaquette.ca" - } - ], - "description": "Facilitating the process of altering string encoding in PHP.", - "homepage": "https://github.com/paquettg/string-encoder", - "keywords": [ - "charset", - "encoding", - "string" - ], - "support": { - "issues": "https://github.com/paquettg/string-encoder/issues", - "source": "https://github.com/paquettg/string-encoder/tree/1.0.1" - }, - "time": "2018-12-21T02:25:09+00:00" - }, - { - "name": "php-http/httplug", - "version": "2.2.0", - "source": { - "type": "git", - "url": "https://github.com/php-http/httplug.git", - "reference": "191a0a1b41ed026b717421931f8d3bd2514ffbf9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-http/httplug/zipball/191a0a1b41ed026b717421931f8d3bd2514ffbf9", - "reference": "191a0a1b41ed026b717421931f8d3bd2514ffbf9", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0", - "php-http/promise": "^1.1", - "psr/http-client": "^1.0", - "psr/http-message": "^1.0" - }, - "require-dev": { - "friends-of-phpspec/phpspec-code-coverage": "^4.1", - "phpspec/phpspec": "^5.1 || ^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - } - }, - "autoload": { - "psr-4": { - "Http\\Client\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eric GELOEN", - "email": "geloen.eric@gmail.com" - }, - { - "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com", - "homepage": "https://sagikazarmark.hu" - } - ], - "description": "HTTPlug, the HTTP client abstraction for PHP", - "homepage": "http://httplug.io", - "keywords": [ - "client", - "http" - ], - "support": { - "issues": "https://github.com/php-http/httplug/issues", - "source": "https://github.com/php-http/httplug/tree/master" - }, - "time": "2020-07-13T15:43:23+00:00" - }, - { - "name": "php-http/promise", - "version": "1.1.0", - "source": { - "type": "git", - "url": "https://github.com/php-http/promise.git", - "reference": "4c4c1f9b7289a2ec57cde7f1e9762a5789506f88" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-http/promise/zipball/4c4c1f9b7289a2ec57cde7f1e9762a5789506f88", - "reference": "4c4c1f9b7289a2ec57cde7f1e9762a5789506f88", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "friends-of-phpspec/phpspec-code-coverage": "^4.3.2", - "phpspec/phpspec": "^5.1.2 || ^6.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1-dev" - } - }, - "autoload": { - "psr-4": { - "Http\\Promise\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Joel Wurtz", - "email": "joel.wurtz@gmail.com" - }, - { - "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com" - } - ], - "description": "Promise used for asynchronous HTTP requests", - "homepage": "http://httplug.io", - "keywords": [ - "promise" - ], - "support": { - "issues": "https://github.com/php-http/promise/issues", - "source": "https://github.com/php-http/promise/tree/1.1.0" - }, - "time": "2020-07-07T09:29:14+00:00" - }, - { - "name": "psr/http-client", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-client.git", - "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", - "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", - "shasum": "" - }, - "require": { - "php": "^7.0 || ^8.0", - "psr/http-message": "^1.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Http\\Client\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP clients", - "homepage": "https://github.com/php-fig/http-client", - "keywords": [ - "http", - "http-client", - "psr", - "psr-18" - ], - "support": { - "source": "https://github.com/php-fig/http-client/tree/master" - }, - "time": "2020-06-29T06:28:15+00:00" - }, - { - "name": "psr/http-message", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP messages", - "homepage": "https://github.com/php-fig/http-message", - "keywords": [ - "http", - "http-message", - "psr", - "psr-7", - "request", - "response" - ], - "support": { - "source": "https://github.com/php-fig/http-message/tree/master" - }, - "time": "2016-08-06T14:39:51+00:00" - }, - { - "name": "ralouphie/getallheaders", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/ralouphie/getallheaders.git", - "reference": "120b605dfeb996808c31b6477290a714d356e822" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", - "reference": "120b605dfeb996808c31b6477290a714d356e822", - "shasum": "" - }, - "require": { - "php": ">=5.6" - }, - "require-dev": { - "php-coveralls/php-coveralls": "^2.1", - "phpunit/phpunit": "^5 || ^6.5" - }, - "type": "library", - "autoload": { - "files": [ - "src/getallheaders.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ralph Khattar", - "email": "ralph.khattar@gmail.com" - } - ], - "description": "A polyfill for getallheaders.", - "support": { - "issues": "https://github.com/ralouphie/getallheaders/issues", - "source": "https://github.com/ralouphie/getallheaders/tree/develop" - }, - "time": "2019-03-08T08:55:37+00:00" - } - ], - "packages-dev": [], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": [], - "prefer-stable": false, - "prefer-lowest": false, - "platform": [], - "platform-dev": [], - "plugin-api-version": "2.0.0" -} diff --git a/plugins/automagic-images/composer.phar b/plugins/automagic-images/composer.phar deleted file mode 100644 index 76d6ceb..0000000 Binary files a/plugins/automagic-images/composer.phar and /dev/null differ diff --git a/plugins/automagic-images/languages.yaml b/plugins/automagic-images/languages.yaml deleted file mode 100644 index 76a0a1b..0000000 --- a/plugins/automagic-images/languages.yaml +++ /dev/null @@ -1,28 +0,0 @@ -en: - PLUGIN_AUTOMAGIC_IMAGES: - LABEL_ADAPTER: Image editing module - HELP_ADAPTER: Imagick will produce better results, but isn't available in all environments. - LABEL_REMOVE_ORIGINAL: Remove original after resizing - HELP_REMOVE_ORIGINAL: By default, the original image will be preserved as the largest variant. Enable this to remove it instead. - LABEL_SIZES: Image sizes - BTNLABEL_ADD_SIZE: Add image size - LABEL_WIDTH: Width - LABEL_QUALITY: JPEG quality - LABEL_SIZESATTR: Sizes directive per CSS class - BTNLABEL_SIZESATTR: Add sizes directive - LABEL_CLASS: CSS class - LABEL_DIRECTIVE: sizes attribute -de: - PLUGIN_AUTOMAGIC_IMAGES: - LABEL_ADAPTER: Bildbearbeitungsmodul - HELP_ADAPTER: Mit Imagick sind die Ergebnisse besser, aber es kann sein, dass es nicht zur Verfüung steht. - LABEL_REMOVE_ORIGINAL: Original nach Bearbeitung löschen - HELP_REMOVE_ORIGINAL: Standardmäßig wird das Originalbild als größte Bildvariante behalten. Wenn diese Option gesetzt ist, wird es stattdessen gelöscht. - LABEL_SIZES: Bildgrößen - BTNLABEL_ADD_SIZE: Bildgröße hinzufügen - LABEL_WIDTH: Breite - LABEL_QUALITY: JPEG-Qualität - LABEL_SIZESATTR: Die sizes-Angaben pro CSS-Klasse - BTNLABEL_SIZESATTR: sizes-Angabe hinzufügen - LABEL_CLASS: CSS-Klasse - LABEL_DIRECTIVE: sizes-Angabe diff --git a/plugins/automagic-images/vendor/autoload.php b/plugins/automagic-images/vendor/autoload.php deleted file mode 100644 index da9f51f..0000000 --- a/plugins/automagic-images/vendor/autoload.php +++ /dev/null @@ -1,7 +0,0 @@ - - * Jordi Boggiano - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Composer\Autoload; - -/** - * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. - * - * $loader = new \Composer\Autoload\ClassLoader(); - * - * // register classes with namespaces - * $loader->add('Symfony\Component', __DIR__.'/component'); - * $loader->add('Symfony', __DIR__.'/framework'); - * - * // activate the autoloader - * $loader->register(); - * - * // to enable searching the include path (eg. for PEAR packages) - * $loader->setUseIncludePath(true); - * - * In this example, if you try to use a class in the Symfony\Component - * namespace or one of its children (Symfony\Component\Console for instance), - * the autoloader will first look for the class under the component/ - * directory, and it will then fallback to the framework/ directory if not - * found before giving up. - * - * This class is loosely based on the Symfony UniversalClassLoader. - * - * @author Fabien Potencier - * @author Jordi Boggiano - * @see https://www.php-fig.org/psr/psr-0/ - * @see https://www.php-fig.org/psr/psr-4/ - */ -class ClassLoader -{ - private $vendorDir; - - // PSR-4 - private $prefixLengthsPsr4 = array(); - private $prefixDirsPsr4 = array(); - private $fallbackDirsPsr4 = array(); - - // PSR-0 - private $prefixesPsr0 = array(); - private $fallbackDirsPsr0 = array(); - - private $useIncludePath = false; - private $classMap = array(); - private $classMapAuthoritative = false; - private $missingClasses = array(); - private $apcuPrefix; - - private static $registeredLoaders = array(); - - public function __construct($vendorDir = null) - { - $this->vendorDir = $vendorDir; - } - - public function getPrefixes() - { - if (!empty($this->prefixesPsr0)) { - return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); - } - - return array(); - } - - public function getPrefixesPsr4() - { - return $this->prefixDirsPsr4; - } - - public function getFallbackDirs() - { - return $this->fallbackDirsPsr0; - } - - public function getFallbackDirsPsr4() - { - return $this->fallbackDirsPsr4; - } - - public function getClassMap() - { - return $this->classMap; - } - - /** - * @param array $classMap Class to filename map - */ - public function addClassMap(array $classMap) - { - if ($this->classMap) { - $this->classMap = array_merge($this->classMap, $classMap); - } else { - $this->classMap = $classMap; - } - } - - /** - * Registers a set of PSR-0 directories for a given prefix, either - * appending or prepending to the ones previously set for this prefix. - * - * @param string $prefix The prefix - * @param array|string $paths The PSR-0 root directories - * @param bool $prepend Whether to prepend the directories - */ - public function add($prefix, $paths, $prepend = false) - { - if (!$prefix) { - if ($prepend) { - $this->fallbackDirsPsr0 = array_merge( - (array) $paths, - $this->fallbackDirsPsr0 - ); - } else { - $this->fallbackDirsPsr0 = array_merge( - $this->fallbackDirsPsr0, - (array) $paths - ); - } - - return; - } - - $first = $prefix[0]; - if (!isset($this->prefixesPsr0[$first][$prefix])) { - $this->prefixesPsr0[$first][$prefix] = (array) $paths; - - return; - } - if ($prepend) { - $this->prefixesPsr0[$first][$prefix] = array_merge( - (array) $paths, - $this->prefixesPsr0[$first][$prefix] - ); - } else { - $this->prefixesPsr0[$first][$prefix] = array_merge( - $this->prefixesPsr0[$first][$prefix], - (array) $paths - ); - } - } - - /** - * Registers a set of PSR-4 directories for a given namespace, either - * appending or prepending to the ones previously set for this namespace. - * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param array|string $paths The PSR-4 base directories - * @param bool $prepend Whether to prepend the directories - * - * @throws \InvalidArgumentException - */ - public function addPsr4($prefix, $paths, $prepend = false) - { - if (!$prefix) { - // Register directories for the root namespace. - if ($prepend) { - $this->fallbackDirsPsr4 = array_merge( - (array) $paths, - $this->fallbackDirsPsr4 - ); - } else { - $this->fallbackDirsPsr4 = array_merge( - $this->fallbackDirsPsr4, - (array) $paths - ); - } - } elseif (!isset($this->prefixDirsPsr4[$prefix])) { - // Register directories for a new namespace. - $length = strlen($prefix); - if ('\\' !== $prefix[$length - 1]) { - throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); - } - $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; - $this->prefixDirsPsr4[$prefix] = (array) $paths; - } elseif ($prepend) { - // Prepend directories for an already registered namespace. - $this->prefixDirsPsr4[$prefix] = array_merge( - (array) $paths, - $this->prefixDirsPsr4[$prefix] - ); - } else { - // Append directories for an already registered namespace. - $this->prefixDirsPsr4[$prefix] = array_merge( - $this->prefixDirsPsr4[$prefix], - (array) $paths - ); - } - } - - /** - * Registers a set of PSR-0 directories for a given prefix, - * replacing any others previously set for this prefix. - * - * @param string $prefix The prefix - * @param array|string $paths The PSR-0 base directories - */ - public function set($prefix, $paths) - { - if (!$prefix) { - $this->fallbackDirsPsr0 = (array) $paths; - } else { - $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; - } - } - - /** - * Registers a set of PSR-4 directories for a given namespace, - * replacing any others previously set for this namespace. - * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param array|string $paths The PSR-4 base directories - * - * @throws \InvalidArgumentException - */ - public function setPsr4($prefix, $paths) - { - if (!$prefix) { - $this->fallbackDirsPsr4 = (array) $paths; - } else { - $length = strlen($prefix); - if ('\\' !== $prefix[$length - 1]) { - throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); - } - $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; - $this->prefixDirsPsr4[$prefix] = (array) $paths; - } - } - - /** - * Turns on searching the include path for class files. - * - * @param bool $useIncludePath - */ - public function setUseIncludePath($useIncludePath) - { - $this->useIncludePath = $useIncludePath; - } - - /** - * Can be used to check if the autoloader uses the include path to check - * for classes. - * - * @return bool - */ - public function getUseIncludePath() - { - return $this->useIncludePath; - } - - /** - * Turns off searching the prefix and fallback directories for classes - * that have not been registered with the class map. - * - * @param bool $classMapAuthoritative - */ - public function setClassMapAuthoritative($classMapAuthoritative) - { - $this->classMapAuthoritative = $classMapAuthoritative; - } - - /** - * Should class lookup fail if not found in the current class map? - * - * @return bool - */ - public function isClassMapAuthoritative() - { - return $this->classMapAuthoritative; - } - - /** - * APCu prefix to use to cache found/not-found classes, if the extension is enabled. - * - * @param string|null $apcuPrefix - */ - public function setApcuPrefix($apcuPrefix) - { - $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; - } - - /** - * The APCu prefix in use, or null if APCu caching is not enabled. - * - * @return string|null - */ - public function getApcuPrefix() - { - return $this->apcuPrefix; - } - - /** - * Registers this instance as an autoloader. - * - * @param bool $prepend Whether to prepend the autoloader or not - */ - public function register($prepend = false) - { - spl_autoload_register(array($this, 'loadClass'), true, $prepend); - - if (null === $this->vendorDir) { - return; - } - - if ($prepend) { - self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders; - } else { - unset(self::$registeredLoaders[$this->vendorDir]); - self::$registeredLoaders[$this->vendorDir] = $this; - } - } - - /** - * Unregisters this instance as an autoloader. - */ - public function unregister() - { - spl_autoload_unregister(array($this, 'loadClass')); - - if (null !== $this->vendorDir) { - unset(self::$registeredLoaders[$this->vendorDir]); - } - } - - /** - * Loads the given class or interface. - * - * @param string $class The name of the class - * @return bool|null True if loaded, null otherwise - */ - public function loadClass($class) - { - if ($file = $this->findFile($class)) { - includeFile($file); - - return true; - } - } - - /** - * Finds the path to the file where the class is defined. - * - * @param string $class The name of the class - * - * @return string|false The path if found, false otherwise - */ - public function findFile($class) - { - // class map lookup - if (isset($this->classMap[$class])) { - return $this->classMap[$class]; - } - if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { - return false; - } - if (null !== $this->apcuPrefix) { - $file = apcu_fetch($this->apcuPrefix.$class, $hit); - if ($hit) { - return $file; - } - } - - $file = $this->findFileWithExtension($class, '.php'); - - // Search for Hack files if we are running on HHVM - if (false === $file && defined('HHVM_VERSION')) { - $file = $this->findFileWithExtension($class, '.hh'); - } - - if (null !== $this->apcuPrefix) { - apcu_add($this->apcuPrefix.$class, $file); - } - - if (false === $file) { - // Remember that this class does not exist. - $this->missingClasses[$class] = true; - } - - return $file; - } - - /** - * Returns the currently registered loaders indexed by their corresponding vendor directories. - * - * @return self[] - */ - public static function getRegisteredLoaders() - { - return self::$registeredLoaders; - } - - private function findFileWithExtension($class, $ext) - { - // PSR-4 lookup - $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; - - $first = $class[0]; - if (isset($this->prefixLengthsPsr4[$first])) { - $subPath = $class; - while (false !== $lastPos = strrpos($subPath, '\\')) { - $subPath = substr($subPath, 0, $lastPos); - $search = $subPath . '\\'; - if (isset($this->prefixDirsPsr4[$search])) { - $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); - foreach ($this->prefixDirsPsr4[$search] as $dir) { - if (file_exists($file = $dir . $pathEnd)) { - return $file; - } - } - } - } - } - - // PSR-4 fallback dirs - foreach ($this->fallbackDirsPsr4 as $dir) { - if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { - return $file; - } - } - - // PSR-0 lookup - if (false !== $pos = strrpos($class, '\\')) { - // namespaced class name - $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) - . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); - } else { - // PEAR-like class name - $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; - } - - if (isset($this->prefixesPsr0[$first])) { - foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { - if (0 === strpos($class, $prefix)) { - foreach ($dirs as $dir) { - if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { - return $file; - } - } - } - } - } - - // PSR-0 fallback dirs - foreach ($this->fallbackDirsPsr0 as $dir) { - if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { - return $file; - } - } - - // PSR-0 include paths. - if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { - return $file; - } - - return false; - } -} - -/** - * Scope isolated include. - * - * Prevents access to $this/self from included files. - */ -function includeFile($file) -{ - include $file; -} diff --git a/plugins/automagic-images/vendor/composer/InstalledVersions.php b/plugins/automagic-images/vendor/composer/InstalledVersions.php deleted file mode 100644 index 86efd35..0000000 --- a/plugins/automagic-images/vendor/composer/InstalledVersions.php +++ /dev/null @@ -1,398 +0,0 @@ - - array ( - 'pretty_version' => '1.0.0+no-version-set', - 'version' => '1.0.0.0', - 'aliases' => - array ( - ), - 'reference' => NULL, - 'name' => '__root__', - ), - 'versions' => - array ( - '__root__' => - array ( - 'pretty_version' => '1.0.0+no-version-set', - 'version' => '1.0.0.0', - 'aliases' => - array ( - ), - 'reference' => NULL, - ), - 'guzzlehttp/guzzle' => - array ( - 'pretty_version' => '7.3.0', - 'version' => '7.3.0.0', - 'aliases' => - array ( - ), - 'reference' => '7008573787b430c1c1f650e3722d9bba59967628', - ), - 'guzzlehttp/promises' => - array ( - 'pretty_version' => '1.4.1', - 'version' => '1.4.1.0', - 'aliases' => - array ( - ), - 'reference' => '8e7d04f1f6450fef59366c399cfad4b9383aa30d', - ), - 'guzzlehttp/psr7' => - array ( - 'pretty_version' => '1.8.2', - 'version' => '1.8.2.0', - 'aliases' => - array ( - ), - 'reference' => 'dc960a912984efb74d0a90222870c72c87f10c91', - ), - 'myclabs/php-enum' => - array ( - 'pretty_version' => '1.8.0', - 'version' => '1.8.0.0', - 'aliases' => - array ( - ), - 'reference' => '46cf3d8498b095bd33727b13fd5707263af99421', - ), - 'paquettg/php-html-parser' => - array ( - 'pretty_version' => '3.1.1', - 'version' => '3.1.1.0', - 'aliases' => - array ( - ), - 'reference' => '4e01a438ad5961cc2d7427eb9798d213c8a12629', - ), - 'paquettg/string-encode' => - array ( - 'pretty_version' => '1.0.1', - 'version' => '1.0.1.0', - 'aliases' => - array ( - ), - 'reference' => 'a8708e9fac9d5ddfc8fc2aac6004e2cd05d80fee', - ), - 'php-http/httplug' => - array ( - 'pretty_version' => '2.2.0', - 'version' => '2.2.0.0', - 'aliases' => - array ( - ), - 'reference' => '191a0a1b41ed026b717421931f8d3bd2514ffbf9', - ), - 'php-http/promise' => - array ( - 'pretty_version' => '1.1.0', - 'version' => '1.1.0.0', - 'aliases' => - array ( - ), - 'reference' => '4c4c1f9b7289a2ec57cde7f1e9762a5789506f88', - ), - 'psr/http-client' => - array ( - 'pretty_version' => '1.0.1', - 'version' => '1.0.1.0', - 'aliases' => - array ( - ), - 'reference' => '2dfb5f6c5eff0e91e20e913f8c5452ed95b86621', - ), - 'psr/http-client-implementation' => - array ( - 'provided' => - array ( - 0 => '1.0', - ), - ), - 'psr/http-message' => - array ( - 'pretty_version' => '1.0.1', - 'version' => '1.0.1.0', - 'aliases' => - array ( - ), - 'reference' => 'f6561bf28d520154e4b0ec72be95418abe6d9363', - ), - 'psr/http-message-implementation' => - array ( - 'provided' => - array ( - 0 => '1.0', - ), - ), - 'ralouphie/getallheaders' => - array ( - 'pretty_version' => '3.0.3', - 'version' => '3.0.3.0', - 'aliases' => - array ( - ), - 'reference' => '120b605dfeb996808c31b6477290a714d356e822', - ), - ), -); -private static $canGetVendors; -private static $installedByVendor = array(); - - - - - - - -public static function getInstalledPackages() -{ -$packages = array(); -foreach (self::getInstalled() as $installed) { -$packages[] = array_keys($installed['versions']); -} - -if (1 === \count($packages)) { -return $packages[0]; -} - -return array_keys(array_flip(\call_user_func_array('array_merge', $packages))); -} - - - - - - - - - -public static function isInstalled($packageName) -{ -foreach (self::getInstalled() as $installed) { -if (isset($installed['versions'][$packageName])) { -return true; -} -} - -return false; -} - - - - - - - - - - - - - - -public static function satisfies(VersionParser $parser, $packageName, $constraint) -{ -$constraint = $parser->parseConstraints($constraint); -$provided = $parser->parseConstraints(self::getVersionRanges($packageName)); - -return $provided->matches($constraint); -} - - - - - - - - - - -public static function getVersionRanges($packageName) -{ -foreach (self::getInstalled() as $installed) { -if (!isset($installed['versions'][$packageName])) { -continue; -} - -$ranges = array(); -if (isset($installed['versions'][$packageName]['pretty_version'])) { -$ranges[] = $installed['versions'][$packageName]['pretty_version']; -} -if (array_key_exists('aliases', $installed['versions'][$packageName])) { -$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']); -} -if (array_key_exists('replaced', $installed['versions'][$packageName])) { -$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']); -} -if (array_key_exists('provided', $installed['versions'][$packageName])) { -$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']); -} - -return implode(' || ', $ranges); -} - -throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); -} - - - - - -public static function getVersion($packageName) -{ -foreach (self::getInstalled() as $installed) { -if (!isset($installed['versions'][$packageName])) { -continue; -} - -if (!isset($installed['versions'][$packageName]['version'])) { -return null; -} - -return $installed['versions'][$packageName]['version']; -} - -throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); -} - - - - - -public static function getPrettyVersion($packageName) -{ -foreach (self::getInstalled() as $installed) { -if (!isset($installed['versions'][$packageName])) { -continue; -} - -if (!isset($installed['versions'][$packageName]['pretty_version'])) { -return null; -} - -return $installed['versions'][$packageName]['pretty_version']; -} - -throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); -} - - - - - -public static function getReference($packageName) -{ -foreach (self::getInstalled() as $installed) { -if (!isset($installed['versions'][$packageName])) { -continue; -} - -if (!isset($installed['versions'][$packageName]['reference'])) { -return null; -} - -return $installed['versions'][$packageName]['reference']; -} - -throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); -} - - - - - -public static function getRootPackage() -{ -$installed = self::getInstalled(); - -return $installed[0]['root']; -} - - - - - - - -public static function getRawData() -{ -return self::$installed; -} - - - - - - - - - - - - - - - - - - - -public static function reload($data) -{ -self::$installed = $data; -self::$installedByVendor = array(); -} - - - - - -private static function getInstalled() -{ -if (null === self::$canGetVendors) { -self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders'); -} - -$installed = array(); - -if (self::$canGetVendors) { -foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { -if (isset(self::$installedByVendor[$vendorDir])) { -$installed[] = self::$installedByVendor[$vendorDir]; -} elseif (is_file($vendorDir.'/composer/installed.php')) { -$installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php'; -} -} -} - -$installed[] = self::$installed; - -return $installed; -} -} diff --git a/plugins/automagic-images/vendor/composer/LICENSE b/plugins/automagic-images/vendor/composer/LICENSE deleted file mode 100644 index f27399a..0000000 --- a/plugins/automagic-images/vendor/composer/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ - -Copyright (c) Nils Adermann, Jordi Boggiano - -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/plugins/automagic-images/vendor/composer/autoload_classmap.php b/plugins/automagic-images/vendor/composer/autoload_classmap.php deleted file mode 100644 index b26f1b1..0000000 --- a/plugins/automagic-images/vendor/composer/autoload_classmap.php +++ /dev/null @@ -1,10 +0,0 @@ - $vendorDir . '/composer/InstalledVersions.php', -); diff --git a/plugins/automagic-images/vendor/composer/autoload_files.php b/plugins/automagic-images/vendor/composer/autoload_files.php deleted file mode 100644 index c59eab5..0000000 --- a/plugins/automagic-images/vendor/composer/autoload_files.php +++ /dev/null @@ -1,13 +0,0 @@ - $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php', - 'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/src/functions_include.php', - 'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php', - '37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php', -); diff --git a/plugins/automagic-images/vendor/composer/autoload_namespaces.php b/plugins/automagic-images/vendor/composer/autoload_namespaces.php deleted file mode 100644 index 5c28f75..0000000 --- a/plugins/automagic-images/vendor/composer/autoload_namespaces.php +++ /dev/null @@ -1,10 +0,0 @@ - array($vendorDir . '/paquettg/string-encode/src'), -); diff --git a/plugins/automagic-images/vendor/composer/autoload_psr4.php b/plugins/automagic-images/vendor/composer/autoload_psr4.php deleted file mode 100644 index 1116c6f..0000000 --- a/plugins/automagic-images/vendor/composer/autoload_psr4.php +++ /dev/null @@ -1,18 +0,0 @@ - array($vendorDir . '/psr/http-message/src'), - 'Psr\\Http\\Client\\' => array($vendorDir . '/psr/http-client/src'), - 'PHPHtmlParser\\' => array($vendorDir . '/paquettg/php-html-parser/src/PHPHtmlParser'), - 'MyCLabs\\Enum\\' => array($vendorDir . '/myclabs/php-enum/src'), - 'Http\\Promise\\' => array($vendorDir . '/php-http/promise/src'), - 'Http\\Client\\' => array($vendorDir . '/php-http/httplug/src'), - 'GuzzleHttp\\Psr7\\' => array($vendorDir . '/guzzlehttp/psr7/src'), - 'GuzzleHttp\\Promise\\' => array($vendorDir . '/guzzlehttp/promises/src'), - 'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'), -); diff --git a/plugins/automagic-images/vendor/composer/autoload_real.php b/plugins/automagic-images/vendor/composer/autoload_real.php deleted file mode 100644 index 455d254..0000000 --- a/plugins/automagic-images/vendor/composer/autoload_real.php +++ /dev/null @@ -1,75 +0,0 @@ -= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); - if ($useStaticLoader) { - require __DIR__ . '/autoload_static.php'; - - call_user_func(\Composer\Autoload\ComposerStaticInitec63ac3db7bdf9f71afc9dc86daedde7::getInitializer($loader)); - } else { - $map = require __DIR__ . '/autoload_namespaces.php'; - foreach ($map as $namespace => $path) { - $loader->set($namespace, $path); - } - - $map = require __DIR__ . '/autoload_psr4.php'; - foreach ($map as $namespace => $path) { - $loader->setPsr4($namespace, $path); - } - - $classMap = require __DIR__ . '/autoload_classmap.php'; - if ($classMap) { - $loader->addClassMap($classMap); - } - } - - $loader->register(true); - - if ($useStaticLoader) { - $includeFiles = Composer\Autoload\ComposerStaticInitec63ac3db7bdf9f71afc9dc86daedde7::$files; - } else { - $includeFiles = require __DIR__ . '/autoload_files.php'; - } - foreach ($includeFiles as $fileIdentifier => $file) { - composerRequireec63ac3db7bdf9f71afc9dc86daedde7($fileIdentifier, $file); - } - - return $loader; - } -} - -function composerRequireec63ac3db7bdf9f71afc9dc86daedde7($fileIdentifier, $file) -{ - if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { - require $file; - - $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; - } -} diff --git a/plugins/automagic-images/vendor/composer/autoload_static.php b/plugins/automagic-images/vendor/composer/autoload_static.php deleted file mode 100644 index 72648d5..0000000 --- a/plugins/automagic-images/vendor/composer/autoload_static.php +++ /dev/null @@ -1,103 +0,0 @@ - __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php', - 'a0edc8309cc5e1d60e3047b5df6b7052' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/functions_include.php', - 'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php', - '37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php', - ); - - public static $prefixLengthsPsr4 = array ( - 'P' => - array ( - 'Psr\\Http\\Message\\' => 17, - 'Psr\\Http\\Client\\' => 16, - 'PHPHtmlParser\\' => 14, - ), - 'M' => - array ( - 'MyCLabs\\Enum\\' => 13, - ), - 'H' => - array ( - 'Http\\Promise\\' => 13, - 'Http\\Client\\' => 12, - ), - 'G' => - array ( - 'GuzzleHttp\\Psr7\\' => 16, - 'GuzzleHttp\\Promise\\' => 19, - 'GuzzleHttp\\' => 11, - ), - ); - - public static $prefixDirsPsr4 = array ( - 'Psr\\Http\\Message\\' => - array ( - 0 => __DIR__ . '/..' . '/psr/http-message/src', - ), - 'Psr\\Http\\Client\\' => - array ( - 0 => __DIR__ . '/..' . '/psr/http-client/src', - ), - 'PHPHtmlParser\\' => - array ( - 0 => __DIR__ . '/..' . '/paquettg/php-html-parser/src/PHPHtmlParser', - ), - 'MyCLabs\\Enum\\' => - array ( - 0 => __DIR__ . '/..' . '/myclabs/php-enum/src', - ), - 'Http\\Promise\\' => - array ( - 0 => __DIR__ . '/..' . '/php-http/promise/src', - ), - 'Http\\Client\\' => - array ( - 0 => __DIR__ . '/..' . '/php-http/httplug/src', - ), - 'GuzzleHttp\\Psr7\\' => - array ( - 0 => __DIR__ . '/..' . '/guzzlehttp/psr7/src', - ), - 'GuzzleHttp\\Promise\\' => - array ( - 0 => __DIR__ . '/..' . '/guzzlehttp/promises/src', - ), - 'GuzzleHttp\\' => - array ( - 0 => __DIR__ . '/..' . '/guzzlehttp/guzzle/src', - ), - ); - - public static $prefixesPsr0 = array ( - 's' => - array ( - 'stringEncode' => - array ( - 0 => __DIR__ . '/..' . '/paquettg/string-encode/src', - ), - ), - ); - - public static $classMap = array ( - 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', - ); - - public static function getInitializer(ClassLoader $loader) - { - return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInitec63ac3db7bdf9f71afc9dc86daedde7::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInitec63ac3db7bdf9f71afc9dc86daedde7::$prefixDirsPsr4; - $loader->prefixesPsr0 = ComposerStaticInitec63ac3db7bdf9f71afc9dc86daedde7::$prefixesPsr0; - $loader->classMap = ComposerStaticInitec63ac3db7bdf9f71afc9dc86daedde7::$classMap; - - }, null, ClassLoader::class); - } -} diff --git a/plugins/automagic-images/vendor/composer/installed.json b/plugins/automagic-images/vendor/composer/installed.json deleted file mode 100644 index 8db51e8..0000000 --- a/plugins/automagic-images/vendor/composer/installed.json +++ /dev/null @@ -1,718 +0,0 @@ -{ - "packages": [ - { - "name": "guzzlehttp/guzzle", - "version": "7.3.0", - "version_normalized": "7.3.0.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/guzzle.git", - "reference": "7008573787b430c1c1f650e3722d9bba59967628" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/7008573787b430c1c1f650e3722d9bba59967628", - "reference": "7008573787b430c1c1f650e3722d9bba59967628", - "shasum": "" - }, - "require": { - "ext-json": "*", - "guzzlehttp/promises": "^1.4", - "guzzlehttp/psr7": "^1.7 || ^2.0", - "php": "^7.2.5 || ^8.0", - "psr/http-client": "^1.0" - }, - "provide": { - "psr/http-client-implementation": "1.0" - }, - "require-dev": { - "bamarni/composer-bin-plugin": "^1.4.1", - "ext-curl": "*", - "php-http/client-integration-tests": "^3.0", - "phpunit/phpunit": "^8.5.5 || ^9.3.5", - "psr/log": "^1.1" - }, - "suggest": { - "ext-curl": "Required for CURL handler support", - "ext-intl": "Required for Internationalized Domain Name (IDN) support", - "psr/log": "Required for using the Log middleware" - }, - "time": "2021-03-23T11:33:13+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "7.3-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "GuzzleHttp\\": "src/" - }, - "files": [ - "src/functions_include.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - }, - { - "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com", - "homepage": "https://sagikazarmark.hu" - } - ], - "description": "Guzzle is a PHP HTTP client library", - "homepage": "http://guzzlephp.org/", - "keywords": [ - "client", - "curl", - "framework", - "http", - "http client", - "psr-18", - "psr-7", - "rest", - "web service" - ], - "support": { - "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/7.3.0" - }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://github.com/Nyholm", - "type": "github" - }, - { - "url": "https://github.com/alexeyshockov", - "type": "github" - }, - { - "url": "https://github.com/gmponos", - "type": "github" - } - ], - "install-path": "../guzzlehttp/guzzle" - }, - { - "name": "guzzlehttp/promises", - "version": "1.4.1", - "version_normalized": "1.4.1.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/promises.git", - "reference": "8e7d04f1f6450fef59366c399cfad4b9383aa30d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/8e7d04f1f6450fef59366c399cfad4b9383aa30d", - "reference": "8e7d04f1f6450fef59366c399cfad4b9383aa30d", - "shasum": "" - }, - "require": { - "php": ">=5.5" - }, - "require-dev": { - "symfony/phpunit-bridge": "^4.4 || ^5.1" - }, - "time": "2021-03-07T09:25:29+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "GuzzleHttp\\Promise\\": "src/" - }, - "files": [ - "src/functions_include.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "description": "Guzzle promises library", - "keywords": [ - "promise" - ], - "support": { - "issues": "https://github.com/guzzle/promises/issues", - "source": "https://github.com/guzzle/promises/tree/1.4.1" - }, - "install-path": "../guzzlehttp/promises" - }, - { - "name": "guzzlehttp/psr7", - "version": "1.8.2", - "version_normalized": "1.8.2.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/psr7.git", - "reference": "dc960a912984efb74d0a90222870c72c87f10c91" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/dc960a912984efb74d0a90222870c72c87f10c91", - "reference": "dc960a912984efb74d0a90222870c72c87f10c91", - "shasum": "" - }, - "require": { - "php": ">=5.4.0", - "psr/http-message": "~1.0", - "ralouphie/getallheaders": "^2.0.5 || ^3.0.0" - }, - "provide": { - "psr/http-message-implementation": "1.0" - }, - "require-dev": { - "ext-zlib": "*", - "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10" - }, - "suggest": { - "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" - }, - "time": "2021-04-26T09:17:50+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.7-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "GuzzleHttp\\Psr7\\": "src/" - }, - "files": [ - "src/functions_include.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - }, - { - "name": "Tobias Schultze", - "homepage": "https://github.com/Tobion" - } - ], - "description": "PSR-7 message implementation that also provides common utility methods", - "keywords": [ - "http", - "message", - "psr-7", - "request", - "response", - "stream", - "uri", - "url" - ], - "support": { - "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/1.8.2" - }, - "install-path": "../guzzlehttp/psr7" - }, - { - "name": "myclabs/php-enum", - "version": "1.8.0", - "version_normalized": "1.8.0.0", - "source": { - "type": "git", - "url": "https://github.com/myclabs/php-enum.git", - "reference": "46cf3d8498b095bd33727b13fd5707263af99421" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/php-enum/zipball/46cf3d8498b095bd33727b13fd5707263af99421", - "reference": "46cf3d8498b095bd33727b13fd5707263af99421", - "shasum": "" - }, - "require": { - "ext-json": "*", - "php": "^7.3 || ^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.5", - "squizlabs/php_codesniffer": "1.*", - "vimeo/psalm": "^4.5.1" - }, - "time": "2021-02-15T16:11:48+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "MyCLabs\\Enum\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP Enum contributors", - "homepage": "https://github.com/myclabs/php-enum/graphs/contributors" - } - ], - "description": "PHP Enum implementation", - "homepage": "http://github.com/myclabs/php-enum", - "keywords": [ - "enum" - ], - "support": { - "issues": "https://github.com/myclabs/php-enum/issues", - "source": "https://github.com/myclabs/php-enum/tree/1.8.0" - }, - "funding": [ - { - "url": "https://github.com/mnapoli", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/myclabs/php-enum", - "type": "tidelift" - } - ], - "install-path": "../myclabs/php-enum" - }, - { - "name": "paquettg/php-html-parser", - "version": "3.1.1", - "version_normalized": "3.1.1.0", - "source": { - "type": "git", - "url": "https://github.com/paquettg/php-html-parser.git", - "reference": "4e01a438ad5961cc2d7427eb9798d213c8a12629" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/paquettg/php-html-parser/zipball/4e01a438ad5961cc2d7427eb9798d213c8a12629", - "reference": "4e01a438ad5961cc2d7427eb9798d213c8a12629", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "ext-mbstring": "*", - "ext-zlib": "*", - "guzzlehttp/guzzle": "^7.0", - "guzzlehttp/psr7": "^1.6", - "myclabs/php-enum": "^1.7", - "paquettg/string-encode": "~1.0.0", - "php": ">=7.2", - "php-http/httplug": "^2.1" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^2.16", - "infection/infection": "^0.13.4", - "mockery/mockery": "^1.2", - "phan/phan": "^2.4", - "phpunit/phpunit": "^7.5.1" - }, - "time": "2020-11-01T20:34:43+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "PHPHtmlParser\\": "src/PHPHtmlParser" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Gilles Paquette", - "email": "paquettg@gmail.com", - "homepage": "http://gillespaquette.ca" - } - ], - "description": "An HTML DOM parser. It allows you to manipulate HTML. Find tags on an HTML page with selectors just like jQuery.", - "homepage": "https://github.com/paquettg/php-html-parser", - "keywords": [ - "dom", - "html", - "parser" - ], - "support": { - "issues": "https://github.com/paquettg/php-html-parser/issues", - "source": "https://github.com/paquettg/php-html-parser/tree/3.1.1" - }, - "funding": [ - { - "url": "https://tidelift.com/funding/github/packagist/paquettg/php-html-parser", - "type": "tidelift" - } - ], - "install-path": "../paquettg/php-html-parser" - }, - { - "name": "paquettg/string-encode", - "version": "1.0.1", - "version_normalized": "1.0.1.0", - "source": { - "type": "git", - "url": "https://github.com/paquettg/string-encoder.git", - "reference": "a8708e9fac9d5ddfc8fc2aac6004e2cd05d80fee" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/paquettg/string-encoder/zipball/a8708e9fac9d5ddfc8fc2aac6004e2cd05d80fee", - "reference": "a8708e9fac9d5ddfc8fc2aac6004e2cd05d80fee", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.5.1" - }, - "time": "2018-12-21T02:25:09+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-0": { - "stringEncode": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Gilles Paquette", - "email": "paquettg@gmail.com", - "homepage": "http://gillespaquette.ca" - } - ], - "description": "Facilitating the process of altering string encoding in PHP.", - "homepage": "https://github.com/paquettg/string-encoder", - "keywords": [ - "charset", - "encoding", - "string" - ], - "support": { - "issues": "https://github.com/paquettg/string-encoder/issues", - "source": "https://github.com/paquettg/string-encoder/tree/1.0.1" - }, - "install-path": "../paquettg/string-encode" - }, - { - "name": "php-http/httplug", - "version": "2.2.0", - "version_normalized": "2.2.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-http/httplug.git", - "reference": "191a0a1b41ed026b717421931f8d3bd2514ffbf9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-http/httplug/zipball/191a0a1b41ed026b717421931f8d3bd2514ffbf9", - "reference": "191a0a1b41ed026b717421931f8d3bd2514ffbf9", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0", - "php-http/promise": "^1.1", - "psr/http-client": "^1.0", - "psr/http-message": "^1.0" - }, - "require-dev": { - "friends-of-phpspec/phpspec-code-coverage": "^4.1", - "phpspec/phpspec": "^5.1 || ^6.0" - }, - "time": "2020-07-13T15:43:23+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Http\\Client\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Eric GELOEN", - "email": "geloen.eric@gmail.com" - }, - { - "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com", - "homepage": "https://sagikazarmark.hu" - } - ], - "description": "HTTPlug, the HTTP client abstraction for PHP", - "homepage": "http://httplug.io", - "keywords": [ - "client", - "http" - ], - "support": { - "issues": "https://github.com/php-http/httplug/issues", - "source": "https://github.com/php-http/httplug/tree/master" - }, - "install-path": "../php-http/httplug" - }, - { - "name": "php-http/promise", - "version": "1.1.0", - "version_normalized": "1.1.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-http/promise.git", - "reference": "4c4c1f9b7289a2ec57cde7f1e9762a5789506f88" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-http/promise/zipball/4c4c1f9b7289a2ec57cde7f1e9762a5789506f88", - "reference": "4c4c1f9b7289a2ec57cde7f1e9762a5789506f88", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "friends-of-phpspec/phpspec-code-coverage": "^4.3.2", - "phpspec/phpspec": "^5.1.2 || ^6.2" - }, - "time": "2020-07-07T09:29:14+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Http\\Promise\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Joel Wurtz", - "email": "joel.wurtz@gmail.com" - }, - { - "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com" - } - ], - "description": "Promise used for asynchronous HTTP requests", - "homepage": "http://httplug.io", - "keywords": [ - "promise" - ], - "support": { - "issues": "https://github.com/php-http/promise/issues", - "source": "https://github.com/php-http/promise/tree/1.1.0" - }, - "install-path": "../php-http/promise" - }, - { - "name": "psr/http-client", - "version": "1.0.1", - "version_normalized": "1.0.1.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-client.git", - "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", - "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", - "shasum": "" - }, - "require": { - "php": "^7.0 || ^8.0", - "psr/http-message": "^1.0" - }, - "time": "2020-06-29T06:28:15+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Psr\\Http\\Client\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP clients", - "homepage": "https://github.com/php-fig/http-client", - "keywords": [ - "http", - "http-client", - "psr", - "psr-18" - ], - "support": { - "source": "https://github.com/php-fig/http-client/tree/master" - }, - "install-path": "../psr/http-client" - }, - { - "name": "psr/http-message", - "version": "1.0.1", - "version_normalized": "1.0.1.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "time": "2016-08-06T14:39:51+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Psr\\Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP messages", - "homepage": "https://github.com/php-fig/http-message", - "keywords": [ - "http", - "http-message", - "psr", - "psr-7", - "request", - "response" - ], - "support": { - "source": "https://github.com/php-fig/http-message/tree/master" - }, - "install-path": "../psr/http-message" - }, - { - "name": "ralouphie/getallheaders", - "version": "3.0.3", - "version_normalized": "3.0.3.0", - "source": { - "type": "git", - "url": "https://github.com/ralouphie/getallheaders.git", - "reference": "120b605dfeb996808c31b6477290a714d356e822" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", - "reference": "120b605dfeb996808c31b6477290a714d356e822", - "shasum": "" - }, - "require": { - "php": ">=5.6" - }, - "require-dev": { - "php-coveralls/php-coveralls": "^2.1", - "phpunit/phpunit": "^5 || ^6.5" - }, - "time": "2019-03-08T08:55:37+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "files": [ - "src/getallheaders.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ralph Khattar", - "email": "ralph.khattar@gmail.com" - } - ], - "description": "A polyfill for getallheaders.", - "support": { - "issues": "https://github.com/ralouphie/getallheaders/issues", - "source": "https://github.com/ralouphie/getallheaders/tree/develop" - }, - "install-path": "../ralouphie/getallheaders" - } - ], - "dev": true, - "dev-package-names": [] -} diff --git a/plugins/automagic-images/vendor/composer/installed.php b/plugins/automagic-images/vendor/composer/installed.php deleted file mode 100644 index 023bb6b..0000000 --- a/plugins/automagic-images/vendor/composer/installed.php +++ /dev/null @@ -1,137 +0,0 @@ - - array ( - 'pretty_version' => '1.0.0+no-version-set', - 'version' => '1.0.0.0', - 'aliases' => - array ( - ), - 'reference' => NULL, - 'name' => '__root__', - ), - 'versions' => - array ( - '__root__' => - array ( - 'pretty_version' => '1.0.0+no-version-set', - 'version' => '1.0.0.0', - 'aliases' => - array ( - ), - 'reference' => NULL, - ), - 'guzzlehttp/guzzle' => - array ( - 'pretty_version' => '7.3.0', - 'version' => '7.3.0.0', - 'aliases' => - array ( - ), - 'reference' => '7008573787b430c1c1f650e3722d9bba59967628', - ), - 'guzzlehttp/promises' => - array ( - 'pretty_version' => '1.4.1', - 'version' => '1.4.1.0', - 'aliases' => - array ( - ), - 'reference' => '8e7d04f1f6450fef59366c399cfad4b9383aa30d', - ), - 'guzzlehttp/psr7' => - array ( - 'pretty_version' => '1.8.2', - 'version' => '1.8.2.0', - 'aliases' => - array ( - ), - 'reference' => 'dc960a912984efb74d0a90222870c72c87f10c91', - ), - 'myclabs/php-enum' => - array ( - 'pretty_version' => '1.8.0', - 'version' => '1.8.0.0', - 'aliases' => - array ( - ), - 'reference' => '46cf3d8498b095bd33727b13fd5707263af99421', - ), - 'paquettg/php-html-parser' => - array ( - 'pretty_version' => '3.1.1', - 'version' => '3.1.1.0', - 'aliases' => - array ( - ), - 'reference' => '4e01a438ad5961cc2d7427eb9798d213c8a12629', - ), - 'paquettg/string-encode' => - array ( - 'pretty_version' => '1.0.1', - 'version' => '1.0.1.0', - 'aliases' => - array ( - ), - 'reference' => 'a8708e9fac9d5ddfc8fc2aac6004e2cd05d80fee', - ), - 'php-http/httplug' => - array ( - 'pretty_version' => '2.2.0', - 'version' => '2.2.0.0', - 'aliases' => - array ( - ), - 'reference' => '191a0a1b41ed026b717421931f8d3bd2514ffbf9', - ), - 'php-http/promise' => - array ( - 'pretty_version' => '1.1.0', - 'version' => '1.1.0.0', - 'aliases' => - array ( - ), - 'reference' => '4c4c1f9b7289a2ec57cde7f1e9762a5789506f88', - ), - 'psr/http-client' => - array ( - 'pretty_version' => '1.0.1', - 'version' => '1.0.1.0', - 'aliases' => - array ( - ), - 'reference' => '2dfb5f6c5eff0e91e20e913f8c5452ed95b86621', - ), - 'psr/http-client-implementation' => - array ( - 'provided' => - array ( - 0 => '1.0', - ), - ), - 'psr/http-message' => - array ( - 'pretty_version' => '1.0.1', - 'version' => '1.0.1.0', - 'aliases' => - array ( - ), - 'reference' => 'f6561bf28d520154e4b0ec72be95418abe6d9363', - ), - 'psr/http-message-implementation' => - array ( - 'provided' => - array ( - 0 => '1.0', - ), - ), - 'ralouphie/getallheaders' => - array ( - 'pretty_version' => '3.0.3', - 'version' => '3.0.3.0', - 'aliases' => - array ( - ), - 'reference' => '120b605dfeb996808c31b6477290a714d356e822', - ), - ), -); diff --git a/plugins/automagic-images/vendor/composer/platform_check.php b/plugins/automagic-images/vendor/composer/platform_check.php deleted file mode 100644 index 92370c5..0000000 --- a/plugins/automagic-images/vendor/composer/platform_check.php +++ /dev/null @@ -1,26 +0,0 @@ -= 70300)) { - $issues[] = 'Your Composer dependencies require a PHP version ">= 7.3.0". You are running ' . PHP_VERSION . '.'; -} - -if ($issues) { - if (!headers_sent()) { - header('HTTP/1.1 500 Internal Server Error'); - } - if (!ini_get('display_errors')) { - if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { - fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); - } elseif (!headers_sent()) { - echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; - } - } - trigger_error( - 'Composer detected issues in your platform: ' . implode(' ', $issues), - E_USER_ERROR - ); -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/guzzle/CHANGELOG.md b/plugins/automagic-images/vendor/guzzlehttp/guzzle/CHANGELOG.md deleted file mode 100644 index e303af2..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/guzzle/CHANGELOG.md +++ /dev/null @@ -1,1462 +0,0 @@ -# Change Log - -Please refer to [UPGRADING](UPGRADING.md) guide for upgrading to a major version. - -## 7.3.0 - 2021-03-23 - -### Added - -- Support for DER and P12 certificates [#2413](https://github.com/guzzle/guzzle/pull/2413) -- Support the cURL (http://) scheme for StreamHandler proxies [#2850](https://github.com/guzzle/guzzle/pull/2850) -- Support for `guzzlehttp/psr7:^2.0` [#2878](https://github.com/guzzle/guzzle/pull/2878) - -### Fixed - -- Handle exceptions on invalid header consistently between PHP versions and handlers [#2872](https://github.com/guzzle/guzzle/pull/2872) - -## 7.2.0 - 2020-10-10 - -### Added - -- Support for PHP 8 [#2712](https://github.com/guzzle/guzzle/pull/2712), [#2715](https://github.com/guzzle/guzzle/pull/2715), [#2789](https://github.com/guzzle/guzzle/pull/2789) -- Support passing a body summarizer to the http errors middleware [#2795](https://github.com/guzzle/guzzle/pull/2795) - -### Fixed - -- Handle exceptions during response creation [#2591](https://github.com/guzzle/guzzle/pull/2591) -- Fix CURLOPT_ENCODING not to be overwritten [#2595](https://github.com/guzzle/guzzle/pull/2595) -- Make sure the Request always has a body object [#2804](https://github.com/guzzle/guzzle/pull/2804) - -### Changed - -- The `TooManyRedirectsException` has a response [#2660](https://github.com/guzzle/guzzle/pull/2660) -- Avoid "functions" from dependencies [#2712](https://github.com/guzzle/guzzle/pull/2712) - -### Deprecated - -- Using environment variable GUZZLE_CURL_SELECT_TIMEOUT [#2786](https://github.com/guzzle/guzzle/pull/2786) - -## 7.1.1 - 2020-09-30 - -### Fixed - -- Incorrect EOF detection for response body streams on Windows. - -### Changed - -- We dont connect curl `sink` on HEAD requests. -- Removed some PHP 5 workarounds - -## 7.1.0 - 2020-09-22 - -### Added - -- `GuzzleHttp\MessageFormatterInterface` - -### Fixed - -- Fixed issue that caused cookies with no value not to be stored. -- On redirects, we allow all safe methods like GET, HEAD and OPTIONS. -- Fixed logging on empty responses. -- Make sure MessageFormatter::format returns string - -### Deprecated - -- All functions in `GuzzleHttp` has been deprecated. Use static methods on `Utils` instead. -- `ClientInterface::getConfig()` -- `Client::getConfig()` -- `Client::__call()` -- `Utils::defaultCaBundle()` -- `CurlFactory::LOW_CURL_VERSION_NUMBER` - -## 7.0.1 - 2020-06-27 - -* Fix multiply defined functions fatal error [#2699](https://github.com/guzzle/guzzle/pull/2699) - -## 7.0.0 - 2020-06-27 - -No changes since 7.0.0-rc1. - -## 7.0.0-rc1 - 2020-06-15 - -### Changed - -* Use error level for logging errors in Middleware [#2629](https://github.com/guzzle/guzzle/pull/2629) -* Disabled IDN support by default and require ext-intl to use it [#2675](https://github.com/guzzle/guzzle/pull/2675) - -## 7.0.0-beta2 - 2020-05-25 - -### Added - -* Using `Utils` class instead of functions in the `GuzzleHttp` namespace. [#2546](https://github.com/guzzle/guzzle/pull/2546) -* `ClientInterface::MAJOR_VERSION` [#2583](https://github.com/guzzle/guzzle/pull/2583) - -### Changed - -* Avoid the `getenv` function when unsafe [#2531](https://github.com/guzzle/guzzle/pull/2531) -* Added real client methods [#2529](https://github.com/guzzle/guzzle/pull/2529) -* Avoid functions due to global install conflicts [#2546](https://github.com/guzzle/guzzle/pull/2546) -* Use Symfony intl-idn polyfill [#2550](https://github.com/guzzle/guzzle/pull/2550) -* Adding methods for HTTP verbs like `Client::get()`, `Client::head()`, `Client::patch()` etc [#2529](https://github.com/guzzle/guzzle/pull/2529) -* `ConnectException` extends `TransferException` [#2541](https://github.com/guzzle/guzzle/pull/2541) -* Updated the default User Agent to "GuzzleHttp/7" [#2654](https://github.com/guzzle/guzzle/pull/2654) - -### Fixed - -* Various intl icu issues [#2626](https://github.com/guzzle/guzzle/pull/2626) - -### Removed - -* Pool option `pool_size` [#2528](https://github.com/guzzle/guzzle/pull/2528) - -## 7.0.0-beta1 - 2019-12-30 - -The diff might look very big but 95% of Guzzle users will be able to upgrade without modification. -Please see [the upgrade document](UPGRADING.md) that describes all BC breaking changes. - -### Added - -* Implement PSR-18 and dropped PHP 5 support [#2421](https://github.com/guzzle/guzzle/pull/2421) [#2474](https://github.com/guzzle/guzzle/pull/2474) -* PHP 7 types [#2442](https://github.com/guzzle/guzzle/pull/2442) [#2449](https://github.com/guzzle/guzzle/pull/2449) [#2466](https://github.com/guzzle/guzzle/pull/2466) [#2497](https://github.com/guzzle/guzzle/pull/2497) [#2499](https://github.com/guzzle/guzzle/pull/2499) -* IDN support for redirects [2424](https://github.com/guzzle/guzzle/pull/2424) - -### Changed - -* Dont allow passing null as third argument to `BadResponseException::__construct()` [#2427](https://github.com/guzzle/guzzle/pull/2427) -* Use SAPI constant instead of method call [#2450](https://github.com/guzzle/guzzle/pull/2450) -* Use native function invocation [#2444](https://github.com/guzzle/guzzle/pull/2444) -* Better defaults for PHP installations with old ICU lib [2454](https://github.com/guzzle/guzzle/pull/2454) -* Added visibility to all constants [#2462](https://github.com/guzzle/guzzle/pull/2462) -* Dont allow passing `null` as URI to `Client::request()` and `Client::requestAsync()` [#2461](https://github.com/guzzle/guzzle/pull/2461) -* Widen the exception argument to throwable [#2495](https://github.com/guzzle/guzzle/pull/2495) - -### Fixed - -* Logging when Promise rejected with a string [#2311](https://github.com/guzzle/guzzle/pull/2311) - -### Removed - -* Class `SeekException` [#2162](https://github.com/guzzle/guzzle/pull/2162) -* `RequestException::getResponseBodySummary()` [#2425](https://github.com/guzzle/guzzle/pull/2425) -* `CookieJar::getCookieValue()` [#2433](https://github.com/guzzle/guzzle/pull/2433) -* `uri_template()` and `UriTemplate` [#2440](https://github.com/guzzle/guzzle/pull/2440) -* Request options `save_to` and `exceptions` [#2464](https://github.com/guzzle/guzzle/pull/2464) - -## 6.5.2 - 2019-12-23 - -* idn_to_ascii() fix for old PHP versions [#2489](https://github.com/guzzle/guzzle/pull/2489) - -## 6.5.1 - 2019-12-21 - -* Better defaults for PHP installations with old ICU lib [#2454](https://github.com/guzzle/guzzle/pull/2454) -* IDN support for redirects [#2424](https://github.com/guzzle/guzzle/pull/2424) - -## 6.5.0 - 2019-12-07 - -* Improvement: Added support for reset internal queue in MockHandler. [#2143](https://github.com/guzzle/guzzle/pull/2143) -* Improvement: Added support to pass arbitrary options to `curl_multi_init`. [#2287](https://github.com/guzzle/guzzle/pull/2287) -* Fix: Gracefully handle passing `null` to the `header` option. [#2132](https://github.com/guzzle/guzzle/pull/2132) -* Fix: `RetryMiddleware` did not do exponential delay between retires due unit mismatch. [#2132](https://github.com/guzzle/guzzle/pull/2132) -* Fix: Prevent undefined offset when using array for ssl_key options. [#2348](https://github.com/guzzle/guzzle/pull/2348) -* Deprecated `ClientInterface::VERSION` - -## 6.4.1 - 2019-10-23 - -* No `guzzle.phar` was created in 6.4.0 due expired API token. This release will fix that -* Added `parent::__construct()` to `FileCookieJar` and `SessionCookieJar` - -## 6.4.0 - 2019-10-23 - -* Improvement: Improved error messages when using curl < 7.21.2 [#2108](https://github.com/guzzle/guzzle/pull/2108) -* Fix: Test if response is readable before returning a summary in `RequestException::getResponseBodySummary()` [#2081](https://github.com/guzzle/guzzle/pull/2081) -* Fix: Add support for GUZZLE_CURL_SELECT_TIMEOUT environment variable [#2161](https://github.com/guzzle/guzzle/pull/2161) -* Improvement: Added `GuzzleHttp\Exception\InvalidArgumentException` [#2163](https://github.com/guzzle/guzzle/pull/2163) -* Improvement: Added `GuzzleHttp\_current_time()` to use `hrtime()` if that function exists. [#2242](https://github.com/guzzle/guzzle/pull/2242) -* Improvement: Added curl's `appconnect_time` in `TransferStats` [#2284](https://github.com/guzzle/guzzle/pull/2284) -* Improvement: Make GuzzleException extend Throwable wherever it's available [#2273](https://github.com/guzzle/guzzle/pull/2273) -* Fix: Prevent concurrent writes to file when saving `CookieJar` [#2335](https://github.com/guzzle/guzzle/pull/2335) -* Improvement: Update `MockHandler` so we can test transfer time [#2362](https://github.com/guzzle/guzzle/pull/2362) - -## 6.3.3 - 2018-04-22 - -* Fix: Default headers when decode_content is specified - - -## 6.3.2 - 2018-03-26 - -* Fix: Release process - - -## 6.3.1 - 2018-03-26 - -* Bug fix: Parsing 0 epoch expiry times in cookies [#2014](https://github.com/guzzle/guzzle/pull/2014) -* Improvement: Better ConnectException detection [#2012](https://github.com/guzzle/guzzle/pull/2012) -* Bug fix: Malformed domain that contains a "/" [#1999](https://github.com/guzzle/guzzle/pull/1999) -* Bug fix: Undefined offset when a cookie has no first key-value pair [#1998](https://github.com/guzzle/guzzle/pull/1998) -* Improvement: Support PHPUnit 6 [#1953](https://github.com/guzzle/guzzle/pull/1953) -* Bug fix: Support empty headers [#1915](https://github.com/guzzle/guzzle/pull/1915) -* Bug fix: Ignore case during header modifications [#1916](https://github.com/guzzle/guzzle/pull/1916) - -+ Minor code cleanups, documentation fixes and clarifications. - - -## 6.3.0 - 2017-06-22 - -* Feature: force IP resolution (ipv4 or ipv6) [#1608](https://github.com/guzzle/guzzle/pull/1608), [#1659](https://github.com/guzzle/guzzle/pull/1659) -* Improvement: Don't include summary in exception message when body is empty [#1621](https://github.com/guzzle/guzzle/pull/1621) -* Improvement: Handle `on_headers` option in MockHandler [#1580](https://github.com/guzzle/guzzle/pull/1580) -* Improvement: Added SUSE Linux CA path [#1609](https://github.com/guzzle/guzzle/issues/1609) -* Improvement: Use class reference for getting the name of the class instead of using hardcoded strings [#1641](https://github.com/guzzle/guzzle/pull/1641) -* Feature: Added `read_timeout` option [#1611](https://github.com/guzzle/guzzle/pull/1611) -* Bug fix: PHP 7.x fixes [#1685](https://github.com/guzzle/guzzle/pull/1685), [#1686](https://github.com/guzzle/guzzle/pull/1686), [#1811](https://github.com/guzzle/guzzle/pull/1811) -* Deprecation: BadResponseException instantiation without a response [#1642](https://github.com/guzzle/guzzle/pull/1642) -* Feature: Added NTLM auth [#1569](https://github.com/guzzle/guzzle/pull/1569) -* Feature: Track redirect HTTP status codes [#1711](https://github.com/guzzle/guzzle/pull/1711) -* Improvement: Check handler type during construction [#1745](https://github.com/guzzle/guzzle/pull/1745) -* Improvement: Always include the Content-Length if there's a body [#1721](https://github.com/guzzle/guzzle/pull/1721) -* Feature: Added convenience method to access a cookie by name [#1318](https://github.com/guzzle/guzzle/pull/1318) -* Bug fix: Fill `CURLOPT_CAPATH` and `CURLOPT_CAINFO` properly [#1684](https://github.com/guzzle/guzzle/pull/1684) -* Improvement: Use `\GuzzleHttp\Promise\rejection_for` function instead of object init [#1827](https://github.com/guzzle/guzzle/pull/1827) - - -+ Minor code cleanups, documentation fixes and clarifications. - -## 6.2.3 - 2017-02-28 - -* Fix deprecations with guzzle/psr7 version 1.4 - -## 6.2.2 - 2016-10-08 - -* Allow to pass nullable Response to delay callable -* Only add scheme when host is present -* Fix drain case where content-length is the literal string zero -* Obfuscate in-URL credentials in exceptions - -## 6.2.1 - 2016-07-18 - -* Address HTTP_PROXY security vulnerability, CVE-2016-5385: - https://httpoxy.org/ -* Fixing timeout bug with StreamHandler: - https://github.com/guzzle/guzzle/pull/1488 -* Only read up to `Content-Length` in PHP StreamHandler to avoid timeouts when - a server does not honor `Connection: close`. -* Ignore URI fragment when sending requests. - -## 6.2.0 - 2016-03-21 - -* Feature: added `GuzzleHttp\json_encode` and `GuzzleHttp\json_decode`. - https://github.com/guzzle/guzzle/pull/1389 -* Bug fix: Fix sleep calculation when waiting for delayed requests. - https://github.com/guzzle/guzzle/pull/1324 -* Feature: More flexible history containers. - https://github.com/guzzle/guzzle/pull/1373 -* Bug fix: defer sink stream opening in StreamHandler. - https://github.com/guzzle/guzzle/pull/1377 -* Bug fix: do not attempt to escape cookie values. - https://github.com/guzzle/guzzle/pull/1406 -* Feature: report original content encoding and length on decoded responses. - https://github.com/guzzle/guzzle/pull/1409 -* Bug fix: rewind seekable request bodies before dispatching to cURL. - https://github.com/guzzle/guzzle/pull/1422 -* Bug fix: provide an empty string to `http_build_query` for HHVM workaround. - https://github.com/guzzle/guzzle/pull/1367 - -## 6.1.1 - 2015-11-22 - -* Bug fix: Proxy::wrapSync() now correctly proxies to the appropriate handler - https://github.com/guzzle/guzzle/commit/911bcbc8b434adce64e223a6d1d14e9a8f63e4e4 -* Feature: HandlerStack is now more generic. - https://github.com/guzzle/guzzle/commit/f2102941331cda544745eedd97fc8fd46e1ee33e -* Bug fix: setting verify to false in the StreamHandler now disables peer - verification. https://github.com/guzzle/guzzle/issues/1256 -* Feature: Middleware now uses an exception factory, including more error - context. https://github.com/guzzle/guzzle/pull/1282 -* Feature: better support for disabled functions. - https://github.com/guzzle/guzzle/pull/1287 -* Bug fix: fixed regression where MockHandler was not using `sink`. - https://github.com/guzzle/guzzle/pull/1292 - -## 6.1.0 - 2015-09-08 - -* Feature: Added the `on_stats` request option to provide access to transfer - statistics for requests. https://github.com/guzzle/guzzle/pull/1202 -* Feature: Added the ability to persist session cookies in CookieJars. - https://github.com/guzzle/guzzle/pull/1195 -* Feature: Some compatibility updates for Google APP Engine - https://github.com/guzzle/guzzle/pull/1216 -* Feature: Added support for NO_PROXY to prevent the use of a proxy based on - a simple set of rules. https://github.com/guzzle/guzzle/pull/1197 -* Feature: Cookies can now contain square brackets. - https://github.com/guzzle/guzzle/pull/1237 -* Bug fix: Now correctly parsing `=` inside of quotes in Cookies. - https://github.com/guzzle/guzzle/pull/1232 -* Bug fix: Cusotm cURL options now correctly override curl options of the - same name. https://github.com/guzzle/guzzle/pull/1221 -* Bug fix: Content-Type header is now added when using an explicitly provided - multipart body. https://github.com/guzzle/guzzle/pull/1218 -* Bug fix: Now ignoring Set-Cookie headers that have no name. -* Bug fix: Reason phrase is no longer cast to an int in some cases in the - cURL handler. https://github.com/guzzle/guzzle/pull/1187 -* Bug fix: Remove the Authorization header when redirecting if the Host - header changes. https://github.com/guzzle/guzzle/pull/1207 -* Bug fix: Cookie path matching fixes - https://github.com/guzzle/guzzle/issues/1129 -* Bug fix: Fixing the cURL `body_as_string` setting - https://github.com/guzzle/guzzle/pull/1201 -* Bug fix: quotes are no longer stripped when parsing cookies. - https://github.com/guzzle/guzzle/issues/1172 -* Bug fix: `form_params` and `query` now always uses the `&` separator. - https://github.com/guzzle/guzzle/pull/1163 -* Bug fix: Adding a Content-Length to PHP stream wrapper requests if not set. - https://github.com/guzzle/guzzle/pull/1189 - -## 6.0.2 - 2015-07-04 - -* Fixed a memory leak in the curl handlers in which references to callbacks - were not being removed by `curl_reset`. -* Cookies are now extracted properly before redirects. -* Cookies now allow more character ranges. -* Decoded Content-Encoding responses are now modified to correctly reflect - their state if the encoding was automatically removed by a handler. This - means that the `Content-Encoding` header may be removed an the - `Content-Length` modified to reflect the message size after removing the - encoding. -* Added a more explicit error message when trying to use `form_params` and - `multipart` in the same request. -* Several fixes for HHVM support. -* Functions are now conditionally required using an additional level of - indirection to help with global Composer installations. - -## 6.0.1 - 2015-05-27 - -* Fixed a bug with serializing the `query` request option where the `&` - separator was missing. -* Added a better error message for when `body` is provided as an array. Please - use `form_params` or `multipart` instead. -* Various doc fixes. - -## 6.0.0 - 2015-05-26 - -* See the UPGRADING.md document for more information. -* Added `multipart` and `form_params` request options. -* Added `synchronous` request option. -* Added the `on_headers` request option. -* Fixed `expect` handling. -* No longer adding default middlewares in the client ctor. These need to be - present on the provided handler in order to work. -* Requests are no longer initiated when sending async requests with the - CurlMultiHandler. This prevents unexpected recursion from requests completing - while ticking the cURL loop. -* Removed the semantics of setting `default` to `true`. This is no longer - required now that the cURL loop is not ticked for async requests. -* Added request and response logging middleware. -* No longer allowing self signed certificates when using the StreamHandler. -* Ensuring that `sink` is valid if saving to a file. -* Request exceptions now include a "handler context" which provides handler - specific contextual information. -* Added `GuzzleHttp\RequestOptions` to allow request options to be applied - using constants. -* `$maxHandles` has been removed from CurlMultiHandler. -* `MultipartPostBody` is now part of the `guzzlehttp/psr7` package. - -## 5.3.0 - 2015-05-19 - -* Mock now supports `save_to` -* Marked `AbstractRequestEvent::getTransaction()` as public. -* Fixed a bug in which multiple headers using different casing would overwrite - previous headers in the associative array. -* Added `Utils::getDefaultHandler()` -* Marked `GuzzleHttp\Client::getDefaultUserAgent` as deprecated. -* URL scheme is now always lowercased. - -## 6.0.0-beta.1 - -* Requires PHP >= 5.5 -* Updated to use PSR-7 - * Requires immutable messages, which basically means an event based system - owned by a request instance is no longer possible. - * Utilizing the [Guzzle PSR-7 package](https://github.com/guzzle/psr7). - * Removed the dependency on `guzzlehttp/streams`. These stream abstractions - are available in the `guzzlehttp/psr7` package under the `GuzzleHttp\Psr7` - namespace. -* Added middleware and handler system - * Replaced the Guzzle event and subscriber system with a middleware system. - * No longer depends on RingPHP, but rather places the HTTP handlers directly - in Guzzle, operating on PSR-7 messages. - * Retry logic is now encapsulated in `GuzzleHttp\Middleware::retry`, which - means the `guzzlehttp/retry-subscriber` is now obsolete. - * Mocking responses is now handled using `GuzzleHttp\Handler\MockHandler`. -* Asynchronous responses - * No longer supports the `future` request option to send an async request. - Instead, use one of the `*Async` methods of a client (e.g., `requestAsync`, - `getAsync`, etc.). - * Utilizing `GuzzleHttp\Promise` instead of React's promise library to avoid - recursion required by chaining and forwarding react promises. See - https://github.com/guzzle/promises - * Added `requestAsync` and `sendAsync` to send request asynchronously. - * Added magic methods for `getAsync()`, `postAsync()`, etc. to send requests - asynchronously. -* Request options - * POST and form updates - * Added the `form_fields` and `form_files` request options. - * Removed the `GuzzleHttp\Post` namespace. - * The `body` request option no longer accepts an array for POST requests. - * The `exceptions` request option has been deprecated in favor of the - `http_errors` request options. - * The `save_to` request option has been deprecated in favor of `sink` request - option. -* Clients no longer accept an array of URI template string and variables for - URI variables. You will need to expand URI templates before passing them - into a client constructor or request method. -* Client methods `get()`, `post()`, `put()`, `patch()`, `options()`, etc. are - now magic methods that will send synchronous requests. -* Replaced `Utils.php` with plain functions in `functions.php`. -* Removed `GuzzleHttp\Collection`. -* Removed `GuzzleHttp\BatchResults`. Batched pool results are now returned as - an array. -* Removed `GuzzleHttp\Query`. Query string handling is now handled using an - associative array passed into the `query` request option. The query string - is serialized using PHP's `http_build_query`. If you need more control, you - can pass the query string in as a string. -* `GuzzleHttp\QueryParser` has been replaced with the - `GuzzleHttp\Psr7\parse_query`. - -## 5.2.0 - 2015-01-27 - -* Added `AppliesHeadersInterface` to make applying headers to a request based - on the body more generic and not specific to `PostBodyInterface`. -* Reduced the number of stack frames needed to send requests. -* Nested futures are now resolved in the client rather than the RequestFsm -* Finishing state transitions is now handled in the RequestFsm rather than the - RingBridge. -* Added a guard in the Pool class to not use recursion for request retries. - -## 5.1.0 - 2014-12-19 - -* Pool class no longer uses recursion when a request is intercepted. -* The size of a Pool can now be dynamically adjusted using a callback. - See https://github.com/guzzle/guzzle/pull/943. -* Setting a request option to `null` when creating a request with a client will - ensure that the option is not set. This allows you to overwrite default - request options on a per-request basis. - See https://github.com/guzzle/guzzle/pull/937. -* Added the ability to limit which protocols are allowed for redirects by - specifying a `protocols` array in the `allow_redirects` request option. -* Nested futures due to retries are now resolved when waiting for synchronous - responses. See https://github.com/guzzle/guzzle/pull/947. -* `"0"` is now an allowed URI path. See - https://github.com/guzzle/guzzle/pull/935. -* `Query` no longer typehints on the `$query` argument in the constructor, - allowing for strings and arrays. -* Exceptions thrown in the `end` event are now correctly wrapped with Guzzle - specific exceptions if necessary. - -## 5.0.3 - 2014-11-03 - -This change updates query strings so that they are treated as un-encoded values -by default where the value represents an un-encoded value to send over the -wire. A Query object then encodes the value before sending over the wire. This -means that even value query string values (e.g., ":") are url encoded. This -makes the Query class match PHP's http_build_query function. However, if you -want to send requests over the wire using valid query string characters that do -not need to be encoded, then you can provide a string to Url::setQuery() and -pass true as the second argument to specify that the query string is a raw -string that should not be parsed or encoded (unless a call to getQuery() is -subsequently made, forcing the query-string to be converted into a Query -object). - -## 5.0.2 - 2014-10-30 - -* Added a trailing `\r\n` to multipart/form-data payloads. See - https://github.com/guzzle/guzzle/pull/871 -* Added a `GuzzleHttp\Pool::send()` convenience method to match the docs. -* Status codes are now returned as integers. See - https://github.com/guzzle/guzzle/issues/881 -* No longer overwriting an existing `application/x-www-form-urlencoded` header - when sending POST requests, allowing for customized headers. See - https://github.com/guzzle/guzzle/issues/877 -* Improved path URL serialization. - - * No longer double percent-encoding characters in the path or query string if - they are already encoded. - * Now properly encoding the supplied path to a URL object, instead of only - encoding ' ' and '?'. - * Note: This has been changed in 5.0.3 to now encode query string values by - default unless the `rawString` argument is provided when setting the query - string on a URL: Now allowing many more characters to be present in the - query string without being percent encoded. See https://tools.ietf.org/html/rfc3986#appendix-A - -## 5.0.1 - 2014-10-16 - -Bugfix release. - -* Fixed an issue where connection errors still returned response object in - error and end events event though the response is unusable. This has been - corrected so that a response is not returned in the `getResponse` method of - these events if the response did not complete. https://github.com/guzzle/guzzle/issues/867 -* Fixed an issue where transfer statistics were not being populated in the - RingBridge. https://github.com/guzzle/guzzle/issues/866 - -## 5.0.0 - 2014-10-12 - -Adding support for non-blocking responses and some minor API cleanup. - -### New Features - -* Added support for non-blocking responses based on `guzzlehttp/guzzle-ring`. -* Added a public API for creating a default HTTP adapter. -* Updated the redirect plugin to be non-blocking so that redirects are sent - concurrently. Other plugins like this can now be updated to be non-blocking. -* Added a "progress" event so that you can get upload and download progress - events. -* Added `GuzzleHttp\Pool` which implements FutureInterface and transfers - requests concurrently using a capped pool size as efficiently as possible. -* Added `hasListeners()` to EmitterInterface. -* Removed `GuzzleHttp\ClientInterface::sendAll` and marked - `GuzzleHttp\Client::sendAll` as deprecated (it's still there, just not the - recommended way). - -### Breaking changes - -The breaking changes in this release are relatively minor. The biggest thing to -look out for is that request and response objects no longer implement fluent -interfaces. - -* Removed the fluent interfaces (i.e., `return $this`) from requests, - responses, `GuzzleHttp\Collection`, `GuzzleHttp\Url`, - `GuzzleHttp\Query`, `GuzzleHttp\Post\PostBody`, and - `GuzzleHttp\Cookie\SetCookie`. This blog post provides a good outline of - why I did this: https://ocramius.github.io/blog/fluent-interfaces-are-evil/. - This also makes the Guzzle message interfaces compatible with the current - PSR-7 message proposal. -* Removed "functions.php", so that Guzzle is truly PSR-4 compliant. Except - for the HTTP request functions from function.php, these functions are now - implemented in `GuzzleHttp\Utils` using camelCase. `GuzzleHttp\json_decode` - moved to `GuzzleHttp\Utils::jsonDecode`. `GuzzleHttp\get_path` moved to - `GuzzleHttp\Utils::getPath`. `GuzzleHttp\set_path` moved to - `GuzzleHttp\Utils::setPath`. `GuzzleHttp\batch` should now be - `GuzzleHttp\Pool::batch`, which returns an `objectStorage`. Using functions.php - caused problems for many users: they aren't PSR-4 compliant, require an - explicit include, and needed an if-guard to ensure that the functions are not - declared multiple times. -* Rewrote adapter layer. - * Removing all classes from `GuzzleHttp\Adapter`, these are now - implemented as callables that are stored in `GuzzleHttp\Ring\Client`. - * Removed the concept of "parallel adapters". Sending requests serially or - concurrently is now handled using a single adapter. - * Moved `GuzzleHttp\Adapter\Transaction` to `GuzzleHttp\Transaction`. The - Transaction object now exposes the request, response, and client as public - properties. The getters and setters have been removed. -* Removed the "headers" event. This event was only useful for changing the - body a response once the headers of the response were known. You can implement - a similar behavior in a number of ways. One example might be to use a - FnStream that has access to the transaction being sent. For example, when the - first byte is written, you could check if the response headers match your - expectations, and if so, change the actual stream body that is being - written to. -* Removed the `asArray` parameter from - `GuzzleHttp\Message\MessageInterface::getHeader`. If you want to get a header - value as an array, then use the newly added `getHeaderAsArray()` method of - `MessageInterface`. This change makes the Guzzle interfaces compatible with - the PSR-7 interfaces. -* `GuzzleHttp\Message\MessageFactory` no longer allows subclasses to add - custom request options using double-dispatch (this was an implementation - detail). Instead, you should now provide an associative array to the - constructor which is a mapping of the request option name mapping to a - function that applies the option value to a request. -* Removed the concept of "throwImmediately" from exceptions and error events. - This control mechanism was used to stop a transfer of concurrent requests - from completing. This can now be handled by throwing the exception or by - cancelling a pool of requests or each outstanding future request individually. -* Updated to "GuzzleHttp\Streams" 3.0. - * `GuzzleHttp\Stream\StreamInterface::getContents()` no longer accepts a - `maxLen` parameter. This update makes the Guzzle streams project - compatible with the current PSR-7 proposal. - * `GuzzleHttp\Stream\Stream::__construct`, - `GuzzleHttp\Stream\Stream::factory`, and - `GuzzleHttp\Stream\Utils::create` no longer accept a size in the second - argument. They now accept an associative array of options, including the - "size" key and "metadata" key which can be used to provide custom metadata. - -## 4.2.2 - 2014-09-08 - -* Fixed a memory leak in the CurlAdapter when reusing cURL handles. -* No longer using `request_fulluri` in stream adapter proxies. -* Relative redirects are now based on the last response, not the first response. - -## 4.2.1 - 2014-08-19 - -* Ensuring that the StreamAdapter does not always add a Content-Type header -* Adding automated github releases with a phar and zip - -## 4.2.0 - 2014-08-17 - -* Now merging in default options using a case-insensitive comparison. - Closes https://github.com/guzzle/guzzle/issues/767 -* Added the ability to automatically decode `Content-Encoding` response bodies - using the `decode_content` request option. This is set to `true` by default - to decode the response body if it comes over the wire with a - `Content-Encoding`. Set this value to `false` to disable decoding the - response content, and pass a string to provide a request `Accept-Encoding` - header and turn on automatic response decoding. This feature now allows you - to pass an `Accept-Encoding` header in the headers of a request but still - disable automatic response decoding. - Closes https://github.com/guzzle/guzzle/issues/764 -* Added the ability to throw an exception immediately when transferring - requests in parallel. Closes https://github.com/guzzle/guzzle/issues/760 -* Updating guzzlehttp/streams dependency to ~2.1 -* No longer utilizing the now deprecated namespaced methods from the stream - package. - -## 4.1.8 - 2014-08-14 - -* Fixed an issue in the CurlFactory that caused setting the `stream=false` - request option to throw an exception. - See: https://github.com/guzzle/guzzle/issues/769 -* TransactionIterator now calls rewind on the inner iterator. - See: https://github.com/guzzle/guzzle/pull/765 -* You can now set the `Content-Type` header to `multipart/form-data` - when creating POST requests to force multipart bodies. - See https://github.com/guzzle/guzzle/issues/768 - -## 4.1.7 - 2014-08-07 - -* Fixed an error in the HistoryPlugin that caused the same request and response - to be logged multiple times when an HTTP protocol error occurs. -* Ensuring that cURL does not add a default Content-Type when no Content-Type - has been supplied by the user. This prevents the adapter layer from modifying - the request that is sent over the wire after any listeners may have already - put the request in a desired state (e.g., signed the request). -* Throwing an exception when you attempt to send requests that have the - "stream" set to true in parallel using the MultiAdapter. -* Only calling curl_multi_select when there are active cURL handles. This was - previously changed and caused performance problems on some systems due to PHP - always selecting until the maximum select timeout. -* Fixed a bug where multipart/form-data POST fields were not correctly - aggregated (e.g., values with "&"). - -## 4.1.6 - 2014-08-03 - -* Added helper methods to make it easier to represent messages as strings, - including getting the start line and getting headers as a string. - -## 4.1.5 - 2014-08-02 - -* Automatically retrying cURL "Connection died, retrying a fresh connect" - errors when possible. -* cURL implementation cleanup -* Allowing multiple event subscriber listeners to be registered per event by - passing an array of arrays of listener configuration. - -## 4.1.4 - 2014-07-22 - -* Fixed a bug that caused multi-part POST requests with more than one field to - serialize incorrectly. -* Paths can now be set to "0" -* `ResponseInterface::xml` now accepts a `libxml_options` option and added a - missing default argument that was required when parsing XML response bodies. -* A `save_to` stream is now created lazily, which means that files are not - created on disk unless a request succeeds. - -## 4.1.3 - 2014-07-15 - -* Various fixes to multipart/form-data POST uploads -* Wrapping function.php in an if-statement to ensure Guzzle can be used - globally and in a Composer install -* Fixed an issue with generating and merging in events to an event array -* POST headers are only applied before sending a request to allow you to change - the query aggregator used before uploading -* Added much more robust query string parsing -* Fixed various parsing and normalization issues with URLs -* Fixing an issue where multi-valued headers were not being utilized correctly - in the StreamAdapter - -## 4.1.2 - 2014-06-18 - -* Added support for sending payloads with GET requests - -## 4.1.1 - 2014-06-08 - -* Fixed an issue related to using custom message factory options in subclasses -* Fixed an issue with nested form fields in a multi-part POST -* Fixed an issue with using the `json` request option for POST requests -* Added `ToArrayInterface` to `GuzzleHttp\Cookie\CookieJar` - -## 4.1.0 - 2014-05-27 - -* Added a `json` request option to easily serialize JSON payloads. -* Added a `GuzzleHttp\json_decode()` wrapper to safely parse JSON. -* Added `setPort()` and `getPort()` to `GuzzleHttp\Message\RequestInterface`. -* Added the ability to provide an emitter to a client in the client constructor. -* Added the ability to persist a cookie session using $_SESSION. -* Added a trait that can be used to add event listeners to an iterator. -* Removed request method constants from RequestInterface. -* Fixed warning when invalid request start-lines are received. -* Updated MessageFactory to work with custom request option methods. -* Updated cacert bundle to latest build. - -4.0.2 (2014-04-16) ------------------- - -* Proxy requests using the StreamAdapter now properly use request_fulluri (#632) -* Added the ability to set scalars as POST fields (#628) - -## 4.0.1 - 2014-04-04 - -* The HTTP status code of a response is now set as the exception code of - RequestException objects. -* 303 redirects will now correctly switch from POST to GET requests. -* The default parallel adapter of a client now correctly uses the MultiAdapter. -* HasDataTrait now initializes the internal data array as an empty array so - that the toArray() method always returns an array. - -## 4.0.0 - 2014-03-29 - -* For information on changes and upgrading, see: - https://github.com/guzzle/guzzle/blob/master/UPGRADING.md#3x-to-40 -* Added `GuzzleHttp\batch()` as a convenience function for sending requests in - parallel without needing to write asynchronous code. -* Restructured how events are added to `GuzzleHttp\ClientInterface::sendAll()`. - You can now pass a callable or an array of associative arrays where each - associative array contains the "fn", "priority", and "once" keys. - -## 4.0.0.rc-2 - 2014-03-25 - -* Removed `getConfig()` and `setConfig()` from clients to avoid confusion - around whether things like base_url, message_factory, etc. should be able to - be retrieved or modified. -* Added `getDefaultOption()` and `setDefaultOption()` to ClientInterface -* functions.php functions were renamed using snake_case to match PHP idioms -* Added support for `HTTP_PROXY`, `HTTPS_PROXY`, and - `GUZZLE_CURL_SELECT_TIMEOUT` environment variables -* Added the ability to specify custom `sendAll()` event priorities -* Added the ability to specify custom stream context options to the stream - adapter. -* Added a functions.php function for `get_path()` and `set_path()` -* CurlAdapter and MultiAdapter now use a callable to generate curl resources -* MockAdapter now properly reads a body and emits a `headers` event -* Updated Url class to check if a scheme and host are set before adding ":" - and "//". This allows empty Url (e.g., "") to be serialized as "". -* Parsing invalid XML no longer emits warnings -* Curl classes now properly throw AdapterExceptions -* Various performance optimizations -* Streams are created with the faster `Stream\create()` function -* Marked deprecation_proxy() as internal -* Test server is now a collection of static methods on a class - -## 4.0.0-rc.1 - 2014-03-15 - -* See https://github.com/guzzle/guzzle/blob/master/UPGRADING.md#3x-to-40 - -## 3.8.1 - 2014-01-28 - -* Bug: Always using GET requests when redirecting from a 303 response -* Bug: CURLOPT_SSL_VERIFYHOST is now correctly set to false when setting `$certificateAuthority` to false in - `Guzzle\Http\ClientInterface::setSslVerification()` -* Bug: RedirectPlugin now uses strict RFC 3986 compliance when combining a base URL with a relative URL -* Bug: The body of a request can now be set to `"0"` -* Sending PHP stream requests no longer forces `HTTP/1.0` -* Adding more information to ExceptionCollection exceptions so that users have more context, including a stack trace of - each sub-exception -* Updated the `$ref` attribute in service descriptions to merge over any existing parameters of a schema (rather than - clobbering everything). -* Merging URLs will now use the query string object from the relative URL (thus allowing custom query aggregators) -* Query strings are now parsed in a way that they do no convert empty keys with no value to have a dangling `=`. - For example `foo&bar=baz` is now correctly parsed and recognized as `foo&bar=baz` rather than `foo=&bar=baz`. -* Now properly escaping the regular expression delimiter when matching Cookie domains. -* Network access is now disabled when loading XML documents - -## 3.8.0 - 2013-12-05 - -* Added the ability to define a POST name for a file -* JSON response parsing now properly walks additionalProperties -* cURL error code 18 is now retried automatically in the BackoffPlugin -* Fixed a cURL error when URLs contain fragments -* Fixed an issue in the BackoffPlugin retry event where it was trying to access all exceptions as if they were - CurlExceptions -* CURLOPT_PROGRESS function fix for PHP 5.5 (69fcc1e) -* Added the ability for Guzzle to work with older versions of cURL that do not support `CURLOPT_TIMEOUT_MS` -* Fixed a bug that was encountered when parsing empty header parameters -* UriTemplate now has a `setRegex()` method to match the docs -* The `debug` request parameter now checks if it is truthy rather than if it exists -* Setting the `debug` request parameter to true shows verbose cURL output instead of using the LogPlugin -* Added the ability to combine URLs using strict RFC 3986 compliance -* Command objects can now return the validation errors encountered by the command -* Various fixes to cache revalidation (#437 and 29797e5) -* Various fixes to the AsyncPlugin -* Cleaned up build scripts - -## 3.7.4 - 2013-10-02 - -* Bug fix: 0 is now an allowed value in a description parameter that has a default value (#430) -* Bug fix: SchemaFormatter now returns an integer when formatting to a Unix timestamp - (see https://github.com/aws/aws-sdk-php/issues/147) -* Bug fix: Cleaned up and fixed URL dot segment removal to properly resolve internal dots -* Minimum PHP version is now properly specified as 5.3.3 (up from 5.3.2) (#420) -* Updated the bundled cacert.pem (#419) -* OauthPlugin now supports adding authentication to headers or query string (#425) - -## 3.7.3 - 2013-09-08 - -* Added the ability to get the exception associated with a request/command when using `MultiTransferException` and - `CommandTransferException`. -* Setting `additionalParameters` of a response to false is now honored when parsing responses with a service description -* Schemas are only injected into response models when explicitly configured. -* No longer guessing Content-Type based on the path of a request. Content-Type is now only guessed based on the path of - an EntityBody. -* Bug fix: ChunkedIterator can now properly chunk a \Traversable as well as an \Iterator. -* Bug fix: FilterIterator now relies on `\Iterator` instead of `\Traversable`. -* Bug fix: Gracefully handling malformed responses in RequestMediator::writeResponseBody() -* Bug fix: Replaced call to canCache with canCacheRequest in the CallbackCanCacheStrategy of the CachePlugin -* Bug fix: Visiting XML attributes first before visiting XML children when serializing requests -* Bug fix: Properly parsing headers that contain commas contained in quotes -* Bug fix: mimetype guessing based on a filename is now case-insensitive - -## 3.7.2 - 2013-08-02 - -* Bug fix: Properly URL encoding paths when using the PHP-only version of the UriTemplate expander - See https://github.com/guzzle/guzzle/issues/371 -* Bug fix: Cookie domains are now matched correctly according to RFC 6265 - See https://github.com/guzzle/guzzle/issues/377 -* Bug fix: GET parameters are now used when calculating an OAuth signature -* Bug fix: Fixed an issue with cache revalidation where the If-None-Match header was being double quoted -* `Guzzle\Common\AbstractHasDispatcher::dispatch()` now returns the event that was dispatched -* `Guzzle\Http\QueryString::factory()` now guesses the most appropriate query aggregator to used based on the input. - See https://github.com/guzzle/guzzle/issues/379 -* Added a way to add custom domain objects to service description parsing using the `operation.parse_class` event. See - https://github.com/guzzle/guzzle/pull/380 -* cURL multi cleanup and optimizations - -## 3.7.1 - 2013-07-05 - -* Bug fix: Setting default options on a client now works -* Bug fix: Setting options on HEAD requests now works. See #352 -* Bug fix: Moving stream factory before send event to before building the stream. See #353 -* Bug fix: Cookies no longer match on IP addresses per RFC 6265 -* Bug fix: Correctly parsing header parameters that are in `<>` and quotes -* Added `cert` and `ssl_key` as request options -* `Host` header can now diverge from the host part of a URL if the header is set manually -* `Guzzle\Service\Command\LocationVisitor\Request\XmlVisitor` was rewritten to change from using SimpleXML to XMLWriter -* OAuth parameters are only added via the plugin if they aren't already set -* Exceptions are now thrown when a URL cannot be parsed -* Returning `false` if `Guzzle\Http\EntityBody::getContentMd5()` fails -* Not setting a `Content-MD5` on a command if calculating the Content-MD5 fails via the CommandContentMd5Plugin - -## 3.7.0 - 2013-06-10 - -* See UPGRADING.md for more information on how to upgrade. -* Requests now support the ability to specify an array of $options when creating a request to more easily modify a - request. You can pass a 'request.options' configuration setting to a client to apply default request options to - every request created by a client (e.g. default query string variables, headers, curl options, etc.). -* Added a static facade class that allows you to use Guzzle with static methods and mount the class to `\Guzzle`. - See `Guzzle\Http\StaticClient::mount`. -* Added `command.request_options` to `Guzzle\Service\Command\AbstractCommand` to pass request options to requests - created by a command (e.g. custom headers, query string variables, timeout settings, etc.). -* Stream size in `Guzzle\Stream\PhpStreamRequestFactory` will now be set if Content-Length is returned in the - headers of a response -* Added `Guzzle\Common\Collection::setPath($path, $value)` to set a value into an array using a nested key - (e.g. `$collection->setPath('foo/baz/bar', 'test'); echo $collection['foo']['bar']['bar'];`) -* ServiceBuilders now support storing and retrieving arbitrary data -* CachePlugin can now purge all resources for a given URI -* CachePlugin can automatically purge matching cached items when a non-idempotent request is sent to a resource -* CachePlugin now uses the Vary header to determine if a resource is a cache hit -* `Guzzle\Http\Message\Response` now implements `\Serializable` -* Added `Guzzle\Cache\CacheAdapterFactory::fromCache()` to more easily create cache adapters -* `Guzzle\Service\ClientInterface::execute()` now accepts an array, single command, or Traversable -* Fixed a bug in `Guzzle\Http\Message\Header\Link::addLink()` -* Better handling of calculating the size of a stream in `Guzzle\Stream\Stream` using fstat() and caching the size -* `Guzzle\Common\Exception\ExceptionCollection` now creates a more readable exception message -* Fixing BC break: Added back the MonologLogAdapter implementation rather than extending from PsrLog so that older - Symfony users can still use the old version of Monolog. -* Fixing BC break: Added the implementation back in for `Guzzle\Http\Message\AbstractMessage::getTokenizedHeader()`. - Now triggering an E_USER_DEPRECATED warning when used. Use `$message->getHeader()->parseParams()`. -* Several performance improvements to `Guzzle\Common\Collection` -* Added an `$options` argument to the end of the following methods of `Guzzle\Http\ClientInterface`: - createRequest, head, delete, put, patch, post, options, prepareRequest -* Added an `$options` argument to the end of `Guzzle\Http\Message\Request\RequestFactoryInterface::createRequest()` -* Added an `applyOptions()` method to `Guzzle\Http\Message\Request\RequestFactoryInterface` -* Changed `Guzzle\Http\ClientInterface::get($uri = null, $headers = null, $body = null)` to - `Guzzle\Http\ClientInterface::get($uri = null, $headers = null, $options = array())`. You can still pass in a - resource, string, or EntityBody into the $options parameter to specify the download location of the response. -* Changed `Guzzle\Common\Collection::__construct($data)` to no longer accepts a null value for `$data` but a - default `array()` -* Added `Guzzle\Stream\StreamInterface::isRepeatable` -* Removed `Guzzle\Http\ClientInterface::setDefaultHeaders(). Use - $client->getConfig()->setPath('request.options/headers/{header_name}', 'value')`. or - $client->getConfig()->setPath('request.options/headers', array('header_name' => 'value'))`. -* Removed `Guzzle\Http\ClientInterface::getDefaultHeaders(). Use $client->getConfig()->getPath('request.options/headers')`. -* Removed `Guzzle\Http\ClientInterface::expandTemplate()` -* Removed `Guzzle\Http\ClientInterface::setRequestFactory()` -* Removed `Guzzle\Http\ClientInterface::getCurlMulti()` -* Removed `Guzzle\Http\Message\RequestInterface::canCache` -* Removed `Guzzle\Http\Message\RequestInterface::setIsRedirect` -* Removed `Guzzle\Http\Message\RequestInterface::isRedirect` -* Made `Guzzle\Http\Client::expandTemplate` and `getUriTemplate` protected methods. -* You can now enable E_USER_DEPRECATED warnings to see if you are using a deprecated method by setting - `Guzzle\Common\Version::$emitWarnings` to true. -* Marked `Guzzle\Http\Message\Request::isResponseBodyRepeatable()` as deprecated. Use - `$request->getResponseBody()->isRepeatable()` instead. -* Marked `Guzzle\Http\Message\Request::canCache()` as deprecated. Use - `Guzzle\Plugin\Cache\DefaultCanCacheStrategy->canCacheRequest()` instead. -* Marked `Guzzle\Http\Message\Request::canCache()` as deprecated. Use - `Guzzle\Plugin\Cache\DefaultCanCacheStrategy->canCacheRequest()` instead. -* Marked `Guzzle\Http\Message\Request::setIsRedirect()` as deprecated. Use the HistoryPlugin instead. -* Marked `Guzzle\Http\Message\Request::isRedirect()` as deprecated. Use the HistoryPlugin instead. -* Marked `Guzzle\Cache\CacheAdapterFactory::factory()` as deprecated -* Marked 'command.headers', 'command.response_body' and 'command.on_complete' as deprecated for AbstractCommand. - These will work through Guzzle 4.0 -* Marked 'request.params' for `Guzzle\Http\Client` as deprecated. Use [request.options][params]. -* Marked `Guzzle\Service\Client::enableMagicMethods()` as deprecated. Magic methods can no longer be disabled on a Guzzle\Service\Client. -* Marked `Guzzle\Service\Client::getDefaultHeaders()` as deprecated. Use $client->getConfig()->getPath('request.options/headers')`. -* Marked `Guzzle\Service\Client::setDefaultHeaders()` as deprecated. Use $client->getConfig()->setPath('request.options/headers/{header_name}', 'value')`. -* Marked `Guzzle\Parser\Url\UrlParser` as deprecated. Just use PHP's `parse_url()` and percent encode your UTF-8. -* Marked `Guzzle\Common\Collection::inject()` as deprecated. -* Marked `Guzzle\Plugin\CurlAuth\CurlAuthPlugin` as deprecated. Use `$client->getConfig()->setPath('request.options/auth', array('user', 'pass', 'Basic|Digest');` -* CacheKeyProviderInterface and DefaultCacheKeyProvider are no longer used. All of this logic is handled in a - CacheStorageInterface. These two objects and interface will be removed in a future version. -* Always setting X-cache headers on cached responses -* Default cache TTLs are now handled by the CacheStorageInterface of a CachePlugin -* `CacheStorageInterface::cache($key, Response $response, $ttl = null)` has changed to `cache(RequestInterface - $request, Response $response);` -* `CacheStorageInterface::fetch($key)` has changed to `fetch(RequestInterface $request);` -* `CacheStorageInterface::delete($key)` has changed to `delete(RequestInterface $request);` -* Added `CacheStorageInterface::purge($url)` -* `DefaultRevalidation::__construct(CacheKeyProviderInterface $cacheKey, CacheStorageInterface $cache, CachePlugin - $plugin)` has changed to `DefaultRevalidation::__construct(CacheStorageInterface $cache, - CanCacheStrategyInterface $canCache = null)` -* Added `RevalidationInterface::shouldRevalidate(RequestInterface $request, Response $response)` - -## 3.6.0 - 2013-05-29 - -* ServiceDescription now implements ToArrayInterface -* Added command.hidden_params to blacklist certain headers from being treated as additionalParameters -* Guzzle can now correctly parse incomplete URLs -* Mixed casing of headers are now forced to be a single consistent casing across all values for that header. -* Messages internally use a HeaderCollection object to delegate handling case-insensitive header resolution -* Removed the whole changedHeader() function system of messages because all header changes now go through addHeader(). -* Specific header implementations can be created for complex headers. When a message creates a header, it uses a - HeaderFactory which can map specific headers to specific header classes. There is now a Link header and - CacheControl header implementation. -* Removed from interface: Guzzle\Http\ClientInterface::setUriTemplate -* Removed from interface: Guzzle\Http\ClientInterface::setCurlMulti() -* Removed Guzzle\Http\Message\Request::receivedRequestHeader() and implemented this functionality in - Guzzle\Http\Curl\RequestMediator -* Removed the optional $asString parameter from MessageInterface::getHeader(). Just cast the header to a string. -* Removed the optional $tryChunkedTransfer option from Guzzle\Http\Message\EntityEnclosingRequestInterface -* Removed the $asObjects argument from Guzzle\Http\Message\MessageInterface::getHeaders() -* Removed Guzzle\Parser\ParserRegister::get(). Use getParser() -* Removed Guzzle\Parser\ParserRegister::set(). Use registerParser(). -* All response header helper functions return a string rather than mixing Header objects and strings inconsistently -* Removed cURL blacklist support. This is no longer necessary now that Expect, Accept, etc. are managed by Guzzle - directly via interfaces -* Removed the injecting of a request object onto a response object. The methods to get and set a request still exist - but are a no-op until removed. -* Most classes that used to require a `Guzzle\Service\Command\CommandInterface` typehint now request a - `Guzzle\Service\Command\ArrayCommandInterface`. -* Added `Guzzle\Http\Message\RequestInterface::startResponse()` to the RequestInterface to handle injecting a response - on a request while the request is still being transferred -* The ability to case-insensitively search for header values -* Guzzle\Http\Message\Header::hasExactHeader -* Guzzle\Http\Message\Header::raw. Use getAll() -* Deprecated cache control specific methods on Guzzle\Http\Message\AbstractMessage. Use the CacheControl header object - instead. -* `Guzzle\Service\Command\CommandInterface` now extends from ToArrayInterface and ArrayAccess -* Added the ability to cast Model objects to a string to view debug information. - -## 3.5.0 - 2013-05-13 - -* Bug: Fixed a regression so that request responses are parsed only once per oncomplete event rather than multiple times -* Bug: Better cleanup of one-time events across the board (when an event is meant to fire once, it will now remove - itself from the EventDispatcher) -* Bug: `Guzzle\Log\MessageFormatter` now properly writes "total_time" and "connect_time" values -* Bug: Cloning an EntityEnclosingRequest now clones the EntityBody too -* Bug: Fixed an undefined index error when parsing nested JSON responses with a sentAs parameter that reference a - non-existent key -* Bug: All __call() method arguments are now required (helps with mocking frameworks) -* Deprecating Response::getRequest() and now using a shallow clone of a request object to remove a circular reference - to help with refcount based garbage collection of resources created by sending a request -* Deprecating ZF1 cache and log adapters. These will be removed in the next major version. -* Deprecating `Response::getPreviousResponse()` (method signature still exists, but it's deprecated). Use the - HistoryPlugin for a history. -* Added a `responseBody` alias for the `response_body` location -* Refactored internals to no longer rely on Response::getRequest() -* HistoryPlugin can now be cast to a string -* HistoryPlugin now logs transactions rather than requests and responses to more accurately keep track of the requests - and responses that are sent over the wire -* Added `getEffectiveUrl()` and `getRedirectCount()` to Response objects - -## 3.4.3 - 2013-04-30 - -* Bug fix: Fixing bug introduced in 3.4.2 where redirect responses are duplicated on the final redirected response -* Added a check to re-extract the temp cacert bundle from the phar before sending each request - -## 3.4.2 - 2013-04-29 - -* Bug fix: Stream objects now work correctly with "a" and "a+" modes -* Bug fix: Removing `Transfer-Encoding: chunked` header when a Content-Length is present -* Bug fix: AsyncPlugin no longer forces HEAD requests -* Bug fix: DateTime timezones are now properly handled when using the service description schema formatter -* Bug fix: CachePlugin now properly handles stale-if-error directives when a request to the origin server fails -* Setting a response on a request will write to the custom request body from the response body if one is specified -* LogPlugin now writes to php://output when STDERR is undefined -* Added the ability to set multiple POST files for the same key in a single call -* application/x-www-form-urlencoded POSTs now use the utf-8 charset by default -* Added the ability to queue CurlExceptions to the MockPlugin -* Cleaned up how manual responses are queued on requests (removed "queued_response" and now using request.before_send) -* Configuration loading now allows remote files - -## 3.4.1 - 2013-04-16 - -* Large refactoring to how CurlMulti handles work. There is now a proxy that sits in front of a pool of CurlMulti - handles. This greatly simplifies the implementation, fixes a couple bugs, and provides a small performance boost. -* Exceptions are now properly grouped when sending requests in parallel -* Redirects are now properly aggregated when a multi transaction fails -* Redirects now set the response on the original object even in the event of a failure -* Bug fix: Model names are now properly set even when using $refs -* Added support for PHP 5.5's CurlFile to prevent warnings with the deprecated @ syntax -* Added support for oauth_callback in OAuth signatures -* Added support for oauth_verifier in OAuth signatures -* Added support to attempt to retrieve a command first literally, then ucfirst, the with inflection - -## 3.4.0 - 2013-04-11 - -* Bug fix: URLs are now resolved correctly based on https://tools.ietf.org/html/rfc3986#section-5.2. #289 -* Bug fix: Absolute URLs with a path in a service description will now properly override the base URL. #289 -* Bug fix: Parsing a query string with a single PHP array value will now result in an array. #263 -* Bug fix: Better normalization of the User-Agent header to prevent duplicate headers. #264. -* Bug fix: Added `number` type to service descriptions. -* Bug fix: empty parameters are removed from an OAuth signature -* Bug fix: Revalidating a cache entry prefers the Last-Modified over the Date header -* Bug fix: Fixed "array to string" error when validating a union of types in a service description -* Bug fix: Removed code that attempted to determine the size of a stream when data is written to the stream -* Bug fix: Not including an `oauth_token` if the value is null in the OauthPlugin. -* Bug fix: Now correctly aggregating successful requests and failed requests in CurlMulti when a redirect occurs. -* The new default CURLOPT_TIMEOUT setting has been increased to 150 seconds so that Guzzle works on poor connections. -* Added a feature to EntityEnclosingRequest::setBody() that will automatically set the Content-Type of the request if - the Content-Type can be determined based on the entity body or the path of the request. -* Added the ability to overwrite configuration settings in a client when grabbing a throwaway client from a builder. -* Added support for a PSR-3 LogAdapter. -* Added a `command.after_prepare` event -* Added `oauth_callback` parameter to the OauthPlugin -* Added the ability to create a custom stream class when using a stream factory -* Added a CachingEntityBody decorator -* Added support for `additionalParameters` in service descriptions to define how custom parameters are serialized. -* The bundled SSL certificate is now provided in the phar file and extracted when running Guzzle from a phar. -* You can now send any EntityEnclosingRequest with POST fields or POST files and cURL will handle creating bodies -* POST requests using a custom entity body are now treated exactly like PUT requests but with a custom cURL method. This - means that the redirect behavior of POST requests with custom bodies will not be the same as POST requests that use - POST fields or files (the latter is only used when emulating a form POST in the browser). -* Lots of cleanup to CurlHandle::factory and RequestFactory::createRequest - -## 3.3.1 - 2013-03-10 - -* Added the ability to create PHP streaming responses from HTTP requests -* Bug fix: Running any filters when parsing response headers with service descriptions -* Bug fix: OauthPlugin fixes to allow for multi-dimensional array signing, and sorting parameters before signing -* Bug fix: Removed the adding of default empty arrays and false Booleans to responses in order to be consistent across - response location visitors. -* Bug fix: Removed the possibility of creating configuration files with circular dependencies -* RequestFactory::create() now uses the key of a POST file when setting the POST file name -* Added xmlAllowEmpty to serialize an XML body even if no XML specific parameters are set - -## 3.3.0 - 2013-03-03 - -* A large number of performance optimizations have been made -* Bug fix: Added 'wb' as a valid write mode for streams -* Bug fix: `Guzzle\Http\Message\Response::json()` now allows scalar values to be returned -* Bug fix: Fixed bug in `Guzzle\Http\Message\Response` where wrapping quotes were stripped from `getEtag()` -* BC: Removed `Guzzle\Http\Utils` class -* BC: Setting a service description on a client will no longer modify the client's command factories. -* BC: Emitting IO events from a RequestMediator is now a parameter that must be set in a request's curl options using - the 'emit_io' key. This was previously set under a request's parameters using 'curl.emit_io' -* BC: `Guzzle\Stream\Stream::getWrapper()` and `Guzzle\Stream\Stream::getSteamType()` are no longer converted to - lowercase -* Operation parameter objects are now lazy loaded internally -* Added ErrorResponsePlugin that can throw errors for responses defined in service description operations' errorResponses -* Added support for instantiating responseType=class responseClass classes. Classes must implement - `Guzzle\Service\Command\ResponseClassInterface` -* Added support for additionalProperties for top-level parameters in responseType=model responseClasses. These - additional properties also support locations and can be used to parse JSON responses where the outermost part of the - JSON is an array -* Added support for nested renaming of JSON models (rename sentAs to name) -* CachePlugin - * Added support for stale-if-error so that the CachePlugin can now serve stale content from the cache on error - * Debug headers can now added to cached response in the CachePlugin - -## 3.2.0 - 2013-02-14 - -* CurlMulti is no longer reused globally. A new multi object is created per-client. This helps to isolate clients. -* URLs with no path no longer contain a "/" by default -* Guzzle\Http\QueryString does no longer manages the leading "?". This is now handled in Guzzle\Http\Url. -* BadResponseException no longer includes the full request and response message -* Adding setData() to Guzzle\Service\Description\ServiceDescriptionInterface -* Adding getResponseBody() to Guzzle\Http\Message\RequestInterface -* Various updates to classes to use ServiceDescriptionInterface type hints rather than ServiceDescription -* Header values can now be normalized into distinct values when multiple headers are combined with a comma separated list -* xmlEncoding can now be customized for the XML declaration of a XML service description operation -* Guzzle\Http\QueryString now uses Guzzle\Http\QueryAggregator\QueryAggregatorInterface objects to add custom value - aggregation and no longer uses callbacks -* The URL encoding implementation of Guzzle\Http\QueryString can now be customized -* Bug fix: Filters were not always invoked for array service description parameters -* Bug fix: Redirects now use a target response body rather than a temporary response body -* Bug fix: The default exponential backoff BackoffPlugin was not giving when the request threshold was exceeded -* Bug fix: Guzzle now takes the first found value when grabbing Cache-Control directives - -## 3.1.2 - 2013-01-27 - -* Refactored how operation responses are parsed. Visitors now include a before() method responsible for parsing the - response body. For example, the XmlVisitor now parses the XML response into an array in the before() method. -* Fixed an issue where cURL would not automatically decompress responses when the Accept-Encoding header was sent -* CURLOPT_SSL_VERIFYHOST is never set to 1 because it is deprecated (see 5e0ff2ef20f839e19d1eeb298f90ba3598784444) -* Fixed a bug where redirect responses were not chained correctly using getPreviousResponse() -* Setting default headers on a client after setting the user-agent will not erase the user-agent setting - -## 3.1.1 - 2013-01-20 - -* Adding wildcard support to Guzzle\Common\Collection::getPath() -* Adding alias support to ServiceBuilder configs -* Adding Guzzle\Service\Resource\CompositeResourceIteratorFactory and cleaning up factory interface - -## 3.1.0 - 2013-01-12 - -* BC: CurlException now extends from RequestException rather than BadResponseException -* BC: Renamed Guzzle\Plugin\Cache\CanCacheStrategyInterface::canCache() to canCacheRequest() and added CanCacheResponse() -* Added getData to ServiceDescriptionInterface -* Added context array to RequestInterface::setState() -* Bug: Removing hard dependency on the BackoffPlugin from Guzzle\Http -* Bug: Adding required content-type when JSON request visitor adds JSON to a command -* Bug: Fixing the serialization of a service description with custom data -* Made it easier to deal with exceptions thrown when transferring commands or requests in parallel by providing - an array of successful and failed responses -* Moved getPath from Guzzle\Service\Resource\Model to Guzzle\Common\Collection -* Added Guzzle\Http\IoEmittingEntityBody -* Moved command filtration from validators to location visitors -* Added `extends` attributes to service description parameters -* Added getModels to ServiceDescriptionInterface - -## 3.0.7 - 2012-12-19 - -* Fixing phar detection when forcing a cacert to system if null or true -* Allowing filename to be passed to `Guzzle\Http\Message\Request::setResponseBody()` -* Cleaning up `Guzzle\Common\Collection::inject` method -* Adding a response_body location to service descriptions - -## 3.0.6 - 2012-12-09 - -* CurlMulti performance improvements -* Adding setErrorResponses() to Operation -* composer.json tweaks - -## 3.0.5 - 2012-11-18 - -* Bug: Fixing an infinite recursion bug caused from revalidating with the CachePlugin -* Bug: Response body can now be a string containing "0" -* Bug: Using Guzzle inside of a phar uses system by default but now allows for a custom cacert -* Bug: QueryString::fromString now properly parses query string parameters that contain equal signs -* Added support for XML attributes in service description responses -* DefaultRequestSerializer now supports array URI parameter values for URI template expansion -* Added better mimetype guessing to requests and post files - -## 3.0.4 - 2012-11-11 - -* Bug: Fixed a bug when adding multiple cookies to a request to use the correct glue value -* Bug: Cookies can now be added that have a name, domain, or value set to "0" -* Bug: Using the system cacert bundle when using the Phar -* Added json and xml methods to Response to make it easier to parse JSON and XML response data into data structures -* Enhanced cookie jar de-duplication -* Added the ability to enable strict cookie jars that throw exceptions when invalid cookies are added -* Added setStream to StreamInterface to actually make it possible to implement custom rewind behavior for entity bodies -* Added the ability to create any sort of hash for a stream rather than just an MD5 hash - -## 3.0.3 - 2012-11-04 - -* Implementing redirects in PHP rather than cURL -* Added PECL URI template extension and using as default parser if available -* Bug: Fixed Content-Length parsing of Response factory -* Adding rewind() method to entity bodies and streams. Allows for custom rewinding of non-repeatable streams. -* Adding ToArrayInterface throughout library -* Fixing OauthPlugin to create unique nonce values per request - -## 3.0.2 - 2012-10-25 - -* Magic methods are enabled by default on clients -* Magic methods return the result of a command -* Service clients no longer require a base_url option in the factory -* Bug: Fixed an issue with URI templates where null template variables were being expanded - -## 3.0.1 - 2012-10-22 - -* Models can now be used like regular collection objects by calling filter, map, etc. -* Models no longer require a Parameter structure or initial data in the constructor -* Added a custom AppendIterator to get around a PHP bug with the `\AppendIterator` - -## 3.0.0 - 2012-10-15 - -* Rewrote service description format to be based on Swagger - * Now based on JSON schema - * Added nested input structures and nested response models - * Support for JSON and XML input and output models - * Renamed `commands` to `operations` - * Removed dot class notation - * Removed custom types -* Broke the project into smaller top-level namespaces to be more component friendly -* Removed support for XML configs and descriptions. Use arrays or JSON files. -* Removed the Validation component and Inspector -* Moved all cookie code to Guzzle\Plugin\Cookie -* Magic methods on a Guzzle\Service\Client now return the command un-executed. -* Calling getResult() or getResponse() on a command will lazily execute the command if needed. -* Now shipping with cURL's CA certs and using it by default -* Added previousResponse() method to response objects -* No longer sending Accept and Accept-Encoding headers on every request -* Only sending an Expect header by default when a payload is greater than 1MB -* Added/moved client options: - * curl.blacklist to curl.option.blacklist - * Added ssl.certificate_authority -* Added a Guzzle\Iterator component -* Moved plugins from Guzzle\Http\Plugin to Guzzle\Plugin -* Added a more robust backoff retry strategy (replaced the ExponentialBackoffPlugin) -* Added a more robust caching plugin -* Added setBody to response objects -* Updating LogPlugin to use a more flexible MessageFormatter -* Added a completely revamped build process -* Cleaning up Collection class and removing default values from the get method -* Fixed ZF2 cache adapters - -## 2.8.8 - 2012-10-15 - -* Bug: Fixed a cookie issue that caused dot prefixed domains to not match where popular browsers did - -## 2.8.7 - 2012-09-30 - -* Bug: Fixed config file aliases for JSON includes -* Bug: Fixed cookie bug on a request object by using CookieParser to parse cookies on requests -* Bug: Removing the path to a file when sending a Content-Disposition header on a POST upload -* Bug: Hardening request and response parsing to account for missing parts -* Bug: Fixed PEAR packaging -* Bug: Fixed Request::getInfo -* Bug: Fixed cases where CURLM_CALL_MULTI_PERFORM return codes were causing curl transactions to fail -* Adding the ability for the namespace Iterator factory to look in multiple directories -* Added more getters/setters/removers from service descriptions -* Added the ability to remove POST fields from OAuth signatures -* OAuth plugin now supports 2-legged OAuth - -## 2.8.6 - 2012-09-05 - -* Added the ability to modify and build service descriptions -* Added the use of visitors to apply parameters to locations in service descriptions using the dynamic command -* Added a `json` parameter location -* Now allowing dot notation for classes in the CacheAdapterFactory -* Using the union of two arrays rather than an array_merge when extending service builder services and service params -* Ensuring that a service is a string before doing strpos() checks on it when substituting services for references - in service builder config files. -* Services defined in two different config files that include one another will by default replace the previously - defined service, but you can now create services that extend themselves and merge their settings over the previous -* The JsonLoader now supports aliasing filenames with different filenames. This allows you to alias something like - '_default' with a default JSON configuration file. - -## 2.8.5 - 2012-08-29 - -* Bug: Suppressed empty arrays from URI templates -* Bug: Added the missing $options argument from ServiceDescription::factory to enable caching -* Added support for HTTP responses that do not contain a reason phrase in the start-line -* AbstractCommand commands are now invokable -* Added a way to get the data used when signing an Oauth request before a request is sent - -## 2.8.4 - 2012-08-15 - -* Bug: Custom delay time calculations are no longer ignored in the ExponentialBackoffPlugin -* Added the ability to transfer entity bodies as a string rather than streamed. This gets around curl error 65. Set `body_as_string` in a request's curl options to enable. -* Added a StreamInterface, EntityBodyInterface, and added ftell() to Guzzle\Common\Stream -* Added an AbstractEntityBodyDecorator and a ReadLimitEntityBody decorator to transfer only a subset of a decorated stream -* Stream and EntityBody objects will now return the file position to the previous position after a read required operation (e.g. getContentMd5()) -* Added additional response status codes -* Removed SSL information from the default User-Agent header -* DELETE requests can now send an entity body -* Added an EventDispatcher to the ExponentialBackoffPlugin and added an ExponentialBackoffLogger to log backoff retries -* Added the ability of the MockPlugin to consume mocked request bodies -* LogPlugin now exposes request and response objects in the extras array - -## 2.8.3 - 2012-07-30 - -* Bug: Fixed a case where empty POST requests were sent as GET requests -* Bug: Fixed a bug in ExponentialBackoffPlugin that caused fatal errors when retrying an EntityEnclosingRequest that does not have a body -* Bug: Setting the response body of a request to null after completing a request, not when setting the state of a request to new -* Added multiple inheritance to service description commands -* Added an ApiCommandInterface and added `getParamNames()` and `hasParam()` -* Removed the default 2mb size cutoff from the Md5ValidatorPlugin so that it now defaults to validating everything -* Changed CurlMulti::perform to pass a smaller timeout to CurlMulti::executeHandles - -## 2.8.2 - 2012-07-24 - -* Bug: Query string values set to 0 are no longer dropped from the query string -* Bug: A Collection object is no longer created each time a call is made to `Guzzle\Service\Command\AbstractCommand::getRequestHeaders()` -* Bug: `+` is now treated as an encoded space when parsing query strings -* QueryString and Collection performance improvements -* Allowing dot notation for class paths in filters attribute of a service descriptions - -## 2.8.1 - 2012-07-16 - -* Loosening Event Dispatcher dependency -* POST redirects can now be customized using CURLOPT_POSTREDIR - -## 2.8.0 - 2012-07-15 - -* BC: Guzzle\Http\Query - * Query strings with empty variables will always show an equal sign unless the variable is set to QueryString::BLANK (e.g. ?acl= vs ?acl) - * Changed isEncodingValues() and isEncodingFields() to isUrlEncoding() - * Changed setEncodeValues(bool) and setEncodeFields(bool) to useUrlEncoding(bool) - * Changed the aggregation functions of QueryString to be static methods - * Can now use fromString() with querystrings that have a leading ? -* cURL configuration values can be specified in service descriptions using `curl.` prefixed parameters -* Content-Length is set to 0 before emitting the request.before_send event when sending an empty request body -* Cookies are no longer URL decoded by default -* Bug: URI template variables set to null are no longer expanded - -## 2.7.2 - 2012-07-02 - -* BC: Moving things to get ready for subtree splits. Moving Inflection into Common. Moving Guzzle\Http\Parser to Guzzle\Parser. -* BC: Removing Guzzle\Common\Batch\Batch::count() and replacing it with isEmpty() -* CachePlugin now allows for a custom request parameter function to check if a request can be cached -* Bug fix: CachePlugin now only caches GET and HEAD requests by default -* Bug fix: Using header glue when transferring headers over the wire -* Allowing deeply nested arrays for composite variables in URI templates -* Batch divisors can now return iterators or arrays - -## 2.7.1 - 2012-06-26 - -* Minor patch to update version number in UA string -* Updating build process - -## 2.7.0 - 2012-06-25 - -* BC: Inflection classes moved to Guzzle\Inflection. No longer static methods. Can now inject custom inflectors into classes. -* BC: Removed magic setX methods from commands -* BC: Magic methods mapped to service description commands are now inflected in the command factory rather than the client __call() method -* Verbose cURL options are no longer enabled by default. Set curl.debug to true on a client to enable. -* Bug: Now allowing colons in a response start-line (e.g. HTTP/1.1 503 Service Unavailable: Back-end server is at capacity) -* Guzzle\Service\Resource\ResourceIteratorApplyBatched now internally uses the Guzzle\Common\Batch namespace -* Added Guzzle\Service\Plugin namespace and a PluginCollectionPlugin -* Added the ability to set POST fields and files in a service description -* Guzzle\Http\EntityBody::factory() now accepts objects with a __toString() method -* Adding a command.before_prepare event to clients -* Added BatchClosureTransfer and BatchClosureDivisor -* BatchTransferException now includes references to the batch divisor and transfer strategies -* Fixed some tests so that they pass more reliably -* Added Guzzle\Common\Log\ArrayLogAdapter - -## 2.6.6 - 2012-06-10 - -* BC: Removing Guzzle\Http\Plugin\BatchQueuePlugin -* BC: Removing Guzzle\Service\Command\CommandSet -* Adding generic batching system (replaces the batch queue plugin and command set) -* Updating ZF cache and log adapters and now using ZF's composer repository -* Bug: Setting the name of each ApiParam when creating through an ApiCommand -* Adding result_type, result_doc, deprecated, and doc_url to service descriptions -* Bug: Changed the default cookie header casing back to 'Cookie' - -## 2.6.5 - 2012-06-03 - -* BC: Renaming Guzzle\Http\Message\RequestInterface::getResourceUri() to getResource() -* BC: Removing unused AUTH_BASIC and AUTH_DIGEST constants from -* BC: Guzzle\Http\Cookie is now used to manage Set-Cookie data, not Cookie data -* BC: Renaming methods in the CookieJarInterface -* Moving almost all cookie logic out of the CookiePlugin and into the Cookie or CookieJar implementations -* Making the default glue for HTTP headers ';' instead of ',' -* Adding a removeValue to Guzzle\Http\Message\Header -* Adding getCookies() to request interface. -* Making it easier to add event subscribers to HasDispatcherInterface classes. Can now directly call addSubscriber() - -## 2.6.4 - 2012-05-30 - -* BC: Cleaning up how POST files are stored in EntityEnclosingRequest objects. Adding PostFile class. -* BC: Moving ApiCommand specific functionality from the Inspector and on to the ApiCommand -* Bug: Fixing magic method command calls on clients -* Bug: Email constraint only validates strings -* Bug: Aggregate POST fields when POST files are present in curl handle -* Bug: Fixing default User-Agent header -* Bug: Only appending or prepending parameters in commands if they are specified -* Bug: Not requiring response reason phrases or status codes to match a predefined list of codes -* Allowing the use of dot notation for class namespaces when using instance_of constraint -* Added any_match validation constraint -* Added an AsyncPlugin -* Passing request object to the calculateWait method of the ExponentialBackoffPlugin -* Allowing the result of a command object to be changed -* Parsing location and type sub values when instantiating a service description rather than over and over at runtime - -## 2.6.3 - 2012-05-23 - -* [BC] Guzzle\Common\FromConfigInterface no longer requires any config options. -* [BC] Refactoring how POST files are stored on an EntityEnclosingRequest. They are now separate from POST fields. -* You can now use an array of data when creating PUT request bodies in the request factory. -* Removing the requirement that HTTPS requests needed a Cache-Control: public directive to be cacheable. -* [Http] Adding support for Content-Type in multipart POST uploads per upload -* [Http] Added support for uploading multiple files using the same name (foo[0], foo[1]) -* Adding more POST data operations for easier manipulation of POST data. -* You can now set empty POST fields. -* The body of a request is only shown on EntityEnclosingRequest objects that do not use POST files. -* Split the Guzzle\Service\Inspector::validateConfig method into two methods. One to initialize when a command is created, and one to validate. -* CS updates - -## 2.6.2 - 2012-05-19 - -* [Http] Better handling of nested scope requests in CurlMulti. Requests are now always prepares in the send() method rather than the addRequest() method. - -## 2.6.1 - 2012-05-19 - -* [BC] Removing 'path' support in service descriptions. Use 'uri'. -* [BC] Guzzle\Service\Inspector::parseDocBlock is now protected. Adding getApiParamsForClass() with cache. -* [BC] Removing Guzzle\Common\NullObject. Use https://github.com/mtdowling/NullObject if you need it. -* [BC] Removing Guzzle\Common\XmlElement. -* All commands, both dynamic and concrete, have ApiCommand objects. -* Adding a fix for CurlMulti so that if all of the connections encounter some sort of curl error, then the loop exits. -* Adding checks to EntityEnclosingRequest so that empty POST files and fields are ignored. -* Making the method signature of Guzzle\Service\Builder\ServiceBuilder::factory more flexible. - -## 2.6.0 - 2012-05-15 - -* [BC] Moving Guzzle\Service\Builder to Guzzle\Service\Builder\ServiceBuilder -* [BC] Executing a Command returns the result of the command rather than the command -* [BC] Moving all HTTP parsing logic to Guzzle\Http\Parsers. Allows for faster C implementations if needed. -* [BC] Changing the Guzzle\Http\Message\Response::setProtocol() method to accept a protocol and version in separate args. -* [BC] Moving ResourceIterator* to Guzzle\Service\Resource -* [BC] Completely refactored ResourceIterators to iterate over a cloned command object -* [BC] Moved Guzzle\Http\UriTemplate to Guzzle\Http\Parser\UriTemplate\UriTemplate -* [BC] Guzzle\Guzzle is now deprecated -* Moving Guzzle\Common\Guzzle::inject to Guzzle\Common\Collection::inject -* Adding Guzzle\Version class to give version information about Guzzle -* Adding Guzzle\Http\Utils class to provide getDefaultUserAgent() and getHttpDate() -* Adding Guzzle\Curl\CurlVersion to manage caching curl_version() data -* ServiceDescription and ServiceBuilder are now cacheable using similar configs -* Changing the format of XML and JSON service builder configs. Backwards compatible. -* Cleaned up Cookie parsing -* Trimming the default Guzzle User-Agent header -* Adding a setOnComplete() method to Commands that is called when a command completes -* Keeping track of requests that were mocked in the MockPlugin -* Fixed a caching bug in the CacheAdapterFactory -* Inspector objects can be injected into a Command object -* Refactoring a lot of code and tests to be case insensitive when dealing with headers -* Adding Guzzle\Http\Message\HeaderComparison for easy comparison of HTTP headers using a DSL -* Adding the ability to set global option overrides to service builder configs -* Adding the ability to include other service builder config files from within XML and JSON files -* Moving the parseQuery method out of Url and on to QueryString::fromString() as a static factory method. - -## 2.5.0 - 2012-05-08 - -* Major performance improvements -* [BC] Simplifying Guzzle\Common\Collection. Please check to see if you are using features that are now deprecated. -* [BC] Using a custom validation system that allows a flyweight implementation for much faster validation. No longer using Symfony2 Validation component. -* [BC] No longer supporting "{{ }}" for injecting into command or UriTemplates. Use "{}" -* Added the ability to passed parameters to all requests created by a client -* Added callback functionality to the ExponentialBackoffPlugin -* Using microtime in ExponentialBackoffPlugin to allow more granular backoff strategies. -* Rewinding request stream bodies when retrying requests -* Exception is thrown when JSON response body cannot be decoded -* Added configurable magic method calls to clients and commands. This is off by default. -* Fixed a defect that added a hash to every parsed URL part -* Fixed duplicate none generation for OauthPlugin. -* Emitting an event each time a client is generated by a ServiceBuilder -* Using an ApiParams object instead of a Collection for parameters of an ApiCommand -* cache.* request parameters should be renamed to params.cache.* -* Added the ability to set arbitrary curl options on requests (disable_wire, progress, etc.). See CurlHandle. -* Added the ability to disable type validation of service descriptions -* ServiceDescriptions and ServiceBuilders are now Serializable diff --git a/plugins/automagic-images/vendor/guzzlehttp/guzzle/LICENSE b/plugins/automagic-images/vendor/guzzlehttp/guzzle/LICENSE deleted file mode 100644 index d51aa69..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/guzzle/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2011 Michael Dowling, https://github.com/mtdowling - -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/plugins/automagic-images/vendor/guzzlehttp/guzzle/README.md b/plugins/automagic-images/vendor/guzzlehttp/guzzle/README.md deleted file mode 100644 index 363d6f8..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/guzzle/README.md +++ /dev/null @@ -1,79 +0,0 @@ -![Guzzle](.github/logo.png?raw=true) - -# Guzzle, PHP HTTP client - -[![Latest Version](https://img.shields.io/github/release/guzzle/guzzle.svg?style=flat-square)](https://github.com/guzzle/guzzle/releases) -[![Build Status](https://img.shields.io/github/workflow/status/guzzle/guzzle/CI?label=ci%20build&style=flat-square)](https://github.com/guzzle/guzzle/actions?query=workflow%3ACI) -[![Total Downloads](https://img.shields.io/packagist/dt/guzzlehttp/guzzle.svg?style=flat-square)](https://packagist.org/packages/guzzlehttp/guzzle) - -Guzzle is a PHP HTTP client that makes it easy to send HTTP requests and -trivial to integrate with web services. - -- Simple interface for building query strings, POST requests, streaming large - uploads, streaming large downloads, using HTTP cookies, uploading JSON data, - etc... -- Can send both synchronous and asynchronous requests using the same interface. -- Uses PSR-7 interfaces for requests, responses, and streams. This allows you - to utilize other PSR-7 compatible libraries with Guzzle. -- Supports PSR-18 allowing interoperability between other PSR-18 HTTP Clients. -- Abstracts away the underlying HTTP transport, allowing you to write - environment and transport agnostic code; i.e., no hard dependency on cURL, - PHP streams, sockets, or non-blocking event loops. -- Middleware system allows you to augment and compose client behavior. - -```php -$client = new \GuzzleHttp\Client(); -$response = $client->request('GET', 'https://api.github.com/repos/guzzle/guzzle'); - -echo $response->getStatusCode(); // 200 -echo $response->getHeaderLine('content-type'); // 'application/json; charset=utf8' -echo $response->getBody(); // '{"id": 1420053, "name": "guzzle", ...}' - -// Send an asynchronous request. -$request = new \GuzzleHttp\Psr7\Request('GET', 'http://httpbin.org'); -$promise = $client->sendAsync($request)->then(function ($response) { - echo 'I completed! ' . $response->getBody(); -}); - -$promise->wait(); -``` - -## Help and docs - -We use GitHub issues only to discuss bugs and new features. For support please refer to: - -- [Documentation](http://guzzlephp.org/) -- [Stack Overflow](http://stackoverflow.com/questions/tagged/guzzle) -- [#guzzle](https://app.slack.com/client/T0D2S9JCT/CE6UAAKL4) channel on [PHP-HTTP Slack](http://slack.httplug.io/) -- [Gitter](https://gitter.im/guzzle/guzzle) - - -## Installing Guzzle - -The recommended way to install Guzzle is through -[Composer](https://getcomposer.org/). - -```bash -composer require guzzlehttp/guzzle -``` - - -## Version Guidance - -| Version | Status | Packagist | Namespace | Repo | Docs | PSR-7 | PHP Version | -|---------|------------|---------------------|--------------|---------------------|---------------------|-------|-------------| -| 3.x | EOL | `guzzle/guzzle` | `Guzzle` | [v3][guzzle-3-repo] | [v3][guzzle-3-docs] | No | >= 5.3.3 | -| 4.x | EOL | `guzzlehttp/guzzle` | `GuzzleHttp` | [v4][guzzle-4-repo] | N/A | No | >= 5.4 | -| 5.x | EOL | `guzzlehttp/guzzle` | `GuzzleHttp` | [v5][guzzle-5-repo] | [v5][guzzle-5-docs] | No | >= 5.4 | -| 6.x | Security fixes | `guzzlehttp/guzzle` | `GuzzleHttp` | [v6][guzzle-6-repo] | [v6][guzzle-6-docs] | Yes | >= 5.5 | -| 7.x | Latest | `guzzlehttp/guzzle` | `GuzzleHttp` | [v7][guzzle-7-repo] | [v7][guzzle-7-docs] | Yes | >= 7.2 | - -[guzzle-3-repo]: https://github.com/guzzle/guzzle3 -[guzzle-4-repo]: https://github.com/guzzle/guzzle/tree/4.x -[guzzle-5-repo]: https://github.com/guzzle/guzzle/tree/5.3 -[guzzle-6-repo]: https://github.com/guzzle/guzzle/tree/6.5 -[guzzle-7-repo]: https://github.com/guzzle/guzzle -[guzzle-3-docs]: http://guzzle3.readthedocs.org -[guzzle-5-docs]: http://docs.guzzlephp.org/en/5.3/ -[guzzle-6-docs]: http://docs.guzzlephp.org/en/6.5/ -[guzzle-7-docs]: http://docs.guzzlephp.org/en/latest/ diff --git a/plugins/automagic-images/vendor/guzzlehttp/guzzle/UPGRADING.md b/plugins/automagic-images/vendor/guzzlehttp/guzzle/UPGRADING.md deleted file mode 100644 index 45417a7..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/guzzle/UPGRADING.md +++ /dev/null @@ -1,1253 +0,0 @@ -Guzzle Upgrade Guide -==================== - -6.0 to 7.0 ----------- - -In order to take advantage of the new features of PHP, Guzzle dropped the support -of PHP 5. The minimum supported PHP version is now PHP 7.2. Type hints and return -types for functions and methods have been added wherever possible. - -Please make sure: -- You are calling a function or a method with the correct type. -- If you extend a class of Guzzle; update all signatures on methods you override. - -#### Other backwards compatibility breaking changes - -- Class `GuzzleHttp\UriTemplate` is removed. -- Class `GuzzleHttp\Exception\SeekException` is removed. -- Classes `GuzzleHttp\Exception\BadResponseException`, `GuzzleHttp\Exception\ClientException`, - `GuzzleHttp\Exception\ServerException` can no longer be initialized with an empty - Response as argument. -- Class `GuzzleHttp\Exception\ConnectException` now extends `GuzzleHttp\Exception\TransferException` - instead of `GuzzleHttp\Exception\RequestException`. -- Function `GuzzleHttp\Exception\ConnectException::getResponse()` is removed. -- Function `GuzzleHttp\Exception\ConnectException::hasResponse()` is removed. -- Constant `GuzzleHttp\ClientInterface::VERSION` is removed. Added `GuzzleHttp\ClientInterface::MAJOR_VERSION` instead. -- Function `GuzzleHttp\Exception\RequestException::getResponseBodySummary` is removed. - Use `\GuzzleHttp\Psr7\get_message_body_summary` as an alternative. -- Function `GuzzleHttp\Cookie\CookieJar::getCookieValue` is removed. -- Request option `exception` is removed. Please use `http_errors`. -- Request option `save_to` is removed. Please use `sink`. -- Pool option `pool_size` is removed. Please use `concurrency`. -- We now look for environment variables in the `$_SERVER` super global, due to thread safety issues with `getenv`. We continue to fallback to `getenv` in CLI environments, for maximum compatibility. -- The `get`, `head`, `put`, `post`, `patch`, `delete`, `getAsync`, `headAsync`, `putAsync`, `postAsync`, `patchAsync`, and `deleteAsync` methods are now implemented as genuine methods on `GuzzleHttp\Client`, with strong typing. The original `__call` implementation remains unchanged for now, for maximum backwards compatibility, but won't be invoked under normal operation. -- The `log` middleware will log the errors with level `error` instead of `notice` -- Support for international domain names (IDN) is now disabled by default, and enabling it requires installing ext-intl, linked against a modern version of the C library (ICU 4.6 or higher). - -#### Native functions calls - -All internal native functions calls of Guzzle are now prefixed with a slash. This -change makes it impossible for method overloading by other libraries or applications. -Example: - -```php -// Before: -curl_version(); - -// After: -\curl_version(); -``` - -For the full diff you can check [here](https://github.com/guzzle/guzzle/compare/6.5.4..master). - -5.0 to 6.0 ----------- - -Guzzle now uses [PSR-7](https://www.php-fig.org/psr/psr-7/) for HTTP messages. -Due to the fact that these messages are immutable, this prompted a refactoring -of Guzzle to use a middleware based system rather than an event system. Any -HTTP message interaction (e.g., `GuzzleHttp\Message\Request`) need to be -updated to work with the new immutable PSR-7 request and response objects. Any -event listeners or subscribers need to be updated to become middleware -functions that wrap handlers (or are injected into a -`GuzzleHttp\HandlerStack`). - -- Removed `GuzzleHttp\BatchResults` -- Removed `GuzzleHttp\Collection` -- Removed `GuzzleHttp\HasDataTrait` -- Removed `GuzzleHttp\ToArrayInterface` -- The `guzzlehttp/streams` dependency has been removed. Stream functionality - is now present in the `GuzzleHttp\Psr7` namespace provided by the - `guzzlehttp/psr7` package. -- Guzzle no longer uses ReactPHP promises and now uses the - `guzzlehttp/promises` library. We use a custom promise library for three - significant reasons: - 1. React promises (at the time of writing this) are recursive. Promise - chaining and promise resolution will eventually blow the stack. Guzzle - promises are not recursive as they use a sort of trampolining technique. - Note: there has been movement in the React project to modify promises to - no longer utilize recursion. - 2. Guzzle needs to have the ability to synchronously block on a promise to - wait for a result. Guzzle promises allows this functionality (and does - not require the use of recursion). - 3. Because we need to be able to wait on a result, doing so using React - promises requires wrapping react promises with RingPHP futures. This - overhead is no longer needed, reducing stack sizes, reducing complexity, - and improving performance. -- `GuzzleHttp\Mimetypes` has been moved to a function in - `GuzzleHttp\Psr7\mimetype_from_extension` and - `GuzzleHttp\Psr7\mimetype_from_filename`. -- `GuzzleHttp\Query` and `GuzzleHttp\QueryParser` have been removed. Query - strings must now be passed into request objects as strings, or provided to - the `query` request option when creating requests with clients. The `query` - option uses PHP's `http_build_query` to convert an array to a string. If you - need a different serialization technique, you will need to pass the query - string in as a string. There are a couple helper functions that will make - working with query strings easier: `GuzzleHttp\Psr7\parse_query` and - `GuzzleHttp\Psr7\build_query`. -- Guzzle no longer has a dependency on RingPHP. Due to the use of a middleware - system based on PSR-7, using RingPHP and it's middleware system as well adds - more complexity than the benefits it provides. All HTTP handlers that were - present in RingPHP have been modified to work directly with PSR-7 messages - and placed in the `GuzzleHttp\Handler` namespace. This significantly reduces - complexity in Guzzle, removes a dependency, and improves performance. RingPHP - will be maintained for Guzzle 5 support, but will no longer be a part of - Guzzle 6. -- As Guzzle now uses a middleware based systems the event system and RingPHP - integration has been removed. Note: while the event system has been removed, - it is possible to add your own type of event system that is powered by the - middleware system. - - Removed the `Event` namespace. - - Removed the `Subscriber` namespace. - - Removed `Transaction` class - - Removed `RequestFsm` - - Removed `RingBridge` - - `GuzzleHttp\Subscriber\Cookie` is now provided by - `GuzzleHttp\Middleware::cookies` - - `GuzzleHttp\Subscriber\HttpError` is now provided by - `GuzzleHttp\Middleware::httpError` - - `GuzzleHttp\Subscriber\History` is now provided by - `GuzzleHttp\Middleware::history` - - `GuzzleHttp\Subscriber\Mock` is now provided by - `GuzzleHttp\Handler\MockHandler` - - `GuzzleHttp\Subscriber\Prepare` is now provided by - `GuzzleHttp\PrepareBodyMiddleware` - - `GuzzleHttp\Subscriber\Redirect` is now provided by - `GuzzleHttp\RedirectMiddleware` -- Guzzle now uses `Psr\Http\Message\UriInterface` (implements in - `GuzzleHttp\Psr7\Uri`) for URI support. `GuzzleHttp\Url` is now gone. -- Static functions in `GuzzleHttp\Utils` have been moved to namespaced - functions under the `GuzzleHttp` namespace. This requires either a Composer - based autoloader or you to include functions.php. -- `GuzzleHttp\ClientInterface::getDefaultOption` has been renamed to - `GuzzleHttp\ClientInterface::getConfig`. -- `GuzzleHttp\ClientInterface::setDefaultOption` has been removed. -- The `json` and `xml` methods of response objects has been removed. With the - migration to strictly adhering to PSR-7 as the interface for Guzzle messages, - adding methods to message interfaces would actually require Guzzle messages - to extend from PSR-7 messages rather then work with them directly. - -## Migrating to middleware - -The change to PSR-7 unfortunately required significant refactoring to Guzzle -due to the fact that PSR-7 messages are immutable. Guzzle 5 relied on an event -system from plugins. The event system relied on mutability of HTTP messages and -side effects in order to work. With immutable messages, you have to change your -workflow to become more about either returning a value (e.g., functional -middlewares) or setting a value on an object. Guzzle v6 has chosen the -functional middleware approach. - -Instead of using the event system to listen for things like the `before` event, -you now create a stack based middleware function that intercepts a request on -the way in and the promise of the response on the way out. This is a much -simpler and more predictable approach than the event system and works nicely -with PSR-7 middleware. Due to the use of promises, the middleware system is -also asynchronous. - -v5: - -```php -use GuzzleHttp\Event\BeforeEvent; -$client = new GuzzleHttp\Client(); -// Get the emitter and listen to the before event. -$client->getEmitter()->on('before', function (BeforeEvent $e) { - // Guzzle v5 events relied on mutation - $e->getRequest()->setHeader('X-Foo', 'Bar'); -}); -``` - -v6: - -In v6, you can modify the request before it is sent using the `mapRequest` -middleware. The idiomatic way in v6 to modify the request/response lifecycle is -to setup a handler middleware stack up front and inject the handler into a -client. - -```php -use GuzzleHttp\Middleware; -// Create a handler stack that has all of the default middlewares attached -$handler = GuzzleHttp\HandlerStack::create(); -// Push the handler onto the handler stack -$handler->push(Middleware::mapRequest(function (RequestInterface $request) { - // Notice that we have to return a request object - return $request->withHeader('X-Foo', 'Bar'); -})); -// Inject the handler into the client -$client = new GuzzleHttp\Client(['handler' => $handler]); -``` - -## POST Requests - -This version added the [`form_params`](http://guzzle.readthedocs.org/en/latest/request-options.html#form_params) -and `multipart` request options. `form_params` is an associative array of -strings or array of strings and is used to serialize an -`application/x-www-form-urlencoded` POST request. The -[`multipart`](http://guzzle.readthedocs.org/en/latest/request-options.html#multipart) -option is now used to send a multipart/form-data POST request. - -`GuzzleHttp\Post\PostFile` has been removed. Use the `multipart` option to add -POST files to a multipart/form-data request. - -The `body` option no longer accepts an array to send POST requests. Please use -`multipart` or `form_params` instead. - -The `base_url` option has been renamed to `base_uri`. - -4.x to 5.0 ----------- - -## Rewritten Adapter Layer - -Guzzle now uses [RingPHP](http://ringphp.readthedocs.org/en/latest) to send -HTTP requests. The `adapter` option in a `GuzzleHttp\Client` constructor -is still supported, but it has now been renamed to `handler`. Instead of -passing a `GuzzleHttp\Adapter\AdapterInterface`, you must now pass a PHP -`callable` that follows the RingPHP specification. - -## Removed Fluent Interfaces - -[Fluent interfaces were removed](https://ocramius.github.io/blog/fluent-interfaces-are-evil/) -from the following classes: - -- `GuzzleHttp\Collection` -- `GuzzleHttp\Url` -- `GuzzleHttp\Query` -- `GuzzleHttp\Post\PostBody` -- `GuzzleHttp\Cookie\SetCookie` - -## Removed functions.php - -Removed "functions.php", so that Guzzle is truly PSR-4 compliant. The following -functions can be used as replacements. - -- `GuzzleHttp\json_decode` -> `GuzzleHttp\Utils::jsonDecode` -- `GuzzleHttp\get_path` -> `GuzzleHttp\Utils::getPath` -- `GuzzleHttp\Utils::setPath` -> `GuzzleHttp\set_path` -- `GuzzleHttp\Pool::batch` -> `GuzzleHttp\batch`. This function is, however, - deprecated in favor of using `GuzzleHttp\Pool::batch()`. - -The "procedural" global client has been removed with no replacement (e.g., -`GuzzleHttp\get()`, `GuzzleHttp\post()`, etc.). Use a `GuzzleHttp\Client` -object as a replacement. - -## `throwImmediately` has been removed - -The concept of "throwImmediately" has been removed from exceptions and error -events. This control mechanism was used to stop a transfer of concurrent -requests from completing. This can now be handled by throwing the exception or -by cancelling a pool of requests or each outstanding future request -individually. - -## headers event has been removed - -Removed the "headers" event. This event was only useful for changing the -body a response once the headers of the response were known. You can implement -a similar behavior in a number of ways. One example might be to use a -FnStream that has access to the transaction being sent. For example, when the -first byte is written, you could check if the response headers match your -expectations, and if so, change the actual stream body that is being -written to. - -## Updates to HTTP Messages - -Removed the `asArray` parameter from -`GuzzleHttp\Message\MessageInterface::getHeader`. If you want to get a header -value as an array, then use the newly added `getHeaderAsArray()` method of -`MessageInterface`. This change makes the Guzzle interfaces compatible with -the PSR-7 interfaces. - -3.x to 4.0 ----------- - -## Overarching changes: - -- Now requires PHP 5.4 or greater. -- No longer requires cURL to send requests. -- Guzzle no longer wraps every exception it throws. Only exceptions that are - recoverable are now wrapped by Guzzle. -- Various namespaces have been removed or renamed. -- No longer requiring the Symfony EventDispatcher. A custom event dispatcher - based on the Symfony EventDispatcher is - now utilized in `GuzzleHttp\Event\EmitterInterface` (resulting in significant - speed and functionality improvements). - -Changes per Guzzle 3.x namespace are described below. - -## Batch - -The `Guzzle\Batch` namespace has been removed. This is best left to -third-parties to implement on top of Guzzle's core HTTP library. - -## Cache - -The `Guzzle\Cache` namespace has been removed. (Todo: No suitable replacement -has been implemented yet, but hoping to utilize a PSR cache interface). - -## Common - -- Removed all of the wrapped exceptions. It's better to use the standard PHP - library for unrecoverable exceptions. -- `FromConfigInterface` has been removed. -- `Guzzle\Common\Version` has been removed. The VERSION constant can be found - at `GuzzleHttp\ClientInterface::VERSION`. - -### Collection - -- `getAll` has been removed. Use `toArray` to convert a collection to an array. -- `inject` has been removed. -- `keySearch` has been removed. -- `getPath` no longer supports wildcard expressions. Use something better like - JMESPath for this. -- `setPath` now supports appending to an existing array via the `[]` notation. - -### Events - -Guzzle no longer requires Symfony's EventDispatcher component. Guzzle now uses -`GuzzleHttp\Event\Emitter`. - -- `Symfony\Component\EventDispatcher\EventDispatcherInterface` is replaced by - `GuzzleHttp\Event\EmitterInterface`. -- `Symfony\Component\EventDispatcher\EventDispatcher` is replaced by - `GuzzleHttp\Event\Emitter`. -- `Symfony\Component\EventDispatcher\Event` is replaced by - `GuzzleHttp\Event\Event`, and Guzzle now has an EventInterface in - `GuzzleHttp\Event\EventInterface`. -- `AbstractHasDispatcher` has moved to a trait, `HasEmitterTrait`, and - `HasDispatcherInterface` has moved to `HasEmitterInterface`. Retrieving the - event emitter of a request, client, etc. now uses the `getEmitter` method - rather than the `getDispatcher` method. - -#### Emitter - -- Use the `once()` method to add a listener that automatically removes itself - the first time it is invoked. -- Use the `listeners()` method to retrieve a list of event listeners rather than - the `getListeners()` method. -- Use `emit()` instead of `dispatch()` to emit an event from an emitter. -- Use `attach()` instead of `addSubscriber()` and `detach()` instead of - `removeSubscriber()`. - -```php -$mock = new Mock(); -// 3.x -$request->getEventDispatcher()->addSubscriber($mock); -$request->getEventDispatcher()->removeSubscriber($mock); -// 4.x -$request->getEmitter()->attach($mock); -$request->getEmitter()->detach($mock); -``` - -Use the `on()` method to add a listener rather than the `addListener()` method. - -```php -// 3.x -$request->getEventDispatcher()->addListener('foo', function (Event $event) { /* ... */ } ); -// 4.x -$request->getEmitter()->on('foo', function (Event $event, $name) { /* ... */ } ); -``` - -## Http - -### General changes - -- The cacert.pem certificate has been moved to `src/cacert.pem`. -- Added the concept of adapters that are used to transfer requests over the - wire. -- Simplified the event system. -- Sending requests in parallel is still possible, but batching is no longer a - concept of the HTTP layer. Instead, you must use the `complete` and `error` - events to asynchronously manage parallel request transfers. -- `Guzzle\Http\Url` has moved to `GuzzleHttp\Url`. -- `Guzzle\Http\QueryString` has moved to `GuzzleHttp\Query`. -- QueryAggregators have been rewritten so that they are simply callable - functions. -- `GuzzleHttp\StaticClient` has been removed. Use the functions provided in - `functions.php` for an easy to use static client instance. -- Exceptions in `GuzzleHttp\Exception` have been updated to all extend from - `GuzzleHttp\Exception\TransferException`. - -### Client - -Calling methods like `get()`, `post()`, `head()`, etc. no longer create and -return a request, but rather creates a request, sends the request, and returns -the response. - -```php -// 3.0 -$request = $client->get('/'); -$response = $request->send(); - -// 4.0 -$response = $client->get('/'); - -// or, to mirror the previous behavior -$request = $client->createRequest('GET', '/'); -$response = $client->send($request); -``` - -`GuzzleHttp\ClientInterface` has changed. - -- The `send` method no longer accepts more than one request. Use `sendAll` to - send multiple requests in parallel. -- `setUserAgent()` has been removed. Use a default request option instead. You - could, for example, do something like: - `$client->setConfig('defaults/headers/User-Agent', 'Foo/Bar ' . $client::getDefaultUserAgent())`. -- `setSslVerification()` has been removed. Use default request options instead, - like `$client->setConfig('defaults/verify', true)`. - -`GuzzleHttp\Client` has changed. - -- The constructor now accepts only an associative array. You can include a - `base_url` string or array to use a URI template as the base URL of a client. - You can also specify a `defaults` key that is an associative array of default - request options. You can pass an `adapter` to use a custom adapter, - `batch_adapter` to use a custom adapter for sending requests in parallel, or - a `message_factory` to change the factory used to create HTTP requests and - responses. -- The client no longer emits a `client.create_request` event. -- Creating requests with a client no longer automatically utilize a URI - template. You must pass an array into a creational method (e.g., - `createRequest`, `get`, `put`, etc.) in order to expand a URI template. - -### Messages - -Messages no longer have references to their counterparts (i.e., a request no -longer has a reference to it's response, and a response no loger has a -reference to its request). This association is now managed through a -`GuzzleHttp\Adapter\TransactionInterface` object. You can get references to -these transaction objects using request events that are emitted over the -lifecycle of a request. - -#### Requests with a body - -- `GuzzleHttp\Message\EntityEnclosingRequest` and - `GuzzleHttp\Message\EntityEnclosingRequestInterface` have been removed. The - separation between requests that contain a body and requests that do not - contain a body has been removed, and now `GuzzleHttp\Message\RequestInterface` - handles both use cases. -- Any method that previously accepts a `GuzzleHttp\Response` object now accept a - `GuzzleHttp\Message\ResponseInterface`. -- `GuzzleHttp\Message\RequestFactoryInterface` has been renamed to - `GuzzleHttp\Message\MessageFactoryInterface`. This interface is used to create - both requests and responses and is implemented in - `GuzzleHttp\Message\MessageFactory`. -- POST field and file methods have been removed from the request object. You - must now use the methods made available to `GuzzleHttp\Post\PostBodyInterface` - to control the format of a POST body. Requests that are created using a - standard `GuzzleHttp\Message\MessageFactoryInterface` will automatically use - a `GuzzleHttp\Post\PostBody` body if the body was passed as an array or if - the method is POST and no body is provided. - -```php -$request = $client->createRequest('POST', '/'); -$request->getBody()->setField('foo', 'bar'); -$request->getBody()->addFile(new PostFile('file_key', fopen('/path/to/content', 'r'))); -``` - -#### Headers - -- `GuzzleHttp\Message\Header` has been removed. Header values are now simply - represented by an array of values or as a string. Header values are returned - as a string by default when retrieving a header value from a message. You can - pass an optional argument of `true` to retrieve a header value as an array - of strings instead of a single concatenated string. -- `GuzzleHttp\PostFile` and `GuzzleHttp\PostFileInterface` have been moved to - `GuzzleHttp\Post`. This interface has been simplified and now allows the - addition of arbitrary headers. -- Custom headers like `GuzzleHttp\Message\Header\Link` have been removed. Most - of the custom headers are now handled separately in specific - subscribers/plugins, and `GuzzleHttp\Message\HeaderValues::parseParams()` has - been updated to properly handle headers that contain parameters (like the - `Link` header). - -#### Responses - -- `GuzzleHttp\Message\Response::getInfo()` and - `GuzzleHttp\Message\Response::setInfo()` have been removed. Use the event - system to retrieve this type of information. -- `GuzzleHttp\Message\Response::getRawHeaders()` has been removed. -- `GuzzleHttp\Message\Response::getMessage()` has been removed. -- `GuzzleHttp\Message\Response::calculateAge()` and other cache specific - methods have moved to the CacheSubscriber. -- Header specific helper functions like `getContentMd5()` have been removed. - Just use `getHeader('Content-MD5')` instead. -- `GuzzleHttp\Message\Response::setRequest()` and - `GuzzleHttp\Message\Response::getRequest()` have been removed. Use the event - system to work with request and response objects as a transaction. -- `GuzzleHttp\Message\Response::getRedirectCount()` has been removed. Use the - Redirect subscriber instead. -- `GuzzleHttp\Message\Response::isSuccessful()` and other related methods have - been removed. Use `getStatusCode()` instead. - -#### Streaming responses - -Streaming requests can now be created by a client directly, returning a -`GuzzleHttp\Message\ResponseInterface` object that contains a body stream -referencing an open PHP HTTP stream. - -```php -// 3.0 -use Guzzle\Stream\PhpStreamRequestFactory; -$request = $client->get('/'); -$factory = new PhpStreamRequestFactory(); -$stream = $factory->fromRequest($request); -$data = $stream->read(1024); - -// 4.0 -$response = $client->get('/', ['stream' => true]); -// Read some data off of the stream in the response body -$data = $response->getBody()->read(1024); -``` - -#### Redirects - -The `configureRedirects()` method has been removed in favor of a -`allow_redirects` request option. - -```php -// Standard redirects with a default of a max of 5 redirects -$request = $client->createRequest('GET', '/', ['allow_redirects' => true]); - -// Strict redirects with a custom number of redirects -$request = $client->createRequest('GET', '/', [ - 'allow_redirects' => ['max' => 5, 'strict' => true] -]); -``` - -#### EntityBody - -EntityBody interfaces and classes have been removed or moved to -`GuzzleHttp\Stream`. All classes and interfaces that once required -`GuzzleHttp\EntityBodyInterface` now require -`GuzzleHttp\Stream\StreamInterface`. Creating a new body for a request no -longer uses `GuzzleHttp\EntityBody::factory` but now uses -`GuzzleHttp\Stream\Stream::factory` or even better: -`GuzzleHttp\Stream\create()`. - -- `Guzzle\Http\EntityBodyInterface` is now `GuzzleHttp\Stream\StreamInterface` -- `Guzzle\Http\EntityBody` is now `GuzzleHttp\Stream\Stream` -- `Guzzle\Http\CachingEntityBody` is now `GuzzleHttp\Stream\CachingStream` -- `Guzzle\Http\ReadLimitEntityBody` is now `GuzzleHttp\Stream\LimitStream` -- `Guzzle\Http\IoEmittyinEntityBody` has been removed. - -#### Request lifecycle events - -Requests previously submitted a large number of requests. The number of events -emitted over the lifecycle of a request has been significantly reduced to make -it easier to understand how to extend the behavior of a request. All events -emitted during the lifecycle of a request now emit a custom -`GuzzleHttp\Event\EventInterface` object that contains context providing -methods and a way in which to modify the transaction at that specific point in -time (e.g., intercept the request and set a response on the transaction). - -- `request.before_send` has been renamed to `before` and now emits a - `GuzzleHttp\Event\BeforeEvent` -- `request.complete` has been renamed to `complete` and now emits a - `GuzzleHttp\Event\CompleteEvent`. -- `request.sent` has been removed. Use `complete`. -- `request.success` has been removed. Use `complete`. -- `error` is now an event that emits a `GuzzleHttp\Event\ErrorEvent`. -- `request.exception` has been removed. Use `error`. -- `request.receive.status_line` has been removed. -- `curl.callback.progress` has been removed. Use a custom `StreamInterface` to - maintain a status update. -- `curl.callback.write` has been removed. Use a custom `StreamInterface` to - intercept writes. -- `curl.callback.read` has been removed. Use a custom `StreamInterface` to - intercept reads. - -`headers` is a new event that is emitted after the response headers of a -request have been received before the body of the response is downloaded. This -event emits a `GuzzleHttp\Event\HeadersEvent`. - -You can intercept a request and inject a response using the `intercept()` event -of a `GuzzleHttp\Event\BeforeEvent`, `GuzzleHttp\Event\CompleteEvent`, and -`GuzzleHttp\Event\ErrorEvent` event. - -See: http://docs.guzzlephp.org/en/latest/events.html - -## Inflection - -The `Guzzle\Inflection` namespace has been removed. This is not a core concern -of Guzzle. - -## Iterator - -The `Guzzle\Iterator` namespace has been removed. - -- `Guzzle\Iterator\AppendIterator`, `Guzzle\Iterator\ChunkedIterator`, and - `Guzzle\Iterator\MethodProxyIterator` are nice, but not a core requirement of - Guzzle itself. -- `Guzzle\Iterator\FilterIterator` is no longer needed because an equivalent - class is shipped with PHP 5.4. -- `Guzzle\Iterator\MapIterator` is not really needed when using PHP 5.5 because - it's easier to just wrap an iterator in a generator that maps values. - -For a replacement of these iterators, see https://github.com/nikic/iter - -## Log - -The LogPlugin has moved to https://github.com/guzzle/log-subscriber. The -`Guzzle\Log` namespace has been removed. Guzzle now relies on -`Psr\Log\LoggerInterface` for all logging. The MessageFormatter class has been -moved to `GuzzleHttp\Subscriber\Log\Formatter`. - -## Parser - -The `Guzzle\Parser` namespace has been removed. This was previously used to -make it possible to plug in custom parsers for cookies, messages, URI -templates, and URLs; however, this level of complexity is not needed in Guzzle -so it has been removed. - -- Cookie: Cookie parsing logic has been moved to - `GuzzleHttp\Cookie\SetCookie::fromString`. -- Message: Message parsing logic for both requests and responses has been moved - to `GuzzleHttp\Message\MessageFactory::fromMessage`. Message parsing is only - used in debugging or deserializing messages, so it doesn't make sense for - Guzzle as a library to add this level of complexity to parsing messages. -- UriTemplate: URI template parsing has been moved to - `GuzzleHttp\UriTemplate`. The Guzzle library will automatically use the PECL - URI template library if it is installed. -- Url: URL parsing is now performed in `GuzzleHttp\Url::fromString` (previously - it was `Guzzle\Http\Url::factory()`). If custom URL parsing is necessary, - then developers are free to subclass `GuzzleHttp\Url`. - -## Plugin - -The `Guzzle\Plugin` namespace has been renamed to `GuzzleHttp\Subscriber`. -Several plugins are shipping with the core Guzzle library under this namespace. - -- `GuzzleHttp\Subscriber\Cookie`: Replaces the old CookiePlugin. Cookie jar - code has moved to `GuzzleHttp\Cookie`. -- `GuzzleHttp\Subscriber\History`: Replaces the old HistoryPlugin. -- `GuzzleHttp\Subscriber\HttpError`: Throws errors when a bad HTTP response is - received. -- `GuzzleHttp\Subscriber\Mock`: Replaces the old MockPlugin. -- `GuzzleHttp\Subscriber\Prepare`: Prepares the body of a request just before - sending. This subscriber is attached to all requests by default. -- `GuzzleHttp\Subscriber\Redirect`: Replaces the RedirectPlugin. - -The following plugins have been removed (third-parties are free to re-implement -these if needed): - -- `GuzzleHttp\Plugin\Async` has been removed. -- `GuzzleHttp\Plugin\CurlAuth` has been removed. -- `GuzzleHttp\Plugin\ErrorResponse\ErrorResponsePlugin` has been removed. This - functionality should instead be implemented with event listeners that occur - after normal response parsing occurs in the guzzle/command package. - -The following plugins are not part of the core Guzzle package, but are provided -in separate repositories: - -- `Guzzle\Http\Plugin\BackoffPlugin` has been rewritten to be much simpler - to build custom retry policies using simple functions rather than various - chained classes. See: https://github.com/guzzle/retry-subscriber -- `Guzzle\Http\Plugin\Cache\CachePlugin` has moved to - https://github.com/guzzle/cache-subscriber -- `Guzzle\Http\Plugin\Log\LogPlugin` has moved to - https://github.com/guzzle/log-subscriber -- `Guzzle\Http\Plugin\Md5\Md5Plugin` has moved to - https://github.com/guzzle/message-integrity-subscriber -- `Guzzle\Http\Plugin\Mock\MockPlugin` has moved to - `GuzzleHttp\Subscriber\MockSubscriber`. -- `Guzzle\Http\Plugin\Oauth\OauthPlugin` has moved to - https://github.com/guzzle/oauth-subscriber - -## Service - -The service description layer of Guzzle has moved into two separate packages: - -- http://github.com/guzzle/command Provides a high level abstraction over web - services by representing web service operations using commands. -- http://github.com/guzzle/guzzle-services Provides an implementation of - guzzle/command that provides request serialization and response parsing using - Guzzle service descriptions. - -## Stream - -Stream have moved to a separate package available at -https://github.com/guzzle/streams. - -`Guzzle\Stream\StreamInterface` has been given a large update to cleanly take -on the responsibilities of `Guzzle\Http\EntityBody` and -`Guzzle\Http\EntityBodyInterface` now that they have been removed. The number -of methods implemented by the `StreamInterface` has been drastically reduced to -allow developers to more easily extend and decorate stream behavior. - -## Removed methods from StreamInterface - -- `getStream` and `setStream` have been removed to better encapsulate streams. -- `getMetadata` and `setMetadata` have been removed in favor of - `GuzzleHttp\Stream\MetadataStreamInterface`. -- `getWrapper`, `getWrapperData`, `getStreamType`, and `getUri` have all been - removed. This data is accessible when - using streams that implement `GuzzleHttp\Stream\MetadataStreamInterface`. -- `rewind` has been removed. Use `seek(0)` for a similar behavior. - -## Renamed methods - -- `detachStream` has been renamed to `detach`. -- `feof` has been renamed to `eof`. -- `ftell` has been renamed to `tell`. -- `readLine` has moved from an instance method to a static class method of - `GuzzleHttp\Stream\Stream`. - -## Metadata streams - -`GuzzleHttp\Stream\MetadataStreamInterface` has been added to denote streams -that contain additional metadata accessible via `getMetadata()`. -`GuzzleHttp\Stream\StreamInterface::getMetadata` and -`GuzzleHttp\Stream\StreamInterface::setMetadata` have been removed. - -## StreamRequestFactory - -The entire concept of the StreamRequestFactory has been removed. The way this -was used in Guzzle 3 broke the actual interface of sending streaming requests -(instead of getting back a Response, you got a StreamInterface). Streaming -PHP requests are now implemented through the `GuzzleHttp\Adapter\StreamAdapter`. - -3.6 to 3.7 ----------- - -### Deprecations - -- You can now enable E_USER_DEPRECATED warnings to see if you are using any deprecated methods.: - -```php -\Guzzle\Common\Version::$emitWarnings = true; -``` - -The following APIs and options have been marked as deprecated: - -- Marked `Guzzle\Http\Message\Request::isResponseBodyRepeatable()` as deprecated. Use `$request->getResponseBody()->isRepeatable()` instead. -- Marked `Guzzle\Http\Message\Request::canCache()` as deprecated. Use `Guzzle\Plugin\Cache\DefaultCanCacheStrategy->canCacheRequest()` instead. -- Marked `Guzzle\Http\Message\Request::canCache()` as deprecated. Use `Guzzle\Plugin\Cache\DefaultCanCacheStrategy->canCacheRequest()` instead. -- Marked `Guzzle\Http\Message\Request::setIsRedirect()` as deprecated. Use the HistoryPlugin instead. -- Marked `Guzzle\Http\Message\Request::isRedirect()` as deprecated. Use the HistoryPlugin instead. -- Marked `Guzzle\Cache\CacheAdapterFactory::factory()` as deprecated -- Marked `Guzzle\Service\Client::enableMagicMethods()` as deprecated. Magic methods can no longer be disabled on a Guzzle\Service\Client. -- Marked `Guzzle\Parser\Url\UrlParser` as deprecated. Just use PHP's `parse_url()` and percent encode your UTF-8. -- Marked `Guzzle\Common\Collection::inject()` as deprecated. -- Marked `Guzzle\Plugin\CurlAuth\CurlAuthPlugin` as deprecated. Use - `$client->getConfig()->setPath('request.options/auth', array('user', 'pass', 'Basic|Digest|NTLM|Any'));` or - `$client->setDefaultOption('auth', array('user', 'pass', 'Basic|Digest|NTLM|Any'));` - -3.7 introduces `request.options` as a parameter for a client configuration and as an optional argument to all creational -request methods. When paired with a client's configuration settings, these options allow you to specify default settings -for various aspects of a request. Because these options make other previous configuration options redundant, several -configuration options and methods of a client and AbstractCommand have been deprecated. - -- Marked `Guzzle\Service\Client::getDefaultHeaders()` as deprecated. Use `$client->getDefaultOption('headers')`. -- Marked `Guzzle\Service\Client::setDefaultHeaders()` as deprecated. Use `$client->setDefaultOption('headers/{header_name}', 'value')`. -- Marked 'request.params' for `Guzzle\Http\Client` as deprecated. Use `$client->setDefaultOption('params/{param_name}', 'value')` -- Marked 'command.headers', 'command.response_body' and 'command.on_complete' as deprecated for AbstractCommand. These will work through Guzzle 4.0 - - $command = $client->getCommand('foo', array( - 'command.headers' => array('Test' => '123'), - 'command.response_body' => '/path/to/file' - )); - - // Should be changed to: - - $command = $client->getCommand('foo', array( - 'command.request_options' => array( - 'headers' => array('Test' => '123'), - 'save_as' => '/path/to/file' - ) - )); - -### Interface changes - -Additions and changes (you will need to update any implementations or subclasses you may have created): - -- Added an `$options` argument to the end of the following methods of `Guzzle\Http\ClientInterface`: - createRequest, head, delete, put, patch, post, options, prepareRequest -- Added an `$options` argument to the end of `Guzzle\Http\Message\Request\RequestFactoryInterface::createRequest()` -- Added an `applyOptions()` method to `Guzzle\Http\Message\Request\RequestFactoryInterface` -- Changed `Guzzle\Http\ClientInterface::get($uri = null, $headers = null, $body = null)` to - `Guzzle\Http\ClientInterface::get($uri = null, $headers = null, $options = array())`. You can still pass in a - resource, string, or EntityBody into the $options parameter to specify the download location of the response. -- Changed `Guzzle\Common\Collection::__construct($data)` to no longer accepts a null value for `$data` but a - default `array()` -- Added `Guzzle\Stream\StreamInterface::isRepeatable` -- Made `Guzzle\Http\Client::expandTemplate` and `getUriTemplate` protected methods. - -The following methods were removed from interfaces. All of these methods are still available in the concrete classes -that implement them, but you should update your code to use alternative methods: - -- Removed `Guzzle\Http\ClientInterface::setDefaultHeaders(). Use - `$client->getConfig()->setPath('request.options/headers/{header_name}', 'value')`. or - `$client->getConfig()->setPath('request.options/headers', array('header_name' => 'value'))` or - `$client->setDefaultOption('headers/{header_name}', 'value')`. or - `$client->setDefaultOption('headers', array('header_name' => 'value'))`. -- Removed `Guzzle\Http\ClientInterface::getDefaultHeaders(). Use `$client->getConfig()->getPath('request.options/headers')`. -- Removed `Guzzle\Http\ClientInterface::expandTemplate()`. This is an implementation detail. -- Removed `Guzzle\Http\ClientInterface::setRequestFactory()`. This is an implementation detail. -- Removed `Guzzle\Http\ClientInterface::getCurlMulti()`. This is a very specific implementation detail. -- Removed `Guzzle\Http\Message\RequestInterface::canCache`. Use the CachePlugin. -- Removed `Guzzle\Http\Message\RequestInterface::setIsRedirect`. Use the HistoryPlugin. -- Removed `Guzzle\Http\Message\RequestInterface::isRedirect`. Use the HistoryPlugin. - -### Cache plugin breaking changes - -- CacheKeyProviderInterface and DefaultCacheKeyProvider are no longer used. All of this logic is handled in a - CacheStorageInterface. These two objects and interface will be removed in a future version. -- Always setting X-cache headers on cached responses -- Default cache TTLs are now handled by the CacheStorageInterface of a CachePlugin -- `CacheStorageInterface::cache($key, Response $response, $ttl = null)` has changed to `cache(RequestInterface - $request, Response $response);` -- `CacheStorageInterface::fetch($key)` has changed to `fetch(RequestInterface $request);` -- `CacheStorageInterface::delete($key)` has changed to `delete(RequestInterface $request);` -- Added `CacheStorageInterface::purge($url)` -- `DefaultRevalidation::__construct(CacheKeyProviderInterface $cacheKey, CacheStorageInterface $cache, CachePlugin - $plugin)` has changed to `DefaultRevalidation::__construct(CacheStorageInterface $cache, - CanCacheStrategyInterface $canCache = null)` -- Added `RevalidationInterface::shouldRevalidate(RequestInterface $request, Response $response)` - -3.5 to 3.6 ----------- - -* Mixed casing of headers are now forced to be a single consistent casing across all values for that header. -* Messages internally use a HeaderCollection object to delegate handling case-insensitive header resolution -* Removed the whole changedHeader() function system of messages because all header changes now go through addHeader(). - For example, setHeader() first removes the header using unset on a HeaderCollection and then calls addHeader(). - Keeping the Host header and URL host in sync is now handled by overriding the addHeader method in Request. -* Specific header implementations can be created for complex headers. When a message creates a header, it uses a - HeaderFactory which can map specific headers to specific header classes. There is now a Link header and - CacheControl header implementation. -* Moved getLinks() from Response to just be used on a Link header object. - -If you previously relied on Guzzle\Http\Message\Header::raw(), then you will need to update your code to use the -HeaderInterface (e.g. toArray(), getAll(), etc.). - -### Interface changes - -* Removed from interface: Guzzle\Http\ClientInterface::setUriTemplate -* Removed from interface: Guzzle\Http\ClientInterface::setCurlMulti() -* Removed Guzzle\Http\Message\Request::receivedRequestHeader() and implemented this functionality in - Guzzle\Http\Curl\RequestMediator -* Removed the optional $asString parameter from MessageInterface::getHeader(). Just cast the header to a string. -* Removed the optional $tryChunkedTransfer option from Guzzle\Http\Message\EntityEnclosingRequestInterface -* Removed the $asObjects argument from Guzzle\Http\Message\MessageInterface::getHeaders() - -### Removed deprecated functions - -* Removed Guzzle\Parser\ParserRegister::get(). Use getParser() -* Removed Guzzle\Parser\ParserRegister::set(). Use registerParser(). - -### Deprecations - -* The ability to case-insensitively search for header values -* Guzzle\Http\Message\Header::hasExactHeader -* Guzzle\Http\Message\Header::raw. Use getAll() -* Deprecated cache control specific methods on Guzzle\Http\Message\AbstractMessage. Use the CacheControl header object - instead. - -### Other changes - -* All response header helper functions return a string rather than mixing Header objects and strings inconsistently -* Removed cURL blacklist support. This is no longer necessary now that Expect, Accept, etc. are managed by Guzzle - directly via interfaces -* Removed the injecting of a request object onto a response object. The methods to get and set a request still exist - but are a no-op until removed. -* Most classes that used to require a `Guzzle\Service\Command\CommandInterface` typehint now request a - `Guzzle\Service\Command\ArrayCommandInterface`. -* Added `Guzzle\Http\Message\RequestInterface::startResponse()` to the RequestInterface to handle injecting a response - on a request while the request is still being transferred -* `Guzzle\Service\Command\CommandInterface` now extends from ToArrayInterface and ArrayAccess - -3.3 to 3.4 ----------- - -Base URLs of a client now follow the rules of https://tools.ietf.org/html/rfc3986#section-5.2.2 when merging URLs. - -3.2 to 3.3 ----------- - -### Response::getEtag() quote stripping removed - -`Guzzle\Http\Message\Response::getEtag()` no longer strips quotes around the ETag response header - -### Removed `Guzzle\Http\Utils` - -The `Guzzle\Http\Utils` class was removed. This class was only used for testing. - -### Stream wrapper and type - -`Guzzle\Stream\Stream::getWrapper()` and `Guzzle\Stream\Stream::getStreamType()` are no longer converted to lowercase. - -### curl.emit_io became emit_io - -Emitting IO events from a RequestMediator is now a parameter that must be set in a request's curl options using the -'emit_io' key. This was previously set under a request's parameters using 'curl.emit_io' - -3.1 to 3.2 ----------- - -### CurlMulti is no longer reused globally - -Before 3.2, the same CurlMulti object was reused globally for each client. This can cause issue where plugins added -to a single client can pollute requests dispatched from other clients. - -If you still wish to reuse the same CurlMulti object with each client, then you can add a listener to the -ServiceBuilder's `service_builder.create_client` event to inject a custom CurlMulti object into each client as it is -created. - -```php -$multi = new Guzzle\Http\Curl\CurlMulti(); -$builder = Guzzle\Service\Builder\ServiceBuilder::factory('/path/to/config.json'); -$builder->addListener('service_builder.create_client', function ($event) use ($multi) { - $event['client']->setCurlMulti($multi); -} -}); -``` - -### No default path - -URLs no longer have a default path value of '/' if no path was specified. - -Before: - -```php -$request = $client->get('http://www.foo.com'); -echo $request->getUrl(); -// >> http://www.foo.com/ -``` - -After: - -```php -$request = $client->get('http://www.foo.com'); -echo $request->getUrl(); -// >> http://www.foo.com -``` - -### Less verbose BadResponseException - -The exception message for `Guzzle\Http\Exception\BadResponseException` no longer contains the full HTTP request and -response information. You can, however, get access to the request and response object by calling `getRequest()` or -`getResponse()` on the exception object. - -### Query parameter aggregation - -Multi-valued query parameters are no longer aggregated using a callback function. `Guzzle\Http\Query` now has a -setAggregator() method that accepts a `Guzzle\Http\QueryAggregator\QueryAggregatorInterface` object. This object is -responsible for handling the aggregation of multi-valued query string variables into a flattened hash. - -2.8 to 3.x ----------- - -### Guzzle\Service\Inspector - -Change `\Guzzle\Service\Inspector::fromConfig` to `\Guzzle\Common\Collection::fromConfig` - -**Before** - -```php -use Guzzle\Service\Inspector; - -class YourClient extends \Guzzle\Service\Client -{ - public static function factory($config = array()) - { - $default = array(); - $required = array('base_url', 'username', 'api_key'); - $config = Inspector::fromConfig($config, $default, $required); - - $client = new self( - $config->get('base_url'), - $config->get('username'), - $config->get('api_key') - ); - $client->setConfig($config); - - $client->setDescription(ServiceDescription::factory(__DIR__ . DIRECTORY_SEPARATOR . 'client.json')); - - return $client; - } -``` - -**After** - -```php -use Guzzle\Common\Collection; - -class YourClient extends \Guzzle\Service\Client -{ - public static function factory($config = array()) - { - $default = array(); - $required = array('base_url', 'username', 'api_key'); - $config = Collection::fromConfig($config, $default, $required); - - $client = new self( - $config->get('base_url'), - $config->get('username'), - $config->get('api_key') - ); - $client->setConfig($config); - - $client->setDescription(ServiceDescription::factory(__DIR__ . DIRECTORY_SEPARATOR . 'client.json')); - - return $client; - } -``` - -### Convert XML Service Descriptions to JSON - -**Before** - -```xml - - - - - - Get a list of groups - - - Uses a search query to get a list of groups - - - - Create a group - - - - - Delete a group by ID - - - - - - - Update a group - - - - - - -``` - -**After** - -```json -{ - "name": "Zendesk REST API v2", - "apiVersion": "2012-12-31", - "description":"Provides access to Zendesk views, groups, tickets, ticket fields, and users", - "operations": { - "list_groups": { - "httpMethod":"GET", - "uri": "groups.json", - "summary": "Get a list of groups" - }, - "search_groups":{ - "httpMethod":"GET", - "uri": "search.json?query=\"{query} type:group\"", - "summary": "Uses a search query to get a list of groups", - "parameters":{ - "query":{ - "location": "uri", - "description":"Zendesk Search Query", - "type": "string", - "required": true - } - } - }, - "create_group": { - "httpMethod":"POST", - "uri": "groups.json", - "summary": "Create a group", - "parameters":{ - "data": { - "type": "array", - "location": "body", - "description":"Group JSON", - "filters": "json_encode", - "required": true - }, - "Content-Type":{ - "type": "string", - "location":"header", - "static": "application/json" - } - } - }, - "delete_group": { - "httpMethod":"DELETE", - "uri": "groups/{id}.json", - "summary": "Delete a group", - "parameters":{ - "id":{ - "location": "uri", - "description":"Group to delete by ID", - "type": "integer", - "required": true - } - } - }, - "get_group": { - "httpMethod":"GET", - "uri": "groups/{id}.json", - "summary": "Get a ticket", - "parameters":{ - "id":{ - "location": "uri", - "description":"Group to get by ID", - "type": "integer", - "required": true - } - } - }, - "update_group": { - "httpMethod":"PUT", - "uri": "groups/{id}.json", - "summary": "Update a group", - "parameters":{ - "id": { - "location": "uri", - "description":"Group to update by ID", - "type": "integer", - "required": true - }, - "data": { - "type": "array", - "location": "body", - "description":"Group JSON", - "filters": "json_encode", - "required": true - }, - "Content-Type":{ - "type": "string", - "location":"header", - "static": "application/json" - } - } - } -} -``` - -### Guzzle\Service\Description\ServiceDescription - -Commands are now called Operations - -**Before** - -```php -use Guzzle\Service\Description\ServiceDescription; - -$sd = new ServiceDescription(); -$sd->getCommands(); // @returns ApiCommandInterface[] -$sd->hasCommand($name); -$sd->getCommand($name); // @returns ApiCommandInterface|null -$sd->addCommand($command); // @param ApiCommandInterface $command -``` - -**After** - -```php -use Guzzle\Service\Description\ServiceDescription; - -$sd = new ServiceDescription(); -$sd->getOperations(); // @returns OperationInterface[] -$sd->hasOperation($name); -$sd->getOperation($name); // @returns OperationInterface|null -$sd->addOperation($operation); // @param OperationInterface $operation -``` - -### Guzzle\Common\Inflection\Inflector - -Namespace is now `Guzzle\Inflection\Inflector` - -### Guzzle\Http\Plugin - -Namespace is now `Guzzle\Plugin`. Many other changes occur within this namespace and are detailed in their own sections below. - -### Guzzle\Http\Plugin\LogPlugin and Guzzle\Common\Log - -Now `Guzzle\Plugin\Log\LogPlugin` and `Guzzle\Log` respectively. - -**Before** - -```php -use Guzzle\Common\Log\ClosureLogAdapter; -use Guzzle\Http\Plugin\LogPlugin; - -/** @var \Guzzle\Http\Client */ -$client; - -// $verbosity is an integer indicating desired message verbosity level -$client->addSubscriber(new LogPlugin(new ClosureLogAdapter(function($m) { echo $m; }, $verbosity = LogPlugin::LOG_VERBOSE); -``` - -**After** - -```php -use Guzzle\Log\ClosureLogAdapter; -use Guzzle\Log\MessageFormatter; -use Guzzle\Plugin\Log\LogPlugin; - -/** @var \Guzzle\Http\Client */ -$client; - -// $format is a string indicating desired message format -- @see MessageFormatter -$client->addSubscriber(new LogPlugin(new ClosureLogAdapter(function($m) { echo $m; }, $format = MessageFormatter::DEBUG_FORMAT); -``` - -### Guzzle\Http\Plugin\CurlAuthPlugin - -Now `Guzzle\Plugin\CurlAuth\CurlAuthPlugin`. - -### Guzzle\Http\Plugin\ExponentialBackoffPlugin - -Now `Guzzle\Plugin\Backoff\BackoffPlugin`, and other changes. - -**Before** - -```php -use Guzzle\Http\Plugin\ExponentialBackoffPlugin; - -$backoffPlugin = new ExponentialBackoffPlugin($maxRetries, array_merge( - ExponentialBackoffPlugin::getDefaultFailureCodes(), array(429) - )); - -$client->addSubscriber($backoffPlugin); -``` - -**After** - -```php -use Guzzle\Plugin\Backoff\BackoffPlugin; -use Guzzle\Plugin\Backoff\HttpBackoffStrategy; - -// Use convenient factory method instead -- see implementation for ideas of what -// you can do with chaining backoff strategies -$backoffPlugin = BackoffPlugin::getExponentialBackoff($maxRetries, array_merge( - HttpBackoffStrategy::getDefaultFailureCodes(), array(429) - )); -$client->addSubscriber($backoffPlugin); -``` - -### Known Issues - -#### [BUG] Accept-Encoding header behavior changed unintentionally. - -(See #217) (Fixed in 09daeb8c666fb44499a0646d655a8ae36456575e) - -In version 2.8 setting the `Accept-Encoding` header would set the CURLOPT_ENCODING option, which permitted cURL to -properly handle gzip/deflate compressed responses from the server. In versions affected by this bug this does not happen. -See issue #217 for a workaround, or use a version containing the fix. diff --git a/plugins/automagic-images/vendor/guzzlehttp/guzzle/composer.json b/plugins/automagic-images/vendor/guzzlehttp/guzzle/composer.json deleted file mode 100644 index 5da35a5..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/guzzle/composer.json +++ /dev/null @@ -1,73 +0,0 @@ -{ - "name": "guzzlehttp/guzzle", - "type": "library", - "description": "Guzzle is a PHP HTTP client library", - "keywords": [ - "framework", - "http", - "rest", - "web service", - "curl", - "client", - "HTTP client", - "PSR-7", - "PSR-18" - ], - "homepage": "http://guzzlephp.org/", - "license": "MIT", - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - }, - { - "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com", - "homepage": "https://sagikazarmark.hu" - } - ], - "require": { - "php": "^7.2.5 || ^8.0", - "ext-json": "*", - "guzzlehttp/promises": "^1.4", - "guzzlehttp/psr7": "^1.7 || ^2.0", - "psr/http-client": "^1.0" - }, - "provide": { - "psr/http-client-implementation": "1.0" - }, - "require-dev": { - "ext-curl": "*", - "bamarni/composer-bin-plugin": "^1.4.1", - "php-http/client-integration-tests": "^3.0", - "phpunit/phpunit": "^8.5.5 || ^9.3.5", - "psr/log": "^1.1" - }, - "suggest": { - "ext-curl": "Required for CURL handler support", - "ext-intl": "Required for Internationalized Domain Name (IDN) support", - "psr/log": "Required for using the Log middleware" - }, - "config": { - "sort-packages": true - }, - "extra": { - "branch-alias": { - "dev-master": "7.3-dev" - } - }, - "autoload": { - "psr-4": { - "GuzzleHttp\\": "src/" - }, - "files": [ - "src/functions_include.php" - ] - }, - "autoload-dev": { - "psr-4": { - "GuzzleHttp\\Tests\\": "tests/" - } - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/BodySummarizer.php b/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/BodySummarizer.php deleted file mode 100644 index 6eca94e..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/BodySummarizer.php +++ /dev/null @@ -1,28 +0,0 @@ -truncateAt = $truncateAt; - } - - /** - * Returns a summarized message body. - */ - public function summarize(MessageInterface $message): ?string - { - return $this->truncateAt === null - ? \GuzzleHttp\Psr7\Message::bodySummary($message) - : \GuzzleHttp\Psr7\Message::bodySummary($message, $this->truncateAt); - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/BodySummarizerInterface.php b/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/BodySummarizerInterface.php deleted file mode 100644 index 3e02e03..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/BodySummarizerInterface.php +++ /dev/null @@ -1,13 +0,0 @@ - 'http://www.foo.com/1.0/', - * 'timeout' => 0, - * 'allow_redirects' => false, - * 'proxy' => '192.168.16.1:10' - * ]); - * - * Client configuration settings include the following options: - * - * - handler: (callable) Function that transfers HTTP requests over the - * wire. The function is called with a Psr7\Http\Message\RequestInterface - * and array of transfer options, and must return a - * GuzzleHttp\Promise\PromiseInterface that is fulfilled with a - * Psr7\Http\Message\ResponseInterface on success. - * If no handler is provided, a default handler will be created - * that enables all of the request options below by attaching all of the - * default middleware to the handler. - * - base_uri: (string|UriInterface) Base URI of the client that is merged - * into relative URIs. Can be a string or instance of UriInterface. - * - **: any request option - * - * @param array $config Client configuration settings. - * - * @see \GuzzleHttp\RequestOptions for a list of available request options. - */ - public function __construct(array $config = []) - { - if (!isset($config['handler'])) { - $config['handler'] = HandlerStack::create(); - } elseif (!\is_callable($config['handler'])) { - throw new InvalidArgumentException('handler must be a callable'); - } - - // Convert the base_uri to a UriInterface - if (isset($config['base_uri'])) { - $config['base_uri'] = Psr7\Utils::uriFor($config['base_uri']); - } - - $this->configureDefaults($config); - } - - /** - * @param string $method - * @param array $args - * - * @return PromiseInterface|ResponseInterface - * - * @deprecated Client::__call will be removed in guzzlehttp/guzzle:8.0. - */ - public function __call($method, $args) - { - if (\count($args) < 1) { - throw new InvalidArgumentException('Magic request methods require a URI and optional options array'); - } - - $uri = $args[0]; - $opts = $args[1] ?? []; - - return \substr($method, -5) === 'Async' - ? $this->requestAsync(\substr($method, 0, -5), $uri, $opts) - : $this->request($method, $uri, $opts); - } - - /** - * Asynchronously send an HTTP request. - * - * @param array $options Request options to apply to the given - * request and to the transfer. See \GuzzleHttp\RequestOptions. - */ - public function sendAsync(RequestInterface $request, array $options = []): PromiseInterface - { - // Merge the base URI into the request URI if needed. - $options = $this->prepareDefaults($options); - - return $this->transfer( - $request->withUri($this->buildUri($request->getUri(), $options), $request->hasHeader('Host')), - $options - ); - } - - /** - * Send an HTTP request. - * - * @param array $options Request options to apply to the given - * request and to the transfer. See \GuzzleHttp\RequestOptions. - * - * @throws GuzzleException - */ - public function send(RequestInterface $request, array $options = []): ResponseInterface - { - $options[RequestOptions::SYNCHRONOUS] = true; - return $this->sendAsync($request, $options)->wait(); - } - - /** - * The HttpClient PSR (PSR-18) specify this method. - * - * @inheritDoc - */ - public function sendRequest(RequestInterface $request): ResponseInterface - { - $options[RequestOptions::SYNCHRONOUS] = true; - $options[RequestOptions::ALLOW_REDIRECTS] = false; - $options[RequestOptions::HTTP_ERRORS] = false; - - return $this->sendAsync($request, $options)->wait(); - } - - /** - * Create and send an asynchronous HTTP request. - * - * Use an absolute path to override the base path of the client, or a - * relative path to append to the base path of the client. The URL can - * contain the query string as well. Use an array to provide a URL - * template and additional variables to use in the URL template expansion. - * - * @param string $method HTTP method - * @param string|UriInterface $uri URI object or string. - * @param array $options Request options to apply. See \GuzzleHttp\RequestOptions. - */ - public function requestAsync(string $method, $uri = '', array $options = []): PromiseInterface - { - $options = $this->prepareDefaults($options); - // Remove request modifying parameter because it can be done up-front. - $headers = $options['headers'] ?? []; - $body = $options['body'] ?? null; - $version = $options['version'] ?? '1.1'; - // Merge the URI into the base URI. - $uri = $this->buildUri(Psr7\Utils::uriFor($uri), $options); - if (\is_array($body)) { - throw $this->invalidBody(); - } - $request = new Psr7\Request($method, $uri, $headers, $body, $version); - // Remove the option so that they are not doubly-applied. - unset($options['headers'], $options['body'], $options['version']); - - return $this->transfer($request, $options); - } - - /** - * Create and send an HTTP request. - * - * Use an absolute path to override the base path of the client, or a - * relative path to append to the base path of the client. The URL can - * contain the query string as well. - * - * @param string $method HTTP method. - * @param string|UriInterface $uri URI object or string. - * @param array $options Request options to apply. See \GuzzleHttp\RequestOptions. - * - * @throws GuzzleException - */ - public function request(string $method, $uri = '', array $options = []): ResponseInterface - { - $options[RequestOptions::SYNCHRONOUS] = true; - return $this->requestAsync($method, $uri, $options)->wait(); - } - - /** - * Get a client configuration option. - * - * These options include default request options of the client, a "handler" - * (if utilized by the concrete client), and a "base_uri" if utilized by - * the concrete client. - * - * @param string|null $option The config option to retrieve. - * - * @return mixed - * - * @deprecated Client::getConfig will be removed in guzzlehttp/guzzle:8.0. - */ - public function getConfig(?string $option = null) - { - return $option === null - ? $this->config - : ($this->config[$option] ?? null); - } - - private function buildUri(UriInterface $uri, array $config): UriInterface - { - if (isset($config['base_uri'])) { - $uri = Psr7\UriResolver::resolve(Psr7\Utils::uriFor($config['base_uri']), $uri); - } - - if (isset($config['idn_conversion']) && ($config['idn_conversion'] !== false)) { - $idnOptions = ($config['idn_conversion'] === true) ? \IDNA_DEFAULT : $config['idn_conversion']; - $uri = Utils::idnUriConvert($uri, $idnOptions); - } - - return $uri->getScheme() === '' && $uri->getHost() !== '' ? $uri->withScheme('http') : $uri; - } - - /** - * Configures the default options for a client. - */ - private function configureDefaults(array $config): void - { - $defaults = [ - 'allow_redirects' => RedirectMiddleware::$defaultSettings, - 'http_errors' => true, - 'decode_content' => true, - 'verify' => true, - 'cookies' => false, - 'idn_conversion' => false, - ]; - - // Use the standard Linux HTTP_PROXY and HTTPS_PROXY if set. - - // We can only trust the HTTP_PROXY environment variable in a CLI - // process due to the fact that PHP has no reliable mechanism to - // get environment variables that start with "HTTP_". - if (\PHP_SAPI === 'cli' && ($proxy = Utils::getenv('HTTP_PROXY'))) { - $defaults['proxy']['http'] = $proxy; - } - - if ($proxy = Utils::getenv('HTTPS_PROXY')) { - $defaults['proxy']['https'] = $proxy; - } - - if ($noProxy = Utils::getenv('NO_PROXY')) { - $cleanedNoProxy = \str_replace(' ', '', $noProxy); - $defaults['proxy']['no'] = \explode(',', $cleanedNoProxy); - } - - $this->config = $config + $defaults; - - if (!empty($config['cookies']) && $config['cookies'] === true) { - $this->config['cookies'] = new CookieJar(); - } - - // Add the default user-agent header. - if (!isset($this->config['headers'])) { - $this->config['headers'] = ['User-Agent' => Utils::defaultUserAgent()]; - } else { - // Add the User-Agent header if one was not already set. - foreach (\array_keys($this->config['headers']) as $name) { - if (\strtolower($name) === 'user-agent') { - return; - } - } - $this->config['headers']['User-Agent'] = Utils::defaultUserAgent(); - } - } - - /** - * Merges default options into the array. - * - * @param array $options Options to modify by reference - */ - private function prepareDefaults(array $options): array - { - $defaults = $this->config; - - if (!empty($defaults['headers'])) { - // Default headers are only added if they are not present. - $defaults['_conditional'] = $defaults['headers']; - unset($defaults['headers']); - } - - // Special handling for headers is required as they are added as - // conditional headers and as headers passed to a request ctor. - if (\array_key_exists('headers', $options)) { - // Allows default headers to be unset. - if ($options['headers'] === null) { - $defaults['_conditional'] = []; - unset($options['headers']); - } elseif (!\is_array($options['headers'])) { - throw new InvalidArgumentException('headers must be an array'); - } - } - - // Shallow merge defaults underneath options. - $result = $options + $defaults; - - // Remove null values. - foreach ($result as $k => $v) { - if ($v === null) { - unset($result[$k]); - } - } - - return $result; - } - - /** - * Transfers the given request and applies request options. - * - * The URI of the request is not modified and the request options are used - * as-is without merging in default options. - * - * @param array $options See \GuzzleHttp\RequestOptions. - */ - private function transfer(RequestInterface $request, array $options): PromiseInterface - { - $request = $this->applyOptions($request, $options); - /** @var HandlerStack $handler */ - $handler = $options['handler']; - - try { - return P\Create::promiseFor($handler($request, $options)); - } catch (\Exception $e) { - return P\Create::rejectionFor($e); - } - } - - /** - * Applies the array of request options to a request. - */ - private function applyOptions(RequestInterface $request, array &$options): RequestInterface - { - $modify = [ - 'set_headers' => [], - ]; - - if (isset($options['headers'])) { - $modify['set_headers'] = $options['headers']; - unset($options['headers']); - } - - if (isset($options['form_params'])) { - if (isset($options['multipart'])) { - throw new InvalidArgumentException('You cannot use ' - . 'form_params and multipart at the same time. Use the ' - . 'form_params option if you want to send application/' - . 'x-www-form-urlencoded requests, and the multipart ' - . 'option to send multipart/form-data requests.'); - } - $options['body'] = \http_build_query($options['form_params'], '', '&'); - unset($options['form_params']); - // Ensure that we don't have the header in different case and set the new value. - $options['_conditional'] = Psr7\Utils::caselessRemove(['Content-Type'], $options['_conditional']); - $options['_conditional']['Content-Type'] = 'application/x-www-form-urlencoded'; - } - - if (isset($options['multipart'])) { - $options['body'] = new Psr7\MultipartStream($options['multipart']); - unset($options['multipart']); - } - - if (isset($options['json'])) { - $options['body'] = Utils::jsonEncode($options['json']); - unset($options['json']); - // Ensure that we don't have the header in different case and set the new value. - $options['_conditional'] = Psr7\Utils::caselessRemove(['Content-Type'], $options['_conditional']); - $options['_conditional']['Content-Type'] = 'application/json'; - } - - if (!empty($options['decode_content']) - && $options['decode_content'] !== true - ) { - // Ensure that we don't have the header in different case and set the new value. - $options['_conditional'] = Psr7\Utils::caselessRemove(['Accept-Encoding'], $options['_conditional']); - $modify['set_headers']['Accept-Encoding'] = $options['decode_content']; - } - - if (isset($options['body'])) { - if (\is_array($options['body'])) { - throw $this->invalidBody(); - } - $modify['body'] = Psr7\Utils::streamFor($options['body']); - unset($options['body']); - } - - if (!empty($options['auth']) && \is_array($options['auth'])) { - $value = $options['auth']; - $type = isset($value[2]) ? \strtolower($value[2]) : 'basic'; - switch ($type) { - case 'basic': - // Ensure that we don't have the header in different case and set the new value. - $modify['set_headers'] = Psr7\Utils::caselessRemove(['Authorization'], $modify['set_headers']); - $modify['set_headers']['Authorization'] = 'Basic ' - . \base64_encode("$value[0]:$value[1]"); - break; - case 'digest': - // @todo: Do not rely on curl - $options['curl'][\CURLOPT_HTTPAUTH] = \CURLAUTH_DIGEST; - $options['curl'][\CURLOPT_USERPWD] = "$value[0]:$value[1]"; - break; - case 'ntlm': - $options['curl'][\CURLOPT_HTTPAUTH] = \CURLAUTH_NTLM; - $options['curl'][\CURLOPT_USERPWD] = "$value[0]:$value[1]"; - break; - } - } - - if (isset($options['query'])) { - $value = $options['query']; - if (\is_array($value)) { - $value = \http_build_query($value, '', '&', \PHP_QUERY_RFC3986); - } - if (!\is_string($value)) { - throw new InvalidArgumentException('query must be a string or array'); - } - $modify['query'] = $value; - unset($options['query']); - } - - // Ensure that sink is not an invalid value. - if (isset($options['sink'])) { - // TODO: Add more sink validation? - if (\is_bool($options['sink'])) { - throw new InvalidArgumentException('sink must not be a boolean'); - } - } - - $request = Psr7\Utils::modifyRequest($request, $modify); - if ($request->getBody() instanceof Psr7\MultipartStream) { - // Use a multipart/form-data POST if a Content-Type is not set. - // Ensure that we don't have the header in different case and set the new value. - $options['_conditional'] = Psr7\Utils::caselessRemove(['Content-Type'], $options['_conditional']); - $options['_conditional']['Content-Type'] = 'multipart/form-data; boundary=' - . $request->getBody()->getBoundary(); - } - - // Merge in conditional headers if they are not present. - if (isset($options['_conditional'])) { - // Build up the changes so it's in a single clone of the message. - $modify = []; - foreach ($options['_conditional'] as $k => $v) { - if (!$request->hasHeader($k)) { - $modify['set_headers'][$k] = $v; - } - } - $request = Psr7\Utils::modifyRequest($request, $modify); - // Don't pass this internal value along to middleware/handlers. - unset($options['_conditional']); - } - - return $request; - } - - /** - * Return an InvalidArgumentException with pre-set message. - */ - private function invalidBody(): InvalidArgumentException - { - return new InvalidArgumentException('Passing in the "body" request ' - . 'option as an array to send a request is not supported. ' - . 'Please use the "form_params" request option to send a ' - . 'application/x-www-form-urlencoded request, or the "multipart" ' - . 'request option to send a multipart/form-data request.'); - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/ClientInterface.php b/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/ClientInterface.php deleted file mode 100644 index f257a1a..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/ClientInterface.php +++ /dev/null @@ -1,84 +0,0 @@ -request('GET', $uri, $options); - } - - /** - * Create and send an HTTP HEAD request. - * - * Use an absolute path to override the base path of the client, or a - * relative path to append to the base path of the client. The URL can - * contain the query string as well. - * - * @param string|UriInterface $uri URI object or string. - * @param array $options Request options to apply. - * - * @throws GuzzleException - */ - public function head($uri, array $options = []): ResponseInterface - { - return $this->request('HEAD', $uri, $options); - } - - /** - * Create and send an HTTP PUT request. - * - * Use an absolute path to override the base path of the client, or a - * relative path to append to the base path of the client. The URL can - * contain the query string as well. - * - * @param string|UriInterface $uri URI object or string. - * @param array $options Request options to apply. - * - * @throws GuzzleException - */ - public function put($uri, array $options = []): ResponseInterface - { - return $this->request('PUT', $uri, $options); - } - - /** - * Create and send an HTTP POST request. - * - * Use an absolute path to override the base path of the client, or a - * relative path to append to the base path of the client. The URL can - * contain the query string as well. - * - * @param string|UriInterface $uri URI object or string. - * @param array $options Request options to apply. - * - * @throws GuzzleException - */ - public function post($uri, array $options = []): ResponseInterface - { - return $this->request('POST', $uri, $options); - } - - /** - * Create and send an HTTP PATCH request. - * - * Use an absolute path to override the base path of the client, or a - * relative path to append to the base path of the client. The URL can - * contain the query string as well. - * - * @param string|UriInterface $uri URI object or string. - * @param array $options Request options to apply. - * - * @throws GuzzleException - */ - public function patch($uri, array $options = []): ResponseInterface - { - return $this->request('PATCH', $uri, $options); - } - - /** - * Create and send an HTTP DELETE request. - * - * Use an absolute path to override the base path of the client, or a - * relative path to append to the base path of the client. The URL can - * contain the query string as well. - * - * @param string|UriInterface $uri URI object or string. - * @param array $options Request options to apply. - * - * @throws GuzzleException - */ - public function delete($uri, array $options = []): ResponseInterface - { - return $this->request('DELETE', $uri, $options); - } - - /** - * Create and send an asynchronous HTTP request. - * - * Use an absolute path to override the base path of the client, or a - * relative path to append to the base path of the client. The URL can - * contain the query string as well. Use an array to provide a URL - * template and additional variables to use in the URL template expansion. - * - * @param string $method HTTP method - * @param string|UriInterface $uri URI object or string. - * @param array $options Request options to apply. - */ - abstract public function requestAsync(string $method, $uri, array $options = []): PromiseInterface; - - /** - * Create and send an asynchronous HTTP GET request. - * - * Use an absolute path to override the base path of the client, or a - * relative path to append to the base path of the client. The URL can - * contain the query string as well. Use an array to provide a URL - * template and additional variables to use in the URL template expansion. - * - * @param string|UriInterface $uri URI object or string. - * @param array $options Request options to apply. - */ - public function getAsync($uri, array $options = []): PromiseInterface - { - return $this->requestAsync('GET', $uri, $options); - } - - /** - * Create and send an asynchronous HTTP HEAD request. - * - * Use an absolute path to override the base path of the client, or a - * relative path to append to the base path of the client. The URL can - * contain the query string as well. Use an array to provide a URL - * template and additional variables to use in the URL template expansion. - * - * @param string|UriInterface $uri URI object or string. - * @param array $options Request options to apply. - */ - public function headAsync($uri, array $options = []): PromiseInterface - { - return $this->requestAsync('HEAD', $uri, $options); - } - - /** - * Create and send an asynchronous HTTP PUT request. - * - * Use an absolute path to override the base path of the client, or a - * relative path to append to the base path of the client. The URL can - * contain the query string as well. Use an array to provide a URL - * template and additional variables to use in the URL template expansion. - * - * @param string|UriInterface $uri URI object or string. - * @param array $options Request options to apply. - */ - public function putAsync($uri, array $options = []): PromiseInterface - { - return $this->requestAsync('PUT', $uri, $options); - } - - /** - * Create and send an asynchronous HTTP POST request. - * - * Use an absolute path to override the base path of the client, or a - * relative path to append to the base path of the client. The URL can - * contain the query string as well. Use an array to provide a URL - * template and additional variables to use in the URL template expansion. - * - * @param string|UriInterface $uri URI object or string. - * @param array $options Request options to apply. - */ - public function postAsync($uri, array $options = []): PromiseInterface - { - return $this->requestAsync('POST', $uri, $options); - } - - /** - * Create and send an asynchronous HTTP PATCH request. - * - * Use an absolute path to override the base path of the client, or a - * relative path to append to the base path of the client. The URL can - * contain the query string as well. Use an array to provide a URL - * template and additional variables to use in the URL template expansion. - * - * @param string|UriInterface $uri URI object or string. - * @param array $options Request options to apply. - */ - public function patchAsync($uri, array $options = []): PromiseInterface - { - return $this->requestAsync('PATCH', $uri, $options); - } - - /** - * Create and send an asynchronous HTTP DELETE request. - * - * Use an absolute path to override the base path of the client, or a - * relative path to append to the base path of the client. The URL can - * contain the query string as well. Use an array to provide a URL - * template and additional variables to use in the URL template expansion. - * - * @param string|UriInterface $uri URI object or string. - * @param array $options Request options to apply. - */ - public function deleteAsync($uri, array $options = []): PromiseInterface - { - return $this->requestAsync('DELETE', $uri, $options); - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Cookie/CookieJar.php b/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Cookie/CookieJar.php deleted file mode 100644 index d6757c6..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Cookie/CookieJar.php +++ /dev/null @@ -1,313 +0,0 @@ -strictMode = $strictMode; - - foreach ($cookieArray as $cookie) { - if (!($cookie instanceof SetCookie)) { - $cookie = new SetCookie($cookie); - } - $this->setCookie($cookie); - } - } - - /** - * Create a new Cookie jar from an associative array and domain. - * - * @param array $cookies Cookies to create the jar from - * @param string $domain Domain to set the cookies to - */ - public static function fromArray(array $cookies, string $domain): self - { - $cookieJar = new self(); - foreach ($cookies as $name => $value) { - $cookieJar->setCookie(new SetCookie([ - 'Domain' => $domain, - 'Name' => $name, - 'Value' => $value, - 'Discard' => true - ])); - } - - return $cookieJar; - } - - /** - * Evaluate if this cookie should be persisted to storage - * that survives between requests. - * - * @param SetCookie $cookie Being evaluated. - * @param bool $allowSessionCookies If we should persist session cookies - */ - public static function shouldPersist(SetCookie $cookie, bool $allowSessionCookies = false): bool - { - if ($cookie->getExpires() || $allowSessionCookies) { - if (!$cookie->getDiscard()) { - return true; - } - } - - return false; - } - - /** - * Finds and returns the cookie based on the name - * - * @param string $name cookie name to search for - * - * @return SetCookie|null cookie that was found or null if not found - */ - public function getCookieByName(string $name): ?SetCookie - { - foreach ($this->cookies as $cookie) { - if ($cookie->getName() !== null && \strcasecmp($cookie->getName(), $name) === 0) { - return $cookie; - } - } - - return null; - } - - /** - * @inheritDoc - */ - public function toArray(): array - { - return \array_map(static function (SetCookie $cookie): array { - return $cookie->toArray(); - }, $this->getIterator()->getArrayCopy()); - } - - /** - * @inheritDoc - */ - public function clear(?string $domain = null, ?string $path = null, ?string $name = null): void - { - if (!$domain) { - $this->cookies = []; - return; - } elseif (!$path) { - $this->cookies = \array_filter( - $this->cookies, - static function (SetCookie $cookie) use ($domain): bool { - return !$cookie->matchesDomain($domain); - } - ); - } elseif (!$name) { - $this->cookies = \array_filter( - $this->cookies, - static function (SetCookie $cookie) use ($path, $domain): bool { - return !($cookie->matchesPath($path) && - $cookie->matchesDomain($domain)); - } - ); - } else { - $this->cookies = \array_filter( - $this->cookies, - static function (SetCookie $cookie) use ($path, $domain, $name) { - return !($cookie->getName() == $name && - $cookie->matchesPath($path) && - $cookie->matchesDomain($domain)); - } - ); - } - } - - /** - * @inheritDoc - */ - public function clearSessionCookies(): void - { - $this->cookies = \array_filter( - $this->cookies, - static function (SetCookie $cookie): bool { - return !$cookie->getDiscard() && $cookie->getExpires(); - } - ); - } - - /** - * @inheritDoc - */ - public function setCookie(SetCookie $cookie): bool - { - // If the name string is empty (but not 0), ignore the set-cookie - // string entirely. - $name = $cookie->getName(); - if (!$name && $name !== '0') { - return false; - } - - // Only allow cookies with set and valid domain, name, value - $result = $cookie->validate(); - if ($result !== true) { - if ($this->strictMode) { - throw new \RuntimeException('Invalid cookie: ' . $result); - } - $this->removeCookieIfEmpty($cookie); - return false; - } - - // Resolve conflicts with previously set cookies - foreach ($this->cookies as $i => $c) { - - // Two cookies are identical, when their path, and domain are - // identical. - if ($c->getPath() != $cookie->getPath() || - $c->getDomain() != $cookie->getDomain() || - $c->getName() != $cookie->getName() - ) { - continue; - } - - // The previously set cookie is a discard cookie and this one is - // not so allow the new cookie to be set - if (!$cookie->getDiscard() && $c->getDiscard()) { - unset($this->cookies[$i]); - continue; - } - - // If the new cookie's expiration is further into the future, then - // replace the old cookie - if ($cookie->getExpires() > $c->getExpires()) { - unset($this->cookies[$i]); - continue; - } - - // If the value has changed, we better change it - if ($cookie->getValue() !== $c->getValue()) { - unset($this->cookies[$i]); - continue; - } - - // The cookie exists, so no need to continue - return false; - } - - $this->cookies[] = $cookie; - - return true; - } - - public function count(): int - { - return \count($this->cookies); - } - - /** - * @return \ArrayIterator - */ - public function getIterator(): \ArrayIterator - { - return new \ArrayIterator(\array_values($this->cookies)); - } - - public function extractCookies(RequestInterface $request, ResponseInterface $response): void - { - if ($cookieHeader = $response->getHeader('Set-Cookie')) { - foreach ($cookieHeader as $cookie) { - $sc = SetCookie::fromString($cookie); - if (!$sc->getDomain()) { - $sc->setDomain($request->getUri()->getHost()); - } - if (0 !== \strpos($sc->getPath(), '/')) { - $sc->setPath($this->getCookiePathFromRequest($request)); - } - $this->setCookie($sc); - } - } - } - - /** - * Computes cookie path following RFC 6265 section 5.1.4 - * - * @link https://tools.ietf.org/html/rfc6265#section-5.1.4 - */ - private function getCookiePathFromRequest(RequestInterface $request): string - { - $uriPath = $request->getUri()->getPath(); - if ('' === $uriPath) { - return '/'; - } - if (0 !== \strpos($uriPath, '/')) { - return '/'; - } - if ('/' === $uriPath) { - return '/'; - } - $lastSlashPos = \strrpos($uriPath, '/'); - if (0 === $lastSlashPos || false === $lastSlashPos) { - return '/'; - } - - return \substr($uriPath, 0, $lastSlashPos); - } - - public function withCookieHeader(RequestInterface $request): RequestInterface - { - $values = []; - $uri = $request->getUri(); - $scheme = $uri->getScheme(); - $host = $uri->getHost(); - $path = $uri->getPath() ?: '/'; - - foreach ($this->cookies as $cookie) { - if ($cookie->matchesPath($path) && - $cookie->matchesDomain($host) && - !$cookie->isExpired() && - (!$cookie->getSecure() || $scheme === 'https') - ) { - $values[] = $cookie->getName() . '=' - . $cookie->getValue(); - } - } - - return $values - ? $request->withHeader('Cookie', \implode('; ', $values)) - : $request; - } - - /** - * If a cookie already exists and the server asks to set it again with a - * null value, the cookie must be deleted. - */ - private function removeCookieIfEmpty(SetCookie $cookie): void - { - $cookieValue = $cookie->getValue(); - if ($cookieValue === null || $cookieValue === '') { - $this->clear( - $cookie->getDomain(), - $cookie->getPath(), - $cookie->getName() - ); - } - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php b/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php deleted file mode 100644 index 7df374b..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php +++ /dev/null @@ -1,79 +0,0 @@ - - */ -interface CookieJarInterface extends \Countable, \IteratorAggregate -{ - /** - * Create a request with added cookie headers. - * - * If no matching cookies are found in the cookie jar, then no Cookie - * header is added to the request and the same request is returned. - * - * @param RequestInterface $request Request object to modify. - * - * @return RequestInterface returns the modified request. - */ - public function withCookieHeader(RequestInterface $request): RequestInterface; - - /** - * Extract cookies from an HTTP response and store them in the CookieJar. - * - * @param RequestInterface $request Request that was sent - * @param ResponseInterface $response Response that was received - */ - public function extractCookies(RequestInterface $request, ResponseInterface $response): void; - - /** - * Sets a cookie in the cookie jar. - * - * @param SetCookie $cookie Cookie to set. - * - * @return bool Returns true on success or false on failure - */ - public function setCookie(SetCookie $cookie): bool; - - /** - * Remove cookies currently held in the cookie jar. - * - * Invoking this method without arguments will empty the whole cookie jar. - * If given a $domain argument only cookies belonging to that domain will - * be removed. If given a $domain and $path argument, cookies belonging to - * the specified path within that domain are removed. If given all three - * arguments, then the cookie with the specified name, path and domain is - * removed. - * - * @param string|null $domain Clears cookies matching a domain - * @param string|null $path Clears cookies matching a domain and path - * @param string|null $name Clears cookies matching a domain, path, and name - */ - public function clear(?string $domain = null, ?string $path = null, ?string $name = null): void; - - /** - * Discard all sessions cookies. - * - * Removes cookies that don't have an expire field or a have a discard - * field set to true. To be called when the user agent shuts down according - * to RFC 2965. - */ - public function clearSessionCookies(): void; - - /** - * Converts the cookie jar to an array. - */ - public function toArray(): array; -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Cookie/FileCookieJar.php b/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Cookie/FileCookieJar.php deleted file mode 100644 index 290236d..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Cookie/FileCookieJar.php +++ /dev/null @@ -1,101 +0,0 @@ -filename = $cookieFile; - $this->storeSessionCookies = $storeSessionCookies; - - if (\file_exists($cookieFile)) { - $this->load($cookieFile); - } - } - - /** - * Saves the file when shutting down - */ - public function __destruct() - { - $this->save($this->filename); - } - - /** - * Saves the cookies to a file. - * - * @param string $filename File to save - * - * @throws \RuntimeException if the file cannot be found or created - */ - public function save(string $filename): void - { - $json = []; - /** @var SetCookie $cookie */ - foreach ($this as $cookie) { - if (CookieJar::shouldPersist($cookie, $this->storeSessionCookies)) { - $json[] = $cookie->toArray(); - } - } - - $jsonStr = Utils::jsonEncode($json); - if (false === \file_put_contents($filename, $jsonStr, \LOCK_EX)) { - throw new \RuntimeException("Unable to save file {$filename}"); - } - } - - /** - * Load cookies from a JSON formatted file. - * - * Old cookies are kept unless overwritten by newly loaded ones. - * - * @param string $filename Cookie file to load. - * - * @throws \RuntimeException if the file cannot be loaded. - */ - public function load(string $filename): void - { - $json = \file_get_contents($filename); - if (false === $json) { - throw new \RuntimeException("Unable to load file {$filename}"); - } - if ($json === '') { - return; - } - - $data = Utils::jsonDecode($json, true); - if (\is_array($data)) { - foreach ($data as $cookie) { - $this->setCookie(new SetCookie($cookie)); - } - } elseif (\is_scalar($data) && !empty($data)) { - throw new \RuntimeException("Invalid cookie file: {$filename}"); - } - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Cookie/SessionCookieJar.php b/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Cookie/SessionCookieJar.php deleted file mode 100644 index 5d51ca9..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Cookie/SessionCookieJar.php +++ /dev/null @@ -1,77 +0,0 @@ -sessionKey = $sessionKey; - $this->storeSessionCookies = $storeSessionCookies; - $this->load(); - } - - /** - * Saves cookies to session when shutting down - */ - public function __destruct() - { - $this->save(); - } - - /** - * Save cookies to the client session - */ - public function save(): void - { - $json = []; - /** @var SetCookie $cookie */ - foreach ($this as $cookie) { - if (CookieJar::shouldPersist($cookie, $this->storeSessionCookies)) { - $json[] = $cookie->toArray(); - } - } - - $_SESSION[$this->sessionKey] = \json_encode($json); - } - - /** - * Load the contents of the client session into the data array - */ - protected function load(): void - { - if (!isset($_SESSION[$this->sessionKey])) { - return; - } - $data = \json_decode($_SESSION[$this->sessionKey], true); - if (\is_array($data)) { - foreach ($data as $cookie) { - $this->setCookie(new SetCookie($cookie)); - } - } elseif (\strlen($data)) { - throw new \RuntimeException("Invalid cookie data"); - } - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Cookie/SetCookie.php b/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Cookie/SetCookie.php deleted file mode 100644 index 602370d..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Cookie/SetCookie.php +++ /dev/null @@ -1,410 +0,0 @@ - null, - 'Value' => null, - 'Domain' => null, - 'Path' => '/', - 'Max-Age' => null, - 'Expires' => null, - 'Secure' => false, - 'Discard' => false, - 'HttpOnly' => false - ]; - - /** - * @var array Cookie data - */ - private $data; - - /** - * Create a new SetCookie object from a string. - * - * @param string $cookie Set-Cookie header string - */ - public static function fromString(string $cookie): self - { - // Create the default return array - $data = self::$defaults; - // Explode the cookie string using a series of semicolons - $pieces = \array_filter(\array_map('trim', \explode(';', $cookie))); - // The name of the cookie (first kvp) must exist and include an equal sign. - if (!isset($pieces[0]) || \strpos($pieces[0], '=') === false) { - return new self($data); - } - - // Add the cookie pieces into the parsed data array - foreach ($pieces as $part) { - $cookieParts = \explode('=', $part, 2); - $key = \trim($cookieParts[0]); - $value = isset($cookieParts[1]) - ? \trim($cookieParts[1], " \n\r\t\0\x0B") - : true; - - // Only check for non-cookies when cookies have been found - if (!isset($data['Name'])) { - $data['Name'] = $key; - $data['Value'] = $value; - } else { - foreach (\array_keys(self::$defaults) as $search) { - if (!\strcasecmp($search, $key)) { - $data[$search] = $value; - continue 2; - } - } - $data[$key] = $value; - } - } - - return new self($data); - } - - /** - * @param array $data Array of cookie data provided by a Cookie parser - */ - public function __construct(array $data = []) - { - /** @var array|null $replaced will be null in case of replace error */ - $replaced = \array_replace(self::$defaults, $data); - if ($replaced === null) { - throw new \InvalidArgumentException('Unable to replace the default values for the Cookie.'); - } - - $this->data = $replaced; - // Extract the Expires value and turn it into a UNIX timestamp if needed - if (!$this->getExpires() && $this->getMaxAge()) { - // Calculate the Expires date - $this->setExpires(\time() + $this->getMaxAge()); - } elseif (null !== ($expires = $this->getExpires()) && !\is_numeric($expires)) { - $this->setExpires($expires); - } - } - - public function __toString() - { - $str = $this->data['Name'] . '=' . $this->data['Value'] . '; '; - foreach ($this->data as $k => $v) { - if ($k !== 'Name' && $k !== 'Value' && $v !== null && $v !== false) { - if ($k === 'Expires') { - $str .= 'Expires=' . \gmdate('D, d M Y H:i:s \G\M\T', $v) . '; '; - } else { - $str .= ($v === true ? $k : "{$k}={$v}") . '; '; - } - } - } - - return \rtrim($str, '; '); - } - - public function toArray(): array - { - return $this->data; - } - - /** - * Get the cookie name. - * - * @return string - */ - public function getName() - { - return $this->data['Name']; - } - - /** - * Set the cookie name. - * - * @param string $name Cookie name - */ - public function setName($name): void - { - $this->data['Name'] = $name; - } - - /** - * Get the cookie value. - * - * @return string|null - */ - public function getValue() - { - return $this->data['Value']; - } - - /** - * Set the cookie value. - * - * @param string $value Cookie value - */ - public function setValue($value): void - { - $this->data['Value'] = $value; - } - - /** - * Get the domain. - * - * @return string|null - */ - public function getDomain() - { - return $this->data['Domain']; - } - - /** - * Set the domain of the cookie. - * - * @param string $domain - */ - public function setDomain($domain): void - { - $this->data['Domain'] = $domain; - } - - /** - * Get the path. - * - * @return string - */ - public function getPath() - { - return $this->data['Path']; - } - - /** - * Set the path of the cookie. - * - * @param string $path Path of the cookie - */ - public function setPath($path): void - { - $this->data['Path'] = $path; - } - - /** - * Maximum lifetime of the cookie in seconds. - * - * @return int|null - */ - public function getMaxAge() - { - return $this->data['Max-Age']; - } - - /** - * Set the max-age of the cookie. - * - * @param int $maxAge Max age of the cookie in seconds - */ - public function setMaxAge($maxAge): void - { - $this->data['Max-Age'] = $maxAge; - } - - /** - * The UNIX timestamp when the cookie Expires. - * - * @return string|int|null - */ - public function getExpires() - { - return $this->data['Expires']; - } - - /** - * Set the unix timestamp for which the cookie will expire. - * - * @param int|string $timestamp Unix timestamp or any English textual datetime description. - */ - public function setExpires($timestamp): void - { - $this->data['Expires'] = \is_numeric($timestamp) - ? (int) $timestamp - : \strtotime($timestamp); - } - - /** - * Get whether or not this is a secure cookie. - * - * @return bool|null - */ - public function getSecure() - { - return $this->data['Secure']; - } - - /** - * Set whether or not the cookie is secure. - * - * @param bool $secure Set to true or false if secure - */ - public function setSecure($secure): void - { - $this->data['Secure'] = $secure; - } - - /** - * Get whether or not this is a session cookie. - * - * @return bool|null - */ - public function getDiscard() - { - return $this->data['Discard']; - } - - /** - * Set whether or not this is a session cookie. - * - * @param bool $discard Set to true or false if this is a session cookie - */ - public function setDiscard($discard): void - { - $this->data['Discard'] = $discard; - } - - /** - * Get whether or not this is an HTTP only cookie. - * - * @return bool - */ - public function getHttpOnly() - { - return $this->data['HttpOnly']; - } - - /** - * Set whether or not this is an HTTP only cookie. - * - * @param bool $httpOnly Set to true or false if this is HTTP only - */ - public function setHttpOnly($httpOnly): void - { - $this->data['HttpOnly'] = $httpOnly; - } - - /** - * Check if the cookie matches a path value. - * - * A request-path path-matches a given cookie-path if at least one of - * the following conditions holds: - * - * - The cookie-path and the request-path are identical. - * - The cookie-path is a prefix of the request-path, and the last - * character of the cookie-path is %x2F ("/"). - * - The cookie-path is a prefix of the request-path, and the first - * character of the request-path that is not included in the cookie- - * path is a %x2F ("/") character. - * - * @param string $requestPath Path to check against - */ - public function matchesPath(string $requestPath): bool - { - $cookiePath = $this->getPath(); - - // Match on exact matches or when path is the default empty "/" - if ($cookiePath === '/' || $cookiePath == $requestPath) { - return true; - } - - // Ensure that the cookie-path is a prefix of the request path. - if (0 !== \strpos($requestPath, $cookiePath)) { - return false; - } - - // Match if the last character of the cookie-path is "/" - if (\substr($cookiePath, -1, 1) === '/') { - return true; - } - - // Match if the first character not included in cookie path is "/" - return \substr($requestPath, \strlen($cookiePath), 1) === '/'; - } - - /** - * Check if the cookie matches a domain value. - * - * @param string $domain Domain to check against - */ - public function matchesDomain(string $domain): bool - { - $cookieDomain = $this->getDomain(); - if (null === $cookieDomain) { - return true; - } - - // Remove the leading '.' as per spec in RFC 6265. - // https://tools.ietf.org/html/rfc6265#section-5.2.3 - $cookieDomain = \ltrim($cookieDomain, '.'); - - // Domain not set or exact match. - if (!$cookieDomain || !\strcasecmp($domain, $cookieDomain)) { - return true; - } - - // Matching the subdomain according to RFC 6265. - // https://tools.ietf.org/html/rfc6265#section-5.1.3 - if (\filter_var($domain, \FILTER_VALIDATE_IP)) { - return false; - } - - return (bool) \preg_match('/\.' . \preg_quote($cookieDomain, '/') . '$/', $domain); - } - - /** - * Check if the cookie is expired. - */ - public function isExpired(): bool - { - return $this->getExpires() !== null && \time() > $this->getExpires(); - } - - /** - * Check if the cookie is valid according to RFC 6265. - * - * @return bool|string Returns true if valid or an error message if invalid - */ - public function validate() - { - $name = $this->getName(); - if ($name === '') { - return 'The cookie name must not be empty'; - } - - // Check if any of the invalid characters are present in the cookie name - if (\preg_match( - '/[\x00-\x20\x22\x28-\x29\x2c\x2f\x3a-\x40\x5c\x7b\x7d\x7f]/', - $name - )) { - return 'Cookie name must not contain invalid characters: ASCII ' - . 'Control characters (0-31;127), space, tab and the ' - . 'following characters: ()<>@,;:\"/?={}'; - } - - // Value must not be null. 0 and empty string are valid. Empty strings - // are technically against RFC 6265, but known to happen in the wild. - $value = $this->getValue(); - if ($value === null) { - return 'The cookie value must not be empty'; - } - - // Domains must not be empty, but can be 0. "0" is not a valid internet - // domain, but may be used as server name in a private network. - $domain = $this->getDomain(); - if ($domain === null || $domain === '') { - return 'The cookie domain must not be empty'; - } - - return true; - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Exception/BadResponseException.php b/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Exception/BadResponseException.php deleted file mode 100644 index a80956c..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Exception/BadResponseException.php +++ /dev/null @@ -1,39 +0,0 @@ -request = $request; - $this->handlerContext = $handlerContext; - } - - /** - * Get the request that caused the exception - */ - public function getRequest(): RequestInterface - { - return $this->request; - } - - /** - * Get contextual information about the error from the underlying handler. - * - * The contents of this array will vary depending on which handler you are - * using. It may also be just an empty array. Relying on this data will - * couple you to a specific handler, but can give more debug information - * when needed. - */ - public function getHandlerContext(): array - { - return $this->handlerContext; - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Exception/GuzzleException.php b/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Exception/GuzzleException.php deleted file mode 100644 index fa3ed69..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Exception/GuzzleException.php +++ /dev/null @@ -1,9 +0,0 @@ -getStatusCode() : 0; - parent::__construct($message, $code, $previous); - $this->request = $request; - $this->response = $response; - $this->handlerContext = $handlerContext; - } - - /** - * Wrap non-RequestExceptions with a RequestException - */ - public static function wrapException(RequestInterface $request, \Throwable $e): RequestException - { - return $e instanceof RequestException ? $e : new RequestException($e->getMessage(), $request, null, $e); - } - - /** - * Factory method to create a new exception with a normalized error message - * - * @param RequestInterface $request Request sent - * @param ResponseInterface $response Response received - * @param \Throwable|null $previous Previous exception - * @param array $handlerContext Optional handler context - * @param BodySummarizerInterface|null $bodySummarizer Optional body summarizer - */ - public static function create( - RequestInterface $request, - ResponseInterface $response = null, - \Throwable $previous = null, - array $handlerContext = [], - BodySummarizerInterface $bodySummarizer = null - ): self { - if (!$response) { - return new self( - 'Error completing request', - $request, - null, - $previous, - $handlerContext - ); - } - - $level = (int) \floor($response->getStatusCode() / 100); - if ($level === 4) { - $label = 'Client error'; - $className = ClientException::class; - } elseif ($level === 5) { - $label = 'Server error'; - $className = ServerException::class; - } else { - $label = 'Unsuccessful request'; - $className = __CLASS__; - } - - $uri = $request->getUri(); - $uri = static::obfuscateUri($uri); - - // Client Error: `GET /` resulted in a `404 Not Found` response: - // ... (truncated) - $message = \sprintf( - '%s: `%s %s` resulted in a `%s %s` response', - $label, - $request->getMethod(), - $uri, - $response->getStatusCode(), - $response->getReasonPhrase() - ); - - $summary = ($bodySummarizer ?? new BodySummarizer())->summarize($response); - - if ($summary !== null) { - $message .= ":\n{$summary}\n"; - } - - return new $className($message, $request, $response, $previous, $handlerContext); - } - - /** - * Obfuscates URI if there is a username and a password present - */ - private static function obfuscateUri(UriInterface $uri): UriInterface - { - $userInfo = $uri->getUserInfo(); - - if (false !== ($pos = \strpos($userInfo, ':'))) { - return $uri->withUserInfo(\substr($userInfo, 0, $pos), '***'); - } - - return $uri; - } - - /** - * Get the request that caused the exception - */ - public function getRequest(): RequestInterface - { - return $this->request; - } - - /** - * Get the associated response - */ - public function getResponse(): ?ResponseInterface - { - return $this->response; - } - - /** - * Check if a response was received - */ - public function hasResponse(): bool - { - return $this->response !== null; - } - - /** - * Get contextual information about the error from the underlying handler. - * - * The contents of this array will vary depending on which handler you are - * using. It may also be just an empty array. Relying on this data will - * couple you to a specific handler, but can give more debug information - * when needed. - */ - public function getHandlerContext(): array - { - return $this->handlerContext; - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Exception/ServerException.php b/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Exception/ServerException.php deleted file mode 100644 index 8055e06..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Exception/ServerException.php +++ /dev/null @@ -1,10 +0,0 @@ -maxHandles = $maxHandles; - } - - public function create(RequestInterface $request, array $options): EasyHandle - { - if (isset($options['curl']['body_as_string'])) { - $options['_body_as_string'] = $options['curl']['body_as_string']; - unset($options['curl']['body_as_string']); - } - - $easy = new EasyHandle; - $easy->request = $request; - $easy->options = $options; - $conf = $this->getDefaultConf($easy); - $this->applyMethod($easy, $conf); - $this->applyHandlerOptions($easy, $conf); - $this->applyHeaders($easy, $conf); - unset($conf['_headers']); - - // Add handler options from the request configuration options - if (isset($options['curl'])) { - $conf = \array_replace($conf, $options['curl']); - } - - $conf[\CURLOPT_HEADERFUNCTION] = $this->createHeaderFn($easy); - $easy->handle = $this->handles ? \array_pop($this->handles) : \curl_init(); - curl_setopt_array($easy->handle, $conf); - - return $easy; - } - - public function release(EasyHandle $easy): void - { - $resource = $easy->handle; - unset($easy->handle); - - if (\count($this->handles) >= $this->maxHandles) { - \curl_close($resource); - } else { - // Remove all callback functions as they can hold onto references - // and are not cleaned up by curl_reset. Using curl_setopt_array - // does not work for some reason, so removing each one - // individually. - \curl_setopt($resource, \CURLOPT_HEADERFUNCTION, null); - \curl_setopt($resource, \CURLOPT_READFUNCTION, null); - \curl_setopt($resource, \CURLOPT_WRITEFUNCTION, null); - \curl_setopt($resource, \CURLOPT_PROGRESSFUNCTION, null); - \curl_reset($resource); - $this->handles[] = $resource; - } - } - - /** - * Completes a cURL transaction, either returning a response promise or a - * rejected promise. - * - * @param callable(RequestInterface, array): PromiseInterface $handler - * @param CurlFactoryInterface $factory Dictates how the handle is released - */ - public static function finish(callable $handler, EasyHandle $easy, CurlFactoryInterface $factory): PromiseInterface - { - if (isset($easy->options['on_stats'])) { - self::invokeStats($easy); - } - - if (!$easy->response || $easy->errno) { - return self::finishError($handler, $easy, $factory); - } - - // Return the response if it is present and there is no error. - $factory->release($easy); - - // Rewind the body of the response if possible. - $body = $easy->response->getBody(); - if ($body->isSeekable()) { - $body->rewind(); - } - - return new FulfilledPromise($easy->response); - } - - private static function invokeStats(EasyHandle $easy): void - { - $curlStats = \curl_getinfo($easy->handle); - $curlStats['appconnect_time'] = \curl_getinfo($easy->handle, \CURLINFO_APPCONNECT_TIME); - $stats = new TransferStats( - $easy->request, - $easy->response, - $curlStats['total_time'], - $easy->errno, - $curlStats - ); - ($easy->options['on_stats'])($stats); - } - - /** - * @param callable(RequestInterface, array): PromiseInterface $handler - */ - private static function finishError(callable $handler, EasyHandle $easy, CurlFactoryInterface $factory): PromiseInterface - { - // Get error information and release the handle to the factory. - $ctx = [ - 'errno' => $easy->errno, - 'error' => \curl_error($easy->handle), - 'appconnect_time' => \curl_getinfo($easy->handle, \CURLINFO_APPCONNECT_TIME), - ] + \curl_getinfo($easy->handle); - $ctx[self::CURL_VERSION_STR] = \curl_version()['version']; - $factory->release($easy); - - // Retry when nothing is present or when curl failed to rewind. - if (empty($easy->options['_err_message']) && (!$easy->errno || $easy->errno == 65)) { - return self::retryFailedRewind($handler, $easy, $ctx); - } - - return self::createRejection($easy, $ctx); - } - - private static function createRejection(EasyHandle $easy, array $ctx): PromiseInterface - { - static $connectionErrors = [ - \CURLE_OPERATION_TIMEOUTED => true, - \CURLE_COULDNT_RESOLVE_HOST => true, - \CURLE_COULDNT_CONNECT => true, - \CURLE_SSL_CONNECT_ERROR => true, - \CURLE_GOT_NOTHING => true, - ]; - - if ($easy->createResponseException) { - return P\Create::rejectionFor( - new RequestException( - 'An error was encountered while creating the response', - $easy->request, - $easy->response, - $easy->createResponseException, - $ctx - ) - ); - } - - // If an exception was encountered during the onHeaders event, then - // return a rejected promise that wraps that exception. - if ($easy->onHeadersException) { - return P\Create::rejectionFor( - new RequestException( - 'An error was encountered during the on_headers event', - $easy->request, - $easy->response, - $easy->onHeadersException, - $ctx - ) - ); - } - - $message = \sprintf( - 'cURL error %s: %s (%s)', - $ctx['errno'], - $ctx['error'], - 'see https://curl.haxx.se/libcurl/c/libcurl-errors.html' - ); - $uriString = (string) $easy->request->getUri(); - if ($uriString !== '' && false === \strpos($ctx['error'], $uriString)) { - $message .= \sprintf(' for %s', $uriString); - } - - // Create a connection exception if it was a specific error code. - $error = isset($connectionErrors[$easy->errno]) - ? new ConnectException($message, $easy->request, null, $ctx) - : new RequestException($message, $easy->request, $easy->response, null, $ctx); - - return P\Create::rejectionFor($error); - } - - /** - * @return array - */ - private function getDefaultConf(EasyHandle $easy): array - { - $conf = [ - '_headers' => $easy->request->getHeaders(), - \CURLOPT_CUSTOMREQUEST => $easy->request->getMethod(), - \CURLOPT_URL => (string) $easy->request->getUri()->withFragment(''), - \CURLOPT_RETURNTRANSFER => false, - \CURLOPT_HEADER => false, - \CURLOPT_CONNECTTIMEOUT => 150, - ]; - - if (\defined('CURLOPT_PROTOCOLS')) { - $conf[\CURLOPT_PROTOCOLS] = \CURLPROTO_HTTP | \CURLPROTO_HTTPS; - } - - $version = $easy->request->getProtocolVersion(); - if ($version == 1.1) { - $conf[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_1_1; - } elseif ($version == 2.0) { - $conf[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_2_0; - } else { - $conf[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_1_0; - } - - return $conf; - } - - private function applyMethod(EasyHandle $easy, array &$conf): void - { - $body = $easy->request->getBody(); - $size = $body->getSize(); - - if ($size === null || $size > 0) { - $this->applyBody($easy->request, $easy->options, $conf); - return; - } - - $method = $easy->request->getMethod(); - if ($method === 'PUT' || $method === 'POST') { - // See https://tools.ietf.org/html/rfc7230#section-3.3.2 - if (!$easy->request->hasHeader('Content-Length')) { - $conf[\CURLOPT_HTTPHEADER][] = 'Content-Length: 0'; - } - } elseif ($method === 'HEAD') { - $conf[\CURLOPT_NOBODY] = true; - unset( - $conf[\CURLOPT_WRITEFUNCTION], - $conf[\CURLOPT_READFUNCTION], - $conf[\CURLOPT_FILE], - $conf[\CURLOPT_INFILE] - ); - } - } - - private function applyBody(RequestInterface $request, array $options, array &$conf): void - { - $size = $request->hasHeader('Content-Length') - ? (int) $request->getHeaderLine('Content-Length') - : null; - - // Send the body as a string if the size is less than 1MB OR if the - // [curl][body_as_string] request value is set. - if (($size !== null && $size < 1000000) || !empty($options['_body_as_string'])) { - $conf[\CURLOPT_POSTFIELDS] = (string) $request->getBody(); - // Don't duplicate the Content-Length header - $this->removeHeader('Content-Length', $conf); - $this->removeHeader('Transfer-Encoding', $conf); - } else { - $conf[\CURLOPT_UPLOAD] = true; - if ($size !== null) { - $conf[\CURLOPT_INFILESIZE] = $size; - $this->removeHeader('Content-Length', $conf); - } - $body = $request->getBody(); - if ($body->isSeekable()) { - $body->rewind(); - } - $conf[\CURLOPT_READFUNCTION] = static function ($ch, $fd, $length) use ($body) { - return $body->read($length); - }; - } - - // If the Expect header is not present, prevent curl from adding it - if (!$request->hasHeader('Expect')) { - $conf[\CURLOPT_HTTPHEADER][] = 'Expect:'; - } - - // cURL sometimes adds a content-type by default. Prevent this. - if (!$request->hasHeader('Content-Type')) { - $conf[\CURLOPT_HTTPHEADER][] = 'Content-Type:'; - } - } - - private function applyHeaders(EasyHandle $easy, array &$conf): void - { - foreach ($conf['_headers'] as $name => $values) { - foreach ($values as $value) { - $value = (string) $value; - if ($value === '') { - // cURL requires a special format for empty headers. - // See https://github.com/guzzle/guzzle/issues/1882 for more details. - $conf[\CURLOPT_HTTPHEADER][] = "$name;"; - } else { - $conf[\CURLOPT_HTTPHEADER][] = "$name: $value"; - } - } - } - - // Remove the Accept header if one was not set - if (!$easy->request->hasHeader('Accept')) { - $conf[\CURLOPT_HTTPHEADER][] = 'Accept:'; - } - } - - /** - * Remove a header from the options array. - * - * @param string $name Case-insensitive header to remove - * @param array $options Array of options to modify - */ - private function removeHeader(string $name, array &$options): void - { - foreach (\array_keys($options['_headers']) as $key) { - if (!\strcasecmp($key, $name)) { - unset($options['_headers'][$key]); - return; - } - } - } - - private function applyHandlerOptions(EasyHandle $easy, array &$conf): void - { - $options = $easy->options; - if (isset($options['verify'])) { - if ($options['verify'] === false) { - unset($conf[\CURLOPT_CAINFO]); - $conf[\CURLOPT_SSL_VERIFYHOST] = 0; - $conf[\CURLOPT_SSL_VERIFYPEER] = false; - } else { - $conf[\CURLOPT_SSL_VERIFYHOST] = 2; - $conf[\CURLOPT_SSL_VERIFYPEER] = true; - if (\is_string($options['verify'])) { - // Throw an error if the file/folder/link path is not valid or doesn't exist. - if (!\file_exists($options['verify'])) { - throw new \InvalidArgumentException("SSL CA bundle not found: {$options['verify']}"); - } - // If it's a directory or a link to a directory use CURLOPT_CAPATH. - // If not, it's probably a file, or a link to a file, so use CURLOPT_CAINFO. - if ( - \is_dir($options['verify']) || - ( - \is_link($options['verify']) === true && - ($verifyLink = \readlink($options['verify'])) !== false && - \is_dir($verifyLink) - ) - ) { - $conf[\CURLOPT_CAPATH] = $options['verify']; - } else { - $conf[\CURLOPT_CAINFO] = $options['verify']; - } - } - } - } - - if (!isset($options['curl'][\CURLOPT_ENCODING]) && !empty($options['decode_content'])) { - $accept = $easy->request->getHeaderLine('Accept-Encoding'); - if ($accept) { - $conf[\CURLOPT_ENCODING] = $accept; - } else { - $conf[\CURLOPT_ENCODING] = ''; - // Don't let curl send the header over the wire - $conf[\CURLOPT_HTTPHEADER][] = 'Accept-Encoding:'; - } - } - - if (!isset($options['sink'])) { - // Use a default temp stream if no sink was set. - $options['sink'] = \GuzzleHttp\Psr7\Utils::tryFopen('php://temp', 'w+'); - } - $sink = $options['sink']; - if (!\is_string($sink)) { - $sink = \GuzzleHttp\Psr7\Utils::streamFor($sink); - } elseif (!\is_dir(\dirname($sink))) { - // Ensure that the directory exists before failing in curl. - throw new \RuntimeException(\sprintf('Directory %s does not exist for sink value of %s', \dirname($sink), $sink)); - } else { - $sink = new LazyOpenStream($sink, 'w+'); - } - $easy->sink = $sink; - $conf[\CURLOPT_WRITEFUNCTION] = static function ($ch, $write) use ($sink): int { - return $sink->write($write); - }; - - $timeoutRequiresNoSignal = false; - if (isset($options['timeout'])) { - $timeoutRequiresNoSignal |= $options['timeout'] < 1; - $conf[\CURLOPT_TIMEOUT_MS] = $options['timeout'] * 1000; - } - - // CURL default value is CURL_IPRESOLVE_WHATEVER - if (isset($options['force_ip_resolve'])) { - if ('v4' === $options['force_ip_resolve']) { - $conf[\CURLOPT_IPRESOLVE] = \CURL_IPRESOLVE_V4; - } elseif ('v6' === $options['force_ip_resolve']) { - $conf[\CURLOPT_IPRESOLVE] = \CURL_IPRESOLVE_V6; - } - } - - if (isset($options['connect_timeout'])) { - $timeoutRequiresNoSignal |= $options['connect_timeout'] < 1; - $conf[\CURLOPT_CONNECTTIMEOUT_MS] = $options['connect_timeout'] * 1000; - } - - if ($timeoutRequiresNoSignal && \strtoupper(\substr(\PHP_OS, 0, 3)) !== 'WIN') { - $conf[\CURLOPT_NOSIGNAL] = true; - } - - if (isset($options['proxy'])) { - if (!\is_array($options['proxy'])) { - $conf[\CURLOPT_PROXY] = $options['proxy']; - } else { - $scheme = $easy->request->getUri()->getScheme(); - if (isset($options['proxy'][$scheme])) { - $host = $easy->request->getUri()->getHost(); - if (!isset($options['proxy']['no']) || !Utils::isHostInNoProxy($host, $options['proxy']['no'])) { - $conf[\CURLOPT_PROXY] = $options['proxy'][$scheme]; - } - } - } - } - - if (isset($options['cert'])) { - $cert = $options['cert']; - if (\is_array($cert)) { - $conf[\CURLOPT_SSLCERTPASSWD] = $cert[1]; - $cert = $cert[0]; - } - if (!\file_exists($cert)) { - throw new \InvalidArgumentException("SSL certificate not found: {$cert}"); - } - # OpenSSL (versions 0.9.3 and later) also support "P12" for PKCS#12-encoded files. - # see https://curl.se/libcurl/c/CURLOPT_SSLCERTTYPE.html - $ext = pathinfo($cert, \PATHINFO_EXTENSION); - if (preg_match('#^(der|p12)$#i', $ext)) { - $conf[\CURLOPT_SSLCERTTYPE] = strtoupper($ext); - } - $conf[\CURLOPT_SSLCERT] = $cert; - } - - if (isset($options['ssl_key'])) { - if (\is_array($options['ssl_key'])) { - if (\count($options['ssl_key']) === 2) { - [$sslKey, $conf[\CURLOPT_SSLKEYPASSWD]] = $options['ssl_key']; - } else { - [$sslKey] = $options['ssl_key']; - } - } - - $sslKey = $sslKey ?? $options['ssl_key']; - - if (!\file_exists($sslKey)) { - throw new \InvalidArgumentException("SSL private key not found: {$sslKey}"); - } - $conf[\CURLOPT_SSLKEY] = $sslKey; - } - - if (isset($options['progress'])) { - $progress = $options['progress']; - if (!\is_callable($progress)) { - throw new \InvalidArgumentException('progress client option must be callable'); - } - $conf[\CURLOPT_NOPROGRESS] = false; - $conf[\CURLOPT_PROGRESSFUNCTION] = static function ($resource, int $downloadSize, int $downloaded, int $uploadSize, int $uploaded) use ($progress) { - $progress($downloadSize, $downloaded, $uploadSize, $uploaded); - }; - } - - if (!empty($options['debug'])) { - $conf[\CURLOPT_STDERR] = Utils::debugResource($options['debug']); - $conf[\CURLOPT_VERBOSE] = true; - } - } - - /** - * This function ensures that a response was set on a transaction. If one - * was not set, then the request is retried if possible. This error - * typically means you are sending a payload, curl encountered a - * "Connection died, retrying a fresh connect" error, tried to rewind the - * stream, and then encountered a "necessary data rewind wasn't possible" - * error, causing the request to be sent through curl_multi_info_read() - * without an error status. - * - * @param callable(RequestInterface, array): PromiseInterface $handler - */ - private static function retryFailedRewind(callable $handler, EasyHandle $easy, array $ctx): PromiseInterface - { - try { - // Only rewind if the body has been read from. - $body = $easy->request->getBody(); - if ($body->tell() > 0) { - $body->rewind(); - } - } catch (\RuntimeException $e) { - $ctx['error'] = 'The connection unexpectedly failed without ' - . 'providing an error. The request would have been retried, ' - . 'but attempting to rewind the request body failed. ' - . 'Exception: ' . $e; - return self::createRejection($easy, $ctx); - } - - // Retry no more than 3 times before giving up. - if (!isset($easy->options['_curl_retries'])) { - $easy->options['_curl_retries'] = 1; - } elseif ($easy->options['_curl_retries'] == 2) { - $ctx['error'] = 'The cURL request was retried 3 times ' - . 'and did not succeed. The most likely reason for the failure ' - . 'is that cURL was unable to rewind the body of the request ' - . 'and subsequent retries resulted in the same error. Turn on ' - . 'the debug option to see what went wrong. See ' - . 'https://bugs.php.net/bug.php?id=47204 for more information.'; - return self::createRejection($easy, $ctx); - } else { - $easy->options['_curl_retries']++; - } - - return $handler($easy->request, $easy->options); - } - - private function createHeaderFn(EasyHandle $easy): callable - { - if (isset($easy->options['on_headers'])) { - $onHeaders = $easy->options['on_headers']; - - if (!\is_callable($onHeaders)) { - throw new \InvalidArgumentException('on_headers must be callable'); - } - } else { - $onHeaders = null; - } - - return static function ($ch, $h) use ( - $onHeaders, - $easy, - &$startingResponse - ) { - $value = \trim($h); - if ($value === '') { - $startingResponse = true; - try { - $easy->createResponse(); - } catch (\Exception $e) { - $easy->createResponseException = $e; - return -1; - } - if ($onHeaders !== null) { - try { - $onHeaders($easy->response); - } catch (\Exception $e) { - // Associate the exception with the handle and trigger - // a curl header write error by returning 0. - $easy->onHeadersException = $e; - return -1; - } - } - } elseif ($startingResponse) { - $startingResponse = false; - $easy->headers = [$value]; - } else { - $easy->headers[] = $value; - } - return \strlen($h); - }; - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Handler/CurlFactoryInterface.php b/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Handler/CurlFactoryInterface.php deleted file mode 100644 index fe57ed5..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Handler/CurlFactoryInterface.php +++ /dev/null @@ -1,25 +0,0 @@ -factory = $options['handle_factory'] - ?? new CurlFactory(3); - } - - public function __invoke(RequestInterface $request, array $options): PromiseInterface - { - if (isset($options['delay'])) { - \usleep($options['delay'] * 1000); - } - - $easy = $this->factory->create($request, $options); - \curl_exec($easy->handle); - $easy->errno = \curl_errno($easy->handle); - - return CurlFactory::finish($this, $easy, $this->factory); - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php b/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php deleted file mode 100644 index 4e31263..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php +++ /dev/null @@ -1,253 +0,0 @@ - An array of delay times, indexed by handle id in `addRequest`. - * - * @see CurlMultiHandler::addRequest - */ - private $delays = []; - - /** - * @var array An associative array of CURLMOPT_* options and corresponding values for curl_multi_setopt() - */ - private $options = []; - - /** - * This handler accepts the following options: - * - * - handle_factory: An optional factory used to create curl handles - * - select_timeout: Optional timeout (in seconds) to block before timing - * out while selecting curl handles. Defaults to 1 second. - * - options: An associative array of CURLMOPT_* options and - * corresponding values for curl_multi_setopt() - */ - public function __construct(array $options = []) - { - $this->factory = $options['handle_factory'] ?? new CurlFactory(50); - - if (isset($options['select_timeout'])) { - $this->selectTimeout = $options['select_timeout']; - } elseif ($selectTimeout = Utils::getenv('GUZZLE_CURL_SELECT_TIMEOUT')) { - @trigger_error('Since guzzlehttp/guzzle 7.2.0: Using environment variable GUZZLE_CURL_SELECT_TIMEOUT is deprecated. Use option "select_timeout" instead.', \E_USER_DEPRECATED); - $this->selectTimeout = (int) $selectTimeout; - } else { - $this->selectTimeout = 1; - } - - $this->options = $options['options'] ?? []; - } - - /** - * @param string $name - * - * @return resource|\CurlMultiHandle - * - * @throws \BadMethodCallException when another field as `_mh` will be gotten - * @throws \RuntimeException when curl can not initialize a multi handle - */ - public function __get($name) - { - if ($name !== '_mh') { - throw new \BadMethodCallException("Can not get other property as '_mh'."); - } - - $multiHandle = \curl_multi_init(); - - if (false === $multiHandle) { - throw new \RuntimeException('Can not initialize curl multi handle.'); - } - - $this->_mh = $multiHandle; - - foreach ($this->options as $option => $value) { - // A warning is raised in case of a wrong option. - curl_multi_setopt($this->_mh, $option, $value); - } - - return $this->_mh; - } - - public function __destruct() - { - if (isset($this->_mh)) { - \curl_multi_close($this->_mh); - unset($this->_mh); - } - } - - public function __invoke(RequestInterface $request, array $options): PromiseInterface - { - $easy = $this->factory->create($request, $options); - $id = (int) $easy->handle; - - $promise = new Promise( - [$this, 'execute'], - function () use ($id) { - return $this->cancel($id); - } - ); - - $this->addRequest(['easy' => $easy, 'deferred' => $promise]); - - return $promise; - } - - /** - * Ticks the curl event loop. - */ - public function tick(): void - { - // Add any delayed handles if needed. - if ($this->delays) { - $currentTime = Utils::currentTime(); - foreach ($this->delays as $id => $delay) { - if ($currentTime >= $delay) { - unset($this->delays[$id]); - \curl_multi_add_handle( - $this->_mh, - $this->handles[$id]['easy']->handle - ); - } - } - } - - // Step through the task queue which may add additional requests. - P\Utils::queue()->run(); - - if ($this->active && \curl_multi_select($this->_mh, $this->selectTimeout) === -1) { - // Perform a usleep if a select returns -1. - // See: https://bugs.php.net/bug.php?id=61141 - \usleep(250); - } - - while (\curl_multi_exec($this->_mh, $this->active) === \CURLM_CALL_MULTI_PERFORM); - - $this->processMessages(); - } - - /** - * Runs until all outstanding connections have completed. - */ - public function execute(): void - { - $queue = P\Utils::queue(); - - while ($this->handles || !$queue->isEmpty()) { - // If there are no transfers, then sleep for the next delay - if (!$this->active && $this->delays) { - \usleep($this->timeToNext()); - } - $this->tick(); - } - } - - private function addRequest(array $entry): void - { - $easy = $entry['easy']; - $id = (int) $easy->handle; - $this->handles[$id] = $entry; - if (empty($easy->options['delay'])) { - \curl_multi_add_handle($this->_mh, $easy->handle); - } else { - $this->delays[$id] = Utils::currentTime() + ($easy->options['delay'] / 1000); - } - } - - /** - * Cancels a handle from sending and removes references to it. - * - * @param int $id Handle ID to cancel and remove. - * - * @return bool True on success, false on failure. - */ - private function cancel($id): bool - { - // Cannot cancel if it has been processed. - if (!isset($this->handles[$id])) { - return false; - } - - $handle = $this->handles[$id]['easy']->handle; - unset($this->delays[$id], $this->handles[$id]); - \curl_multi_remove_handle($this->_mh, $handle); - \curl_close($handle); - - return true; - } - - private function processMessages(): void - { - while ($done = \curl_multi_info_read($this->_mh)) { - $id = (int) $done['handle']; - \curl_multi_remove_handle($this->_mh, $done['handle']); - - if (!isset($this->handles[$id])) { - // Probably was cancelled. - continue; - } - - $entry = $this->handles[$id]; - unset($this->handles[$id], $this->delays[$id]); - $entry['easy']->errno = $done['result']; - $entry['deferred']->resolve( - CurlFactory::finish($this, $entry['easy'], $this->factory) - ); - } - } - - private function timeToNext(): int - { - $currentTime = Utils::currentTime(); - $nextTime = \PHP_INT_MAX; - foreach ($this->delays as $time) { - if ($time < $nextTime) { - $nextTime = $time; - } - } - - return ((int) \max(0, $nextTime - $currentTime)) * 1000000; - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Handler/EasyHandle.php b/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Handler/EasyHandle.php deleted file mode 100644 index 224344d..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Handler/EasyHandle.php +++ /dev/null @@ -1,112 +0,0 @@ -headers); - - $normalizedKeys = Utils::normalizeHeaderKeys($headers); - - if (!empty($this->options['decode_content']) && isset($normalizedKeys['content-encoding'])) { - $headers['x-encoded-content-encoding'] = $headers[$normalizedKeys['content-encoding']]; - unset($headers[$normalizedKeys['content-encoding']]); - if (isset($normalizedKeys['content-length'])) { - $headers['x-encoded-content-length'] = $headers[$normalizedKeys['content-length']]; - - $bodyLength = (int) $this->sink->getSize(); - if ($bodyLength) { - $headers[$normalizedKeys['content-length']] = $bodyLength; - } else { - unset($headers[$normalizedKeys['content-length']]); - } - } - } - - // Attach a response to the easy handle with the parsed headers. - $this->response = new Response( - $status, - $headers, - $this->sink, - $ver, - $reason - ); - } - - /** - * @param string $name - * - * @return void - * - * @throws \BadMethodCallException - */ - public function __get($name) - { - $msg = $name === 'handle' ? 'The EasyHandle has been released' : 'Invalid property: ' . $name; - throw new \BadMethodCallException($msg); - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Handler/HeaderProcessor.php b/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Handler/HeaderProcessor.php deleted file mode 100644 index a098884..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Handler/HeaderProcessor.php +++ /dev/null @@ -1,42 +0,0 @@ -|null $queue The parameters to be passed to the append function, as an indexed array. - * @param callable|null $onFulfilled Callback to invoke when the return value is fulfilled. - * @param callable|null $onRejected Callback to invoke when the return value is rejected. - */ - public function __construct(array $queue = null, callable $onFulfilled = null, callable $onRejected = null) - { - $this->onFulfilled = $onFulfilled; - $this->onRejected = $onRejected; - - if ($queue) { - // array_values included for BC - $this->append(...array_values($queue)); - } - } - - public function __invoke(RequestInterface $request, array $options): PromiseInterface - { - if (!$this->queue) { - throw new \OutOfBoundsException('Mock queue is empty'); - } - - if (isset($options['delay']) && \is_numeric($options['delay'])) { - \usleep((int) $options['delay'] * 1000); - } - - $this->lastRequest = $request; - $this->lastOptions = $options; - $response = \array_shift($this->queue); - - if (isset($options['on_headers'])) { - if (!\is_callable($options['on_headers'])) { - throw new \InvalidArgumentException('on_headers must be callable'); - } - try { - $options['on_headers']($response); - } catch (\Exception $e) { - $msg = 'An error was encountered during the on_headers event'; - $response = new RequestException($msg, $request, $response, $e); - } - } - - if (\is_callable($response)) { - $response = $response($request, $options); - } - - $response = $response instanceof \Throwable - ? P\Create::rejectionFor($response) - : P\Create::promiseFor($response); - - return $response->then( - function (?ResponseInterface $value) use ($request, $options) { - $this->invokeStats($request, $options, $value); - if ($this->onFulfilled) { - ($this->onFulfilled)($value); - } - - if ($value !== null && isset($options['sink'])) { - $contents = (string) $value->getBody(); - $sink = $options['sink']; - - if (\is_resource($sink)) { - \fwrite($sink, $contents); - } elseif (\is_string($sink)) { - \file_put_contents($sink, $contents); - } elseif ($sink instanceof StreamInterface) { - $sink->write($contents); - } - } - - return $value; - }, - function ($reason) use ($request, $options) { - $this->invokeStats($request, $options, null, $reason); - if ($this->onRejected) { - ($this->onRejected)($reason); - } - return P\Create::rejectionFor($reason); - } - ); - } - - /** - * Adds one or more variadic requests, exceptions, callables, or promises - * to the queue. - * - * @param mixed ...$values - */ - public function append(...$values): void - { - foreach ($values as $value) { - if ($value instanceof ResponseInterface - || $value instanceof \Throwable - || $value instanceof PromiseInterface - || \is_callable($value) - ) { - $this->queue[] = $value; - } else { - throw new \TypeError('Expected a Response, Promise, Throwable or callable. Found ' . Utils::describeType($value)); - } - } - } - - /** - * Get the last received request. - */ - public function getLastRequest(): ?RequestInterface - { - return $this->lastRequest; - } - - /** - * Get the last received request options. - */ - public function getLastOptions(): array - { - return $this->lastOptions; - } - - /** - * Returns the number of remaining items in the queue. - */ - public function count(): int - { - return \count($this->queue); - } - - public function reset(): void - { - $this->queue = []; - } - - /** - * @param mixed $reason Promise or reason. - */ - private function invokeStats( - RequestInterface $request, - array $options, - ResponseInterface $response = null, - $reason = null - ): void { - if (isset($options['on_stats'])) { - $transferTime = $options['transfer_time'] ?? 0; - $stats = new TransferStats($request, $response, $transferTime, $reason); - ($options['on_stats'])($stats); - } - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Handler/Proxy.php b/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Handler/Proxy.php deleted file mode 100644 index f045b52..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Handler/Proxy.php +++ /dev/null @@ -1,51 +0,0 @@ -withoutHeader('Expect'); - - // Append a content-length header if body size is zero to match - // cURL's behavior. - if (0 === $request->getBody()->getSize()) { - $request = $request->withHeader('Content-Length', '0'); - } - - return $this->createResponse( - $request, - $options, - $this->createStream($request, $options), - $startTime - ); - } catch (\InvalidArgumentException $e) { - throw $e; - } catch (\Exception $e) { - // Determine if the error was a networking error. - $message = $e->getMessage(); - // This list can probably get more comprehensive. - if (false !== \strpos($message, 'getaddrinfo') // DNS lookup failed - || false !== \strpos($message, 'Connection refused') - || false !== \strpos($message, "couldn't connect to host") // error on HHVM - || false !== \strpos($message, "connection attempt failed") - ) { - $e = new ConnectException($e->getMessage(), $request, $e); - } else { - $e = RequestException::wrapException($request, $e); - } - $this->invokeStats($options, $request, $startTime, null, $e); - - return P\Create::rejectionFor($e); - } - } - - private function invokeStats( - array $options, - RequestInterface $request, - ?float $startTime, - ResponseInterface $response = null, - \Throwable $error = null - ): void { - if (isset($options['on_stats'])) { - $stats = new TransferStats($request, $response, Utils::currentTime() - $startTime, $error, []); - ($options['on_stats'])($stats); - } - } - - /** - * @param resource $stream - */ - private function createResponse(RequestInterface $request, array $options, $stream, ?float $startTime): PromiseInterface - { - $hdrs = $this->lastHeaders; - $this->lastHeaders = []; - - try { - [$ver, $status, $reason, $headers] = HeaderProcessor::parseHeaders($hdrs); - } catch (\Exception $e) { - return P\Create::rejectionFor( - new RequestException('An error was encountered while creating the response', $request, null, $e) - ); - } - - [$stream, $headers] = $this->checkDecode($options, $headers, $stream); - $stream = Psr7\Utils::streamFor($stream); - $sink = $stream; - - if (\strcasecmp('HEAD', $request->getMethod())) { - $sink = $this->createSink($stream, $options); - } - - try { - $response = new Psr7\Response($status, $headers, $sink, $ver, $reason); - } catch (\Exception $e) { - return P\Create::rejectionFor( - new RequestException('An error was encountered while creating the response', $request, null, $e) - ); - } - - if (isset($options['on_headers'])) { - try { - $options['on_headers']($response); - } catch (\Exception $e) { - return P\Create::rejectionFor( - new RequestException('An error was encountered during the on_headers event', $request, $response, $e) - ); - } - } - - // Do not drain when the request is a HEAD request because they have - // no body. - if ($sink !== $stream) { - $this->drain($stream, $sink, $response->getHeaderLine('Content-Length')); - } - - $this->invokeStats($options, $request, $startTime, $response, null); - - return new FulfilledPromise($response); - } - - private function createSink(StreamInterface $stream, array $options): StreamInterface - { - if (!empty($options['stream'])) { - return $stream; - } - - $sink = $options['sink'] ?? Psr7\Utils::tryFopen('php://temp', 'r+'); - - return \is_string($sink) ? new Psr7\LazyOpenStream($sink, 'w+') : Psr7\Utils::streamFor($sink); - } - - /** - * @param resource $stream - */ - private function checkDecode(array $options, array $headers, $stream): array - { - // Automatically decode responses when instructed. - if (!empty($options['decode_content'])) { - $normalizedKeys = Utils::normalizeHeaderKeys($headers); - if (isset($normalizedKeys['content-encoding'])) { - $encoding = $headers[$normalizedKeys['content-encoding']]; - if ($encoding[0] === 'gzip' || $encoding[0] === 'deflate') { - $stream = new Psr7\InflateStream(Psr7\Utils::streamFor($stream)); - $headers['x-encoded-content-encoding'] = $headers[$normalizedKeys['content-encoding']]; - - // Remove content-encoding header - unset($headers[$normalizedKeys['content-encoding']]); - - // Fix content-length header - if (isset($normalizedKeys['content-length'])) { - $headers['x-encoded-content-length'] = $headers[$normalizedKeys['content-length']]; - $length = (int) $stream->getSize(); - if ($length === 0) { - unset($headers[$normalizedKeys['content-length']]); - } else { - $headers[$normalizedKeys['content-length']] = [$length]; - } - } - } - } - } - - return [$stream, $headers]; - } - - /** - * Drains the source stream into the "sink" client option. - * - * @param string $contentLength Header specifying the amount of - * data to read. - * - * @throws \RuntimeException when the sink option is invalid. - */ - private function drain(StreamInterface $source, StreamInterface $sink, string $contentLength): StreamInterface - { - // If a content-length header is provided, then stop reading once - // that number of bytes has been read. This can prevent infinitely - // reading from a stream when dealing with servers that do not honor - // Connection: Close headers. - Psr7\Utils::copyToStream( - $source, - $sink, - (\strlen($contentLength) > 0 && (int) $contentLength > 0) ? (int) $contentLength : -1 - ); - - $sink->seek(0); - $source->close(); - - return $sink; - } - - /** - * Create a resource and check to ensure it was created successfully - * - * @param callable $callback Callable that returns stream resource - * - * @return resource - * - * @throws \RuntimeException on error - */ - private function createResource(callable $callback) - { - $errors = []; - \set_error_handler(static function ($_, $msg, $file, $line) use (&$errors): bool { - $errors[] = [ - 'message' => $msg, - 'file' => $file, - 'line' => $line - ]; - return true; - }); - - $resource = $callback(); - \restore_error_handler(); - - if (!$resource) { - $message = 'Error creating resource: '; - foreach ($errors as $err) { - foreach ($err as $key => $value) { - $message .= "[$key] $value" . \PHP_EOL; - } - } - throw new \RuntimeException(\trim($message)); - } - - return $resource; - } - - /** - * @return resource - */ - private function createStream(RequestInterface $request, array $options) - { - static $methods; - if (!$methods) { - $methods = \array_flip(\get_class_methods(__CLASS__)); - } - - // HTTP/1.1 streams using the PHP stream wrapper require a - // Connection: close header - if ($request->getProtocolVersion() == '1.1' - && !$request->hasHeader('Connection') - ) { - $request = $request->withHeader('Connection', 'close'); - } - - // Ensure SSL is verified by default - if (!isset($options['verify'])) { - $options['verify'] = true; - } - - $params = []; - $context = $this->getDefaultContext($request); - - if (isset($options['on_headers']) && !\is_callable($options['on_headers'])) { - throw new \InvalidArgumentException('on_headers must be callable'); - } - - if (!empty($options)) { - foreach ($options as $key => $value) { - $method = "add_{$key}"; - if (isset($methods[$method])) { - $this->{$method}($request, $context, $value, $params); - } - } - } - - if (isset($options['stream_context'])) { - if (!\is_array($options['stream_context'])) { - throw new \InvalidArgumentException('stream_context must be an array'); - } - $context = \array_replace_recursive($context, $options['stream_context']); - } - - // Microsoft NTLM authentication only supported with curl handler - if (isset($options['auth'][2]) && 'ntlm' === $options['auth'][2]) { - throw new \InvalidArgumentException('Microsoft NTLM authentication only supported with curl handler'); - } - - $uri = $this->resolveHost($request, $options); - - $contextResource = $this->createResource( - static function () use ($context, $params) { - return \stream_context_create($context, $params); - } - ); - - return $this->createResource( - function () use ($uri, &$http_response_header, $contextResource, $context, $options, $request) { - $resource = @\fopen((string) $uri, 'r', false, $contextResource); - $this->lastHeaders = $http_response_header; - - if (false === $resource) { - throw new ConnectException(sprintf('Connection refused for URI %s', $uri), $request, null, $context); - } - - if (isset($options['read_timeout'])) { - $readTimeout = $options['read_timeout']; - $sec = (int) $readTimeout; - $usec = ($readTimeout - $sec) * 100000; - \stream_set_timeout($resource, $sec, $usec); - } - - return $resource; - } - ); - } - - private function resolveHost(RequestInterface $request, array $options): UriInterface - { - $uri = $request->getUri(); - - if (isset($options['force_ip_resolve']) && !\filter_var($uri->getHost(), \FILTER_VALIDATE_IP)) { - if ('v4' === $options['force_ip_resolve']) { - $records = \dns_get_record($uri->getHost(), \DNS_A); - if (false === $records || !isset($records[0]['ip'])) { - throw new ConnectException(\sprintf("Could not resolve IPv4 address for host '%s'", $uri->getHost()), $request); - } - return $uri->withHost($records[0]['ip']); - } - if ('v6' === $options['force_ip_resolve']) { - $records = \dns_get_record($uri->getHost(), \DNS_AAAA); - if (false === $records || !isset($records[0]['ipv6'])) { - throw new ConnectException(\sprintf("Could not resolve IPv6 address for host '%s'", $uri->getHost()), $request); - } - return $uri->withHost('[' . $records[0]['ipv6'] . ']'); - } - } - - return $uri; - } - - private function getDefaultContext(RequestInterface $request): array - { - $headers = ''; - foreach ($request->getHeaders() as $name => $value) { - foreach ($value as $val) { - $headers .= "$name: $val\r\n"; - } - } - - $context = [ - 'http' => [ - 'method' => $request->getMethod(), - 'header' => $headers, - 'protocol_version' => $request->getProtocolVersion(), - 'ignore_errors' => true, - 'follow_location' => 0, - ], - ]; - - $body = (string) $request->getBody(); - - if (!empty($body)) { - $context['http']['content'] = $body; - // Prevent the HTTP handler from adding a Content-Type header. - if (!$request->hasHeader('Content-Type')) { - $context['http']['header'] .= "Content-Type:\r\n"; - } - } - - $context['http']['header'] = \rtrim($context['http']['header']); - - return $context; - } - - /** - * @param mixed $value as passed via Request transfer options. - */ - private function add_proxy(RequestInterface $request, array &$options, $value, array &$params): void - { - $uri = null; - - if (!\is_array($value)) { - $uri = $value; - } else { - $scheme = $request->getUri()->getScheme(); - if (isset($value[$scheme])) { - if (!isset($value['no']) || !Utils::isHostInNoProxy($request->getUri()->getHost(), $value['no'])) { - $uri = $value[$scheme]; - } - } - } - - if (!$uri) { - return; - } - - $parsed = $this->parse_proxy($uri); - $options['http']['proxy'] = $parsed['proxy']; - - if ($parsed['auth']) { - if (!isset($options['http']['header'])) { - $options['http']['header'] = []; - } - $options['http']['header'] .= "\r\nProxy-Authorization: {$parsed['auth']}"; - } - } - - /** - * Parses the given proxy URL to make it compatible with the format PHP's stream context expects. - */ - private function parse_proxy(string $url): array - { - $parsed = \parse_url($url); - - if ($parsed !== false && isset($parsed['scheme']) && $parsed['scheme'] === 'http') { - if (isset($parsed['host']) && isset($parsed['port'])) { - $auth = null; - if (isset($parsed['user']) && isset($parsed['pass'])) { - $auth = \base64_encode("{$parsed['user']}:{$parsed['pass']}"); - } - - return [ - 'proxy' => "tcp://{$parsed['host']}:{$parsed['port']}", - 'auth' => $auth ? "Basic {$auth}" : null, - ]; - } - } - - // Return proxy as-is. - return [ - 'proxy' => $url, - 'auth' => null, - ]; - } - - /** - * @param mixed $value as passed via Request transfer options. - */ - private function add_timeout(RequestInterface $request, array &$options, $value, array &$params): void - { - if ($value > 0) { - $options['http']['timeout'] = $value; - } - } - - /** - * @param mixed $value as passed via Request transfer options. - */ - private function add_verify(RequestInterface $request, array &$options, $value, array &$params): void - { - if ($value === false) { - $options['ssl']['verify_peer'] = false; - $options['ssl']['verify_peer_name'] = false; - - return; - } - - if (\is_string($value)) { - $options['ssl']['cafile'] = $value; - if (!\file_exists($value)) { - throw new \RuntimeException("SSL CA bundle not found: $value"); - } - } elseif ($value !== true) { - throw new \InvalidArgumentException('Invalid verify request option'); - } - - $options['ssl']['verify_peer'] = true; - $options['ssl']['verify_peer_name'] = true; - $options['ssl']['allow_self_signed'] = false; - } - - /** - * @param mixed $value as passed via Request transfer options. - */ - private function add_cert(RequestInterface $request, array &$options, $value, array &$params): void - { - if (\is_array($value)) { - $options['ssl']['passphrase'] = $value[1]; - $value = $value[0]; - } - - if (!\file_exists($value)) { - throw new \RuntimeException("SSL certificate not found: {$value}"); - } - - $options['ssl']['local_cert'] = $value; - } - - /** - * @param mixed $value as passed via Request transfer options. - */ - private function add_progress(RequestInterface $request, array &$options, $value, array &$params): void - { - self::addNotification( - $params, - static function ($code, $a, $b, $c, $transferred, $total) use ($value) { - if ($code == \STREAM_NOTIFY_PROGRESS) { - $value($total, $transferred, null, null); - } - } - ); - } - - /** - * @param mixed $value as passed via Request transfer options. - */ - private function add_debug(RequestInterface $request, array &$options, $value, array &$params): void - { - if ($value === false) { - return; - } - - static $map = [ - \STREAM_NOTIFY_CONNECT => 'CONNECT', - \STREAM_NOTIFY_AUTH_REQUIRED => 'AUTH_REQUIRED', - \STREAM_NOTIFY_AUTH_RESULT => 'AUTH_RESULT', - \STREAM_NOTIFY_MIME_TYPE_IS => 'MIME_TYPE_IS', - \STREAM_NOTIFY_FILE_SIZE_IS => 'FILE_SIZE_IS', - \STREAM_NOTIFY_REDIRECTED => 'REDIRECTED', - \STREAM_NOTIFY_PROGRESS => 'PROGRESS', - \STREAM_NOTIFY_FAILURE => 'FAILURE', - \STREAM_NOTIFY_COMPLETED => 'COMPLETED', - \STREAM_NOTIFY_RESOLVE => 'RESOLVE', - ]; - static $args = ['severity', 'message', 'message_code', 'bytes_transferred', 'bytes_max']; - - $value = Utils::debugResource($value); - $ident = $request->getMethod() . ' ' . $request->getUri()->withFragment(''); - self::addNotification( - $params, - static function (int $code, ...$passed) use ($ident, $value, $map, $args): void { - \fprintf($value, '<%s> [%s] ', $ident, $map[$code]); - foreach (\array_filter($passed) as $i => $v) { - \fwrite($value, $args[$i] . ': "' . $v . '" '); - } - \fwrite($value, "\n"); - } - ); - } - - private static function addNotification(array &$params, callable $notify): void - { - // Wrap the existing function if needed. - if (!isset($params['notification'])) { - $params['notification'] = $notify; - } else { - $params['notification'] = self::callArray([ - $params['notification'], - $notify - ]); - } - } - - private static function callArray(array $functions): callable - { - return static function (...$args) use ($functions) { - foreach ($functions as $fn) { - $fn(...$args); - } - }; - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/HandlerStack.php b/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/HandlerStack.php deleted file mode 100644 index b67239e..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/HandlerStack.php +++ /dev/null @@ -1,271 +0,0 @@ -push(Middleware::httpErrors(), 'http_errors'); - $stack->push(Middleware::redirect(), 'allow_redirects'); - $stack->push(Middleware::cookies(), 'cookies'); - $stack->push(Middleware::prepareBody(), 'prepare_body'); - - return $stack; - } - - /** - * @param null|callable(RequestInterface, array): PromiseInterface $handler Underlying HTTP handler. - */ - public function __construct(callable $handler = null) - { - $this->handler = $handler; - } - - /** - * Invokes the handler stack as a composed handler - * - * @return ResponseInterface|PromiseInterface - */ - public function __invoke(RequestInterface $request, array $options) - { - $handler = $this->resolve(); - - return $handler($request, $options); - } - - /** - * Dumps a string representation of the stack. - * - * @return string - */ - public function __toString() - { - $depth = 0; - $stack = []; - - if ($this->handler !== null) { - $stack[] = "0) Handler: " . $this->debugCallable($this->handler); - } - - $result = ''; - foreach (\array_reverse($this->stack) as $tuple) { - $depth++; - $str = "{$depth}) Name: '{$tuple[1]}', "; - $str .= "Function: " . $this->debugCallable($tuple[0]); - $result = "> {$str}\n{$result}"; - $stack[] = $str; - } - - foreach (\array_keys($stack) as $k) { - $result .= "< {$stack[$k]}\n"; - } - - return $result; - } - - /** - * Set the HTTP handler that actually returns a promise. - * - * @param callable(RequestInterface, array): PromiseInterface $handler Accepts a request and array of options and - * returns a Promise. - */ - public function setHandler(callable $handler): void - { - $this->handler = $handler; - $this->cached = null; - } - - /** - * Returns true if the builder has a handler. - */ - public function hasHandler(): bool - { - return $this->handler !== null ; - } - - /** - * Unshift a middleware to the bottom of the stack. - * - * @param callable(callable): callable $middleware Middleware function - * @param string $name Name to register for this middleware. - */ - public function unshift(callable $middleware, ?string $name = null): void - { - \array_unshift($this->stack, [$middleware, $name]); - $this->cached = null; - } - - /** - * Push a middleware to the top of the stack. - * - * @param callable(callable): callable $middleware Middleware function - * @param string $name Name to register for this middleware. - */ - public function push(callable $middleware, string $name = ''): void - { - $this->stack[] = [$middleware, $name]; - $this->cached = null; - } - - /** - * Add a middleware before another middleware by name. - * - * @param string $findName Middleware to find - * @param callable(callable): callable $middleware Middleware function - * @param string $withName Name to register for this middleware. - */ - public function before(string $findName, callable $middleware, string $withName = ''): void - { - $this->splice($findName, $withName, $middleware, true); - } - - /** - * Add a middleware after another middleware by name. - * - * @param string $findName Middleware to find - * @param callable(callable): callable $middleware Middleware function - * @param string $withName Name to register for this middleware. - */ - public function after(string $findName, callable $middleware, string $withName = ''): void - { - $this->splice($findName, $withName, $middleware, false); - } - - /** - * Remove a middleware by instance or name from the stack. - * - * @param callable|string $remove Middleware to remove by instance or name. - */ - public function remove($remove): void - { - $this->cached = null; - $idx = \is_callable($remove) ? 0 : 1; - $this->stack = \array_values(\array_filter( - $this->stack, - static function ($tuple) use ($idx, $remove) { - return $tuple[$idx] !== $remove; - } - )); - } - - /** - * Compose the middleware and handler into a single callable function. - * - * @return callable(RequestInterface, array): PromiseInterface - */ - public function resolve(): callable - { - if ($this->cached === null) { - if (($prev = $this->handler) === null) { - throw new \LogicException('No handler has been specified'); - } - - foreach (\array_reverse($this->stack) as $fn) { - /** @var callable(RequestInterface, array): PromiseInterface $prev */ - $prev = $fn[0]($prev); - } - - $this->cached = $prev; - } - - return $this->cached; - } - - private function findByName(string $name): int - { - foreach ($this->stack as $k => $v) { - if ($v[1] === $name) { - return $k; - } - } - - throw new \InvalidArgumentException("Middleware not found: $name"); - } - - /** - * Splices a function into the middleware list at a specific position. - */ - private function splice(string $findName, string $withName, callable $middleware, bool $before): void - { - $this->cached = null; - $idx = $this->findByName($findName); - $tuple = [$middleware, $withName]; - - if ($before) { - if ($idx === 0) { - \array_unshift($this->stack, $tuple); - } else { - $replacement = [$tuple, $this->stack[$idx]]; - \array_splice($this->stack, $idx, 1, $replacement); - } - } elseif ($idx === \count($this->stack) - 1) { - $this->stack[] = $tuple; - } else { - $replacement = [$this->stack[$idx], $tuple]; - \array_splice($this->stack, $idx, 1, $replacement); - } - } - - /** - * Provides a debug string for a given callable. - * - * @param callable $fn Function to write as a string. - */ - private function debugCallable($fn): string - { - if (\is_string($fn)) { - return "callable({$fn})"; - } - - if (\is_array($fn)) { - return \is_string($fn[0]) - ? "callable({$fn[0]}::{$fn[1]})" - : "callable(['" . \get_class($fn[0]) . "', '{$fn[1]}'])"; - } - - /** @var object $fn */ - return 'callable(' . \spl_object_hash($fn) . ')'; - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/MessageFormatter.php b/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/MessageFormatter.php deleted file mode 100644 index 238770f..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/MessageFormatter.php +++ /dev/null @@ -1,198 +0,0 @@ ->>>>>>>\n{request}\n<<<<<<<<\n{response}\n--------\n{error}"; - public const SHORT = '[{ts}] "{method} {target} HTTP/{version}" {code}'; - - /** - * @var string Template used to format log messages - */ - private $template; - - /** - * @param string $template Log message template - */ - public function __construct(?string $template = self::CLF) - { - $this->template = $template ?: self::CLF; - } - - /** - * Returns a formatted message string. - * - * @param RequestInterface $request Request that was sent - * @param ResponseInterface|null $response Response that was received - * @param \Throwable|null $error Exception that was received - */ - public function format(RequestInterface $request, ?ResponseInterface $response = null, ?\Throwable $error = null): string - { - $cache = []; - - /** @var string */ - return \preg_replace_callback( - '/{\s*([A-Za-z_\-\.0-9]+)\s*}/', - function (array $matches) use ($request, $response, $error, &$cache) { - if (isset($cache[$matches[1]])) { - return $cache[$matches[1]]; - } - - $result = ''; - switch ($matches[1]) { - case 'request': - $result = Psr7\Message::toString($request); - break; - case 'response': - $result = $response ? Psr7\Message::toString($response) : ''; - break; - case 'req_headers': - $result = \trim($request->getMethod() - . ' ' . $request->getRequestTarget()) - . ' HTTP/' . $request->getProtocolVersion() . "\r\n" - . $this->headers($request); - break; - case 'res_headers': - $result = $response ? - \sprintf( - 'HTTP/%s %d %s', - $response->getProtocolVersion(), - $response->getStatusCode(), - $response->getReasonPhrase() - ) . "\r\n" . $this->headers($response) - : 'NULL'; - break; - case 'req_body': - $result = $request->getBody()->__toString(); - break; - case 'res_body': - if (!$response instanceof ResponseInterface) { - $result = 'NULL'; - break; - } - - $body = $response->getBody(); - - if (!$body->isSeekable()) { - $result = 'RESPONSE_NOT_LOGGEABLE'; - break; - } - - $result = $response->getBody()->__toString(); - break; - case 'ts': - case 'date_iso_8601': - $result = \gmdate('c'); - break; - case 'date_common_log': - $result = \date('d/M/Y:H:i:s O'); - break; - case 'method': - $result = $request->getMethod(); - break; - case 'version': - $result = $request->getProtocolVersion(); - break; - case 'uri': - case 'url': - $result = $request->getUri(); - break; - case 'target': - $result = $request->getRequestTarget(); - break; - case 'req_version': - $result = $request->getProtocolVersion(); - break; - case 'res_version': - $result = $response - ? $response->getProtocolVersion() - : 'NULL'; - break; - case 'host': - $result = $request->getHeaderLine('Host'); - break; - case 'hostname': - $result = \gethostname(); - break; - case 'code': - $result = $response ? $response->getStatusCode() : 'NULL'; - break; - case 'phrase': - $result = $response ? $response->getReasonPhrase() : 'NULL'; - break; - case 'error': - $result = $error ? $error->getMessage() : 'NULL'; - break; - default: - // handle prefixed dynamic headers - if (\strpos($matches[1], 'req_header_') === 0) { - $result = $request->getHeaderLine(\substr($matches[1], 11)); - } elseif (\strpos($matches[1], 'res_header_') === 0) { - $result = $response - ? $response->getHeaderLine(\substr($matches[1], 11)) - : 'NULL'; - } - } - - $cache[$matches[1]] = $result; - return $result; - }, - $this->template - ); - } - - /** - * Get headers from message as string - */ - private function headers(MessageInterface $message): string - { - $result = ''; - foreach ($message->getHeaders() as $name => $values) { - $result .= $name . ': ' . \implode(', ', $values) . "\r\n"; - } - - return \trim($result); - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/MessageFormatterInterface.php b/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/MessageFormatterInterface.php deleted file mode 100644 index a39ac24..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/MessageFormatterInterface.php +++ /dev/null @@ -1,18 +0,0 @@ -withCookieHeader($request); - return $handler($request, $options) - ->then( - static function (ResponseInterface $response) use ($cookieJar, $request): ResponseInterface { - $cookieJar->extractCookies($request, $response); - return $response; - } - ); - }; - }; - } - - /** - * Middleware that throws exceptions for 4xx or 5xx responses when the - * "http_errors" request option is set to true. - * - * @param BodySummarizerInterface|null $bodySummarizer The body summarizer to use in exception messages. - * - * @return callable(callable): callable Returns a function that accepts the next handler. - */ - public static function httpErrors(BodySummarizerInterface $bodySummarizer = null): callable - { - return static function (callable $handler) use ($bodySummarizer): callable { - return static function ($request, array $options) use ($handler, $bodySummarizer) { - if (empty($options['http_errors'])) { - return $handler($request, $options); - } - return $handler($request, $options)->then( - static function (ResponseInterface $response) use ($request, $bodySummarizer) { - $code = $response->getStatusCode(); - if ($code < 400) { - return $response; - } - throw RequestException::create($request, $response, null, [], $bodySummarizer); - } - ); - }; - }; - } - - /** - * Middleware that pushes history data to an ArrayAccess container. - * - * @param array|\ArrayAccess $container Container to hold the history (by reference). - * - * @return callable(callable): callable Returns a function that accepts the next handler. - * - * @throws \InvalidArgumentException if container is not an array or ArrayAccess. - */ - public static function history(&$container): callable - { - if (!\is_array($container) && !$container instanceof \ArrayAccess) { - throw new \InvalidArgumentException('history container must be an array or object implementing ArrayAccess'); - } - - return static function (callable $handler) use (&$container): callable { - return static function (RequestInterface $request, array $options) use ($handler, &$container) { - return $handler($request, $options)->then( - static function ($value) use ($request, &$container, $options) { - $container[] = [ - 'request' => $request, - 'response' => $value, - 'error' => null, - 'options' => $options - ]; - return $value; - }, - static function ($reason) use ($request, &$container, $options) { - $container[] = [ - 'request' => $request, - 'response' => null, - 'error' => $reason, - 'options' => $options - ]; - return P\Create::rejectionFor($reason); - } - ); - }; - }; - } - - /** - * Middleware that invokes a callback before and after sending a request. - * - * The provided listener cannot modify or alter the response. It simply - * "taps" into the chain to be notified before returning the promise. The - * before listener accepts a request and options array, and the after - * listener accepts a request, options array, and response promise. - * - * @param callable $before Function to invoke before forwarding the request. - * @param callable $after Function invoked after forwarding. - * - * @return callable Returns a function that accepts the next handler. - */ - public static function tap(callable $before = null, callable $after = null): callable - { - return static function (callable $handler) use ($before, $after): callable { - return static function (RequestInterface $request, array $options) use ($handler, $before, $after) { - if ($before) { - $before($request, $options); - } - $response = $handler($request, $options); - if ($after) { - $after($request, $options, $response); - } - return $response; - }; - }; - } - - /** - * Middleware that handles request redirects. - * - * @return callable Returns a function that accepts the next handler. - */ - public static function redirect(): callable - { - return static function (callable $handler): RedirectMiddleware { - return new RedirectMiddleware($handler); - }; - } - - /** - * Middleware that retries requests based on the boolean result of - * invoking the provided "decider" function. - * - * If no delay function is provided, a simple implementation of exponential - * backoff will be utilized. - * - * @param callable $decider Function that accepts the number of retries, - * a request, [response], and [exception] and - * returns true if the request is to be retried. - * @param callable $delay Function that accepts the number of retries and - * returns the number of milliseconds to delay. - * - * @return callable Returns a function that accepts the next handler. - */ - public static function retry(callable $decider, callable $delay = null): callable - { - return static function (callable $handler) use ($decider, $delay): RetryMiddleware { - return new RetryMiddleware($decider, $handler, $delay); - }; - } - - /** - * Middleware that logs requests, responses, and errors using a message - * formatter. - * - * @phpstan-param \Psr\Log\LogLevel::* $logLevel Level at which to log requests. - * - * @param LoggerInterface $logger Logs messages. - * @param MessageFormatterInterface|MessageFormatter $formatter Formatter used to create message strings. - * @param string $logLevel Level at which to log requests. - * - * @return callable Returns a function that accepts the next handler. - */ - public static function log(LoggerInterface $logger, $formatter, string $logLevel = 'info'): callable - { - // To be compatible with Guzzle 7.1.x we need to allow users to pass a MessageFormatter - if (!$formatter instanceof MessageFormatter && !$formatter instanceof MessageFormatterInterface) { - throw new \LogicException(sprintf('Argument 2 to %s::log() must be of type %s', self::class, MessageFormatterInterface::class)); - } - - return static function (callable $handler) use ($logger, $formatter, $logLevel): callable { - return static function (RequestInterface $request, array $options = []) use ($handler, $logger, $formatter, $logLevel) { - return $handler($request, $options)->then( - static function ($response) use ($logger, $request, $formatter, $logLevel): ResponseInterface { - $message = $formatter->format($request, $response); - $logger->log($logLevel, $message); - return $response; - }, - static function ($reason) use ($logger, $request, $formatter): PromiseInterface { - $response = $reason instanceof RequestException ? $reason->getResponse() : null; - $message = $formatter->format($request, $response, P\Create::exceptionFor($reason)); - $logger->error($message); - return P\Create::rejectionFor($reason); - } - ); - }; - }; - } - - /** - * This middleware adds a default content-type if possible, a default - * content-length or transfer-encoding header, and the expect header. - */ - public static function prepareBody(): callable - { - return static function (callable $handler): PrepareBodyMiddleware { - return new PrepareBodyMiddleware($handler); - }; - } - - /** - * Middleware that applies a map function to the request before passing to - * the next handler. - * - * @param callable $fn Function that accepts a RequestInterface and returns - * a RequestInterface. - */ - public static function mapRequest(callable $fn): callable - { - return static function (callable $handler) use ($fn): callable { - return static function (RequestInterface $request, array $options) use ($handler, $fn) { - return $handler($fn($request), $options); - }; - }; - } - - /** - * Middleware that applies a map function to the resolved promise's - * response. - * - * @param callable $fn Function that accepts a ResponseInterface and - * returns a ResponseInterface. - */ - public static function mapResponse(callable $fn): callable - { - return static function (callable $handler) use ($fn): callable { - return static function (RequestInterface $request, array $options) use ($handler, $fn) { - return $handler($request, $options)->then($fn); - }; - }; - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Pool.php b/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Pool.php deleted file mode 100644 index 6277c61..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Pool.php +++ /dev/null @@ -1,125 +0,0 @@ - $rfn) { - if ($rfn instanceof RequestInterface) { - yield $key => $client->sendAsync($rfn, $opts); - } elseif (\is_callable($rfn)) { - yield $key => $rfn($opts); - } else { - throw new \InvalidArgumentException('Each value yielded by the iterator must be a Psr7\Http\Message\RequestInterface or a callable that returns a promise that fulfills with a Psr7\Message\Http\ResponseInterface object.'); - } - } - }; - - $this->each = new EachPromise($requests(), $config); - } - - /** - * Get promise - */ - public function promise(): PromiseInterface - { - return $this->each->promise(); - } - - /** - * Sends multiple requests concurrently and returns an array of responses - * and exceptions that uses the same ordering as the provided requests. - * - * IMPORTANT: This method keeps every request and response in memory, and - * as such, is NOT recommended when sending a large number or an - * indeterminate number of requests concurrently. - * - * @param ClientInterface $client Client used to send the requests - * @param array|\Iterator $requests Requests to send concurrently. - * @param array $options Passes through the options available in - * {@see \GuzzleHttp\Pool::__construct} - * - * @return array Returns an array containing the response or an exception - * in the same order that the requests were sent. - * - * @throws \InvalidArgumentException if the event format is incorrect. - */ - public static function batch(ClientInterface $client, $requests, array $options = []): array - { - $res = []; - self::cmpCallback($options, 'fulfilled', $res); - self::cmpCallback($options, 'rejected', $res); - $pool = new static($client, $requests, $options); - $pool->promise()->wait(); - \ksort($res); - - return $res; - } - - /** - * Execute callback(s) - */ - private static function cmpCallback(array &$options, string $name, array &$results): void - { - if (!isset($options[$name])) { - $options[$name] = static function ($v, $k) use (&$results) { - $results[$k] = $v; - }; - } else { - $currentFn = $options[$name]; - $options[$name] = static function ($v, $k) use (&$results, $currentFn) { - $currentFn($v, $k); - $results[$k] = $v; - }; - } - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php b/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php deleted file mode 100644 index 7ca6283..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php +++ /dev/null @@ -1,104 +0,0 @@ -nextHandler = $nextHandler; - } - - public function __invoke(RequestInterface $request, array $options): PromiseInterface - { - $fn = $this->nextHandler; - - // Don't do anything if the request has no body. - if ($request->getBody()->getSize() === 0) { - return $fn($request, $options); - } - - $modify = []; - - // Add a default content-type if possible. - if (!$request->hasHeader('Content-Type')) { - if ($uri = $request->getBody()->getMetadata('uri')) { - if (is_string($uri) && $type = Psr7\MimeType::fromFilename($uri)) { - $modify['set_headers']['Content-Type'] = $type; - } - } - } - - // Add a default content-length or transfer-encoding header. - if (!$request->hasHeader('Content-Length') - && !$request->hasHeader('Transfer-Encoding') - ) { - $size = $request->getBody()->getSize(); - if ($size !== null) { - $modify['set_headers']['Content-Length'] = $size; - } else { - $modify['set_headers']['Transfer-Encoding'] = 'chunked'; - } - } - - // Add the expect header if needed. - $this->addExpectHeader($request, $options, $modify); - - return $fn(Psr7\Utils::modifyRequest($request, $modify), $options); - } - - /** - * Add expect header - */ - private function addExpectHeader(RequestInterface $request, array $options, array &$modify): void - { - // Determine if the Expect header should be used - if ($request->hasHeader('Expect')) { - return; - } - - $expect = $options['expect'] ?? null; - - // Return if disabled or if you're not using HTTP/1.1 or HTTP/2.0 - if ($expect === false || $request->getProtocolVersion() < 1.1) { - return; - } - - // The expect header is unconditionally enabled - if ($expect === true) { - $modify['set_headers']['Expect'] = '100-Continue'; - return; - } - - // By default, send the expect header when the payload is > 1mb - if ($expect === null) { - $expect = 1048576; - } - - // Always add if the body cannot be rewound, the size cannot be - // determined, or the size is greater than the cutoff threshold - $body = $request->getBody(); - $size = $body->getSize(); - - if ($size === null || $size >= (int) $expect || !$body->isSeekable()) { - $modify['set_headers']['Expect'] = '100-Continue'; - } - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/RedirectMiddleware.php b/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/RedirectMiddleware.php deleted file mode 100644 index 1dd3861..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/RedirectMiddleware.php +++ /dev/null @@ -1,216 +0,0 @@ - 5, - 'protocols' => ['http', 'https'], - 'strict' => false, - 'referer' => false, - 'track_redirects' => false, - ]; - - /** - * @var callable(RequestInterface, array): PromiseInterface - */ - private $nextHandler; - - /** - * @param callable(RequestInterface, array): PromiseInterface $nextHandler Next handler to invoke. - */ - public function __construct(callable $nextHandler) - { - $this->nextHandler = $nextHandler; - } - - public function __invoke(RequestInterface $request, array $options): PromiseInterface - { - $fn = $this->nextHandler; - - if (empty($options['allow_redirects'])) { - return $fn($request, $options); - } - - if ($options['allow_redirects'] === true) { - $options['allow_redirects'] = self::$defaultSettings; - } elseif (!\is_array($options['allow_redirects'])) { - throw new \InvalidArgumentException('allow_redirects must be true, false, or array'); - } else { - // Merge the default settings with the provided settings - $options['allow_redirects'] += self::$defaultSettings; - } - - if (empty($options['allow_redirects']['max'])) { - return $fn($request, $options); - } - - return $fn($request, $options) - ->then(function (ResponseInterface $response) use ($request, $options) { - return $this->checkRedirect($request, $options, $response); - }); - } - - /** - * @return ResponseInterface|PromiseInterface - */ - public function checkRedirect(RequestInterface $request, array $options, ResponseInterface $response) - { - if (\strpos((string) $response->getStatusCode(), '3') !== 0 - || !$response->hasHeader('Location') - ) { - return $response; - } - - $this->guardMax($request, $response, $options); - $nextRequest = $this->modifyRequest($request, $options, $response); - - if (isset($options['allow_redirects']['on_redirect'])) { - ($options['allow_redirects']['on_redirect'])( - $request, - $response, - $nextRequest->getUri() - ); - } - - $promise = $this($nextRequest, $options); - - // Add headers to be able to track history of redirects. - if (!empty($options['allow_redirects']['track_redirects'])) { - return $this->withTracking( - $promise, - (string) $nextRequest->getUri(), - $response->getStatusCode() - ); - } - - return $promise; - } - - /** - * Enable tracking on promise. - */ - private function withTracking(PromiseInterface $promise, string $uri, int $statusCode): PromiseInterface - { - return $promise->then( - static function (ResponseInterface $response) use ($uri, $statusCode) { - // Note that we are pushing to the front of the list as this - // would be an earlier response than what is currently present - // in the history header. - $historyHeader = $response->getHeader(self::HISTORY_HEADER); - $statusHeader = $response->getHeader(self::STATUS_HISTORY_HEADER); - \array_unshift($historyHeader, $uri); - \array_unshift($statusHeader, (string) $statusCode); - - return $response->withHeader(self::HISTORY_HEADER, $historyHeader) - ->withHeader(self::STATUS_HISTORY_HEADER, $statusHeader); - } - ); - } - - /** - * Check for too many redirects - * - * @throws TooManyRedirectsException Too many redirects. - */ - private function guardMax(RequestInterface $request, ResponseInterface $response, array &$options): void - { - $current = $options['__redirect_count'] - ?? 0; - $options['__redirect_count'] = $current + 1; - $max = $options['allow_redirects']['max']; - - if ($options['__redirect_count'] > $max) { - throw new TooManyRedirectsException("Will not follow more than {$max} redirects", $request, $response); - } - } - - public function modifyRequest(RequestInterface $request, array $options, ResponseInterface $response): RequestInterface - { - // Request modifications to apply. - $modify = []; - $protocols = $options['allow_redirects']['protocols']; - - // Use a GET request if this is an entity enclosing request and we are - // not forcing RFC compliance, but rather emulating what all browsers - // would do. - $statusCode = $response->getStatusCode(); - if ($statusCode == 303 || - ($statusCode <= 302 && !$options['allow_redirects']['strict']) - ) { - $safeMethods = ['GET', 'HEAD', 'OPTIONS']; - $requestMethod = $request->getMethod(); - - $modify['method'] = in_array($requestMethod, $safeMethods) ? $requestMethod : 'GET'; - $modify['body'] = ''; - } - - $uri = $this->redirectUri($request, $response, $protocols); - if (isset($options['idn_conversion']) && ($options['idn_conversion'] !== false)) { - $idnOptions = ($options['idn_conversion'] === true) ? \IDNA_DEFAULT : $options['idn_conversion']; - $uri = Utils::idnUriConvert($uri, $idnOptions); - } - - $modify['uri'] = $uri; - Psr7\Message::rewindBody($request); - - // Add the Referer header if it is told to do so and only - // add the header if we are not redirecting from https to http. - if ($options['allow_redirects']['referer'] - && $modify['uri']->getScheme() === $request->getUri()->getScheme() - ) { - $uri = $request->getUri()->withUserInfo(''); - $modify['set_headers']['Referer'] = (string) $uri; - } else { - $modify['remove_headers'][] = 'Referer'; - } - - // Remove Authorization header if host is different. - if ($request->getUri()->getHost() !== $modify['uri']->getHost()) { - $modify['remove_headers'][] = 'Authorization'; - } - - return Psr7\Utils::modifyRequest($request, $modify); - } - - /** - * Set the appropriate URL on the request based on the location header - */ - private function redirectUri(RequestInterface $request, ResponseInterface $response, array $protocols): UriInterface - { - $location = Psr7\UriResolver::resolve( - $request->getUri(), - new Psr7\Uri($response->getHeaderLine('Location')) - ); - - // Ensure that the redirect URI is allowed based on the protocols. - if (!\in_array($location->getScheme(), $protocols)) { - throw new BadResponseException(\sprintf('Redirect URI, %s, does not use one of the allowed redirect protocols: %s', $location, \implode(', ', $protocols)), $request, $response); - } - - return $location; - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/RequestOptions.php b/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/RequestOptions.php deleted file mode 100644 index 20b31bc..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/RequestOptions.php +++ /dev/null @@ -1,264 +0,0 @@ -decider = $decider; - $this->nextHandler = $nextHandler; - $this->delay = $delay ?: __CLASS__ . '::exponentialDelay'; - } - - /** - * Default exponential backoff delay function. - * - * @return int milliseconds. - */ - public static function exponentialDelay(int $retries): int - { - return (int) \pow(2, $retries - 1) * 1000; - } - - public function __invoke(RequestInterface $request, array $options): PromiseInterface - { - if (!isset($options['retries'])) { - $options['retries'] = 0; - } - - $fn = $this->nextHandler; - return $fn($request, $options) - ->then( - $this->onFulfilled($request, $options), - $this->onRejected($request, $options) - ); - } - - /** - * Execute fulfilled closure - */ - private function onFulfilled(RequestInterface $request, array $options): callable - { - return function ($value) use ($request, $options) { - if (!($this->decider)( - $options['retries'], - $request, - $value, - null - )) { - return $value; - } - return $this->doRetry($request, $options, $value); - }; - } - - /** - * Execute rejected closure - */ - private function onRejected(RequestInterface $req, array $options): callable - { - return function ($reason) use ($req, $options) { - if (!($this->decider)( - $options['retries'], - $req, - null, - $reason - )) { - return P\Create::rejectionFor($reason); - } - return $this->doRetry($req, $options); - }; - } - - private function doRetry(RequestInterface $request, array $options, ResponseInterface $response = null): PromiseInterface - { - $options['delay'] = ($this->delay)(++$options['retries'], $response); - - return $this($request, $options); - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/TransferStats.php b/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/TransferStats.php deleted file mode 100644 index 93fa334..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/TransferStats.php +++ /dev/null @@ -1,133 +0,0 @@ -request = $request; - $this->response = $response; - $this->transferTime = $transferTime; - $this->handlerErrorData = $handlerErrorData; - $this->handlerStats = $handlerStats; - } - - public function getRequest(): RequestInterface - { - return $this->request; - } - - /** - * Returns the response that was received (if any). - */ - public function getResponse(): ?ResponseInterface - { - return $this->response; - } - - /** - * Returns true if a response was received. - */ - public function hasResponse(): bool - { - return $this->response !== null; - } - - /** - * Gets handler specific error data. - * - * This might be an exception, a integer representing an error code, or - * anything else. Relying on this value assumes that you know what handler - * you are using. - * - * @return mixed - */ - public function getHandlerErrorData() - { - return $this->handlerErrorData; - } - - /** - * Get the effective URI the request was sent to. - */ - public function getEffectiveUri(): UriInterface - { - return $this->request->getUri(); - } - - /** - * Get the estimated time the request was being transferred by the handler. - * - * @return float|null Time in seconds. - */ - public function getTransferTime(): ?float - { - return $this->transferTime; - } - - /** - * Gets an array of all of the handler specific transfer data. - */ - public function getHandlerStats(): array - { - return $this->handlerStats; - } - - /** - * Get a specific handler statistic from the handler by name. - * - * @param string $stat Handler specific transfer stat to retrieve. - * - * @return mixed|null - */ - public function getHandlerStat(string $stat) - { - return $this->handlerStats[$stat] ?? null; - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Utils.php b/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Utils.php deleted file mode 100644 index 1e4e704..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/Utils.php +++ /dev/null @@ -1,382 +0,0 @@ -getHost()) { - $asciiHost = self::idnToAsci($uri->getHost(), $options, $info); - if ($asciiHost === false) { - $errorBitSet = $info['errors'] ?? 0; - - $errorConstants = array_filter(array_keys(get_defined_constants()), static function ($name) { - return substr($name, 0, 11) === 'IDNA_ERROR_'; - }); - - $errors = []; - foreach ($errorConstants as $errorConstant) { - if ($errorBitSet & constant($errorConstant)) { - $errors[] = $errorConstant; - } - } - - $errorMessage = 'IDN conversion failed'; - if ($errors) { - $errorMessage .= ' (errors: ' . implode(', ', $errors) . ')'; - } - - throw new InvalidArgumentException($errorMessage); - } - if ($uri->getHost() !== $asciiHost) { - // Replace URI only if the ASCII version is different - $uri = $uri->withHost($asciiHost); - } - } - - return $uri; - } - - /** - * @internal - */ - public static function getenv(string $name): ?string - { - if (isset($_SERVER[$name])) { - return (string) $_SERVER[$name]; - } - - if (\PHP_SAPI === 'cli' && ($value = \getenv($name)) !== false && $value !== null) { - return (string) $value; - } - - return null; - } - - /** - * @return string|false - */ - private static function idnToAsci(string $domain, int $options, ?array &$info = []) - { - if (\function_exists('idn_to_ascii') && \defined('INTL_IDNA_VARIANT_UTS46')) { - return \idn_to_ascii($domain, $options, \INTL_IDNA_VARIANT_UTS46, $info); - } - - throw new \Error('ext-idn or symfony/polyfill-intl-idn not loaded or too old'); - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/functions.php b/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/functions.php deleted file mode 100644 index a70d2cb..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/guzzle/src/functions.php +++ /dev/null @@ -1,167 +0,0 @@ - - -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/plugins/automagic-images/vendor/guzzlehttp/promises/Makefile b/plugins/automagic-images/vendor/guzzlehttp/promises/Makefile deleted file mode 100644 index 8d5b3ef..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/promises/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -all: clean test - -test: - vendor/bin/phpunit - -coverage: - vendor/bin/phpunit --coverage-html=artifacts/coverage - -view-coverage: - open artifacts/coverage/index.html - -clean: - rm -rf artifacts/* diff --git a/plugins/automagic-images/vendor/guzzlehttp/promises/README.md b/plugins/automagic-images/vendor/guzzlehttp/promises/README.md deleted file mode 100644 index a95c605..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/promises/README.md +++ /dev/null @@ -1,532 +0,0 @@ -# Guzzle Promises - -[Promises/A+](https://promisesaplus.com/) implementation that handles promise -chaining and resolution iteratively, allowing for "infinite" promise chaining -while keeping the stack size constant. Read [this blog post](https://blog.domenic.me/youre-missing-the-point-of-promises/) -for a general introduction to promises. - -- [Features](#features) -- [Quick start](#quick-start) -- [Synchronous wait](#synchronous-wait) -- [Cancellation](#cancellation) -- [API](#api) - - [Promise](#promise) - - [FulfilledPromise](#fulfilledpromise) - - [RejectedPromise](#rejectedpromise) -- [Promise interop](#promise-interop) -- [Implementation notes](#implementation-notes) - - -# Features - -- [Promises/A+](https://promisesaplus.com/) implementation. -- Promise resolution and chaining is handled iteratively, allowing for - "infinite" promise chaining. -- Promises have a synchronous `wait` method. -- Promises can be cancelled. -- Works with any object that has a `then` function. -- C# style async/await coroutine promises using - `GuzzleHttp\Promise\Coroutine::of()`. - - -# Quick start - -A *promise* represents the eventual result of an asynchronous operation. The -primary way of interacting with a promise is through its `then` method, which -registers callbacks to receive either a promise's eventual value or the reason -why the promise cannot be fulfilled. - - -## Callbacks - -Callbacks are registered with the `then` method by providing an optional -`$onFulfilled` followed by an optional `$onRejected` function. - - -```php -use GuzzleHttp\Promise\Promise; - -$promise = new Promise(); -$promise->then( - // $onFulfilled - function ($value) { - echo 'The promise was fulfilled.'; - }, - // $onRejected - function ($reason) { - echo 'The promise was rejected.'; - } -); -``` - -*Resolving* a promise means that you either fulfill a promise with a *value* or -reject a promise with a *reason*. Resolving a promises triggers callbacks -registered with the promises's `then` method. These callbacks are triggered -only once and in the order in which they were added. - - -## Resolving a promise - -Promises are fulfilled using the `resolve($value)` method. Resolving a promise -with any value other than a `GuzzleHttp\Promise\RejectedPromise` will trigger -all of the onFulfilled callbacks (resolving a promise with a rejected promise -will reject the promise and trigger the `$onRejected` callbacks). - -```php -use GuzzleHttp\Promise\Promise; - -$promise = new Promise(); -$promise - ->then(function ($value) { - // Return a value and don't break the chain - return "Hello, " . $value; - }) - // This then is executed after the first then and receives the value - // returned from the first then. - ->then(function ($value) { - echo $value; - }); - -// Resolving the promise triggers the $onFulfilled callbacks and outputs -// "Hello, reader." -$promise->resolve('reader.'); -``` - - -## Promise forwarding - -Promises can be chained one after the other. Each then in the chain is a new -promise. The return value of a promise is what's forwarded to the next -promise in the chain. Returning a promise in a `then` callback will cause the -subsequent promises in the chain to only be fulfilled when the returned promise -has been fulfilled. The next promise in the chain will be invoked with the -resolved value of the promise. - -```php -use GuzzleHttp\Promise\Promise; - -$promise = new Promise(); -$nextPromise = new Promise(); - -$promise - ->then(function ($value) use ($nextPromise) { - echo $value; - return $nextPromise; - }) - ->then(function ($value) { - echo $value; - }); - -// Triggers the first callback and outputs "A" -$promise->resolve('A'); -// Triggers the second callback and outputs "B" -$nextPromise->resolve('B'); -``` - -## Promise rejection - -When a promise is rejected, the `$onRejected` callbacks are invoked with the -rejection reason. - -```php -use GuzzleHttp\Promise\Promise; - -$promise = new Promise(); -$promise->then(null, function ($reason) { - echo $reason; -}); - -$promise->reject('Error!'); -// Outputs "Error!" -``` - -## Rejection forwarding - -If an exception is thrown in an `$onRejected` callback, subsequent -`$onRejected` callbacks are invoked with the thrown exception as the reason. - -```php -use GuzzleHttp\Promise\Promise; - -$promise = new Promise(); -$promise->then(null, function ($reason) { - throw new Exception($reason); -})->then(null, function ($reason) { - assert($reason->getMessage() === 'Error!'); -}); - -$promise->reject('Error!'); -``` - -You can also forward a rejection down the promise chain by returning a -`GuzzleHttp\Promise\RejectedPromise` in either an `$onFulfilled` or -`$onRejected` callback. - -```php -use GuzzleHttp\Promise\Promise; -use GuzzleHttp\Promise\RejectedPromise; - -$promise = new Promise(); -$promise->then(null, function ($reason) { - return new RejectedPromise($reason); -})->then(null, function ($reason) { - assert($reason === 'Error!'); -}); - -$promise->reject('Error!'); -``` - -If an exception is not thrown in a `$onRejected` callback and the callback -does not return a rejected promise, downstream `$onFulfilled` callbacks are -invoked using the value returned from the `$onRejected` callback. - -```php -use GuzzleHttp\Promise\Promise; - -$promise = new Promise(); -$promise - ->then(null, function ($reason) { - return "It's ok"; - }) - ->then(function ($value) { - assert($value === "It's ok"); - }); - -$promise->reject('Error!'); -``` - -# Synchronous wait - -You can synchronously force promises to complete using a promise's `wait` -method. When creating a promise, you can provide a wait function that is used -to synchronously force a promise to complete. When a wait function is invoked -it is expected to deliver a value to the promise or reject the promise. If the -wait function does not deliver a value, then an exception is thrown. The wait -function provided to a promise constructor is invoked when the `wait` function -of the promise is called. - -```php -$promise = new Promise(function () use (&$promise) { - $promise->resolve('foo'); -}); - -// Calling wait will return the value of the promise. -echo $promise->wait(); // outputs "foo" -``` - -If an exception is encountered while invoking the wait function of a promise, -the promise is rejected with the exception and the exception is thrown. - -```php -$promise = new Promise(function () use (&$promise) { - throw new Exception('foo'); -}); - -$promise->wait(); // throws the exception. -``` - -Calling `wait` on a promise that has been fulfilled will not trigger the wait -function. It will simply return the previously resolved value. - -```php -$promise = new Promise(function () { die('this is not called!'); }); -$promise->resolve('foo'); -echo $promise->wait(); // outputs "foo" -``` - -Calling `wait` on a promise that has been rejected will throw an exception. If -the rejection reason is an instance of `\Exception` the reason is thrown. -Otherwise, a `GuzzleHttp\Promise\RejectionException` is thrown and the reason -can be obtained by calling the `getReason` method of the exception. - -```php -$promise = new Promise(); -$promise->reject('foo'); -$promise->wait(); -``` - -> PHP Fatal error: Uncaught exception 'GuzzleHttp\Promise\RejectionException' with message 'The promise was rejected with value: foo' - - -## Unwrapping a promise - -When synchronously waiting on a promise, you are joining the state of the -promise into the current state of execution (i.e., return the value of the -promise if it was fulfilled or throw an exception if it was rejected). This is -called "unwrapping" the promise. Waiting on a promise will by default unwrap -the promise state. - -You can force a promise to resolve and *not* unwrap the state of the promise -by passing `false` to the first argument of the `wait` function: - -```php -$promise = new Promise(); -$promise->reject('foo'); -// This will not throw an exception. It simply ensures the promise has -// been resolved. -$promise->wait(false); -``` - -When unwrapping a promise, the resolved value of the promise will be waited -upon until the unwrapped value is not a promise. This means that if you resolve -promise A with a promise B and unwrap promise A, the value returned by the -wait function will be the value delivered to promise B. - -**Note**: when you do not unwrap the promise, no value is returned. - - -# Cancellation - -You can cancel a promise that has not yet been fulfilled using the `cancel()` -method of a promise. When creating a promise you can provide an optional -cancel function that when invoked cancels the action of computing a resolution -of the promise. - - -# API - - -## Promise - -When creating a promise object, you can provide an optional `$waitFn` and -`$cancelFn`. `$waitFn` is a function that is invoked with no arguments and is -expected to resolve the promise. `$cancelFn` is a function with no arguments -that is expected to cancel the computation of a promise. It is invoked when the -`cancel()` method of a promise is called. - -```php -use GuzzleHttp\Promise\Promise; - -$promise = new Promise( - function () use (&$promise) { - $promise->resolve('waited'); - }, - function () { - // do something that will cancel the promise computation (e.g., close - // a socket, cancel a database query, etc...) - } -); - -assert('waited' === $promise->wait()); -``` - -A promise has the following methods: - -- `then(callable $onFulfilled, callable $onRejected) : PromiseInterface` - - Appends fulfillment and rejection handlers to the promise, and returns a new promise resolving to the return value of the called handler. - -- `otherwise(callable $onRejected) : PromiseInterface` - - Appends a rejection handler callback to the promise, and returns a new promise resolving to the return value of the callback if it is called, or to its original fulfillment value if the promise is instead fulfilled. - -- `wait($unwrap = true) : mixed` - - Synchronously waits on the promise to complete. - - `$unwrap` controls whether or not the value of the promise is returned for a - fulfilled promise or if an exception is thrown if the promise is rejected. - This is set to `true` by default. - -- `cancel()` - - Attempts to cancel the promise if possible. The promise being cancelled and - the parent most ancestor that has not yet been resolved will also be - cancelled. Any promises waiting on the cancelled promise to resolve will also - be cancelled. - -- `getState() : string` - - Returns the state of the promise. One of `pending`, `fulfilled`, or - `rejected`. - -- `resolve($value)` - - Fulfills the promise with the given `$value`. - -- `reject($reason)` - - Rejects the promise with the given `$reason`. - - -## FulfilledPromise - -A fulfilled promise can be created to represent a promise that has been -fulfilled. - -```php -use GuzzleHttp\Promise\FulfilledPromise; - -$promise = new FulfilledPromise('value'); - -// Fulfilled callbacks are immediately invoked. -$promise->then(function ($value) { - echo $value; -}); -``` - - -## RejectedPromise - -A rejected promise can be created to represent a promise that has been -rejected. - -```php -use GuzzleHttp\Promise\RejectedPromise; - -$promise = new RejectedPromise('Error'); - -// Rejected callbacks are immediately invoked. -$promise->then(null, function ($reason) { - echo $reason; -}); -``` - - -# Promise interop - -This library works with foreign promises that have a `then` method. This means -you can use Guzzle promises with [React promises](https://github.com/reactphp/promise) -for example. When a foreign promise is returned inside of a then method -callback, promise resolution will occur recursively. - -```php -// Create a React promise -$deferred = new React\Promise\Deferred(); -$reactPromise = $deferred->promise(); - -// Create a Guzzle promise that is fulfilled with a React promise. -$guzzlePromise = new GuzzleHttp\Promise\Promise(); -$guzzlePromise->then(function ($value) use ($reactPromise) { - // Do something something with the value... - // Return the React promise - return $reactPromise; -}); -``` - -Please note that wait and cancel chaining is no longer possible when forwarding -a foreign promise. You will need to wrap a third-party promise with a Guzzle -promise in order to utilize wait and cancel functions with foreign promises. - - -## Event Loop Integration - -In order to keep the stack size constant, Guzzle promises are resolved -asynchronously using a task queue. When waiting on promises synchronously, the -task queue will be automatically run to ensure that the blocking promise and -any forwarded promises are resolved. When using promises asynchronously in an -event loop, you will need to run the task queue on each tick of the loop. If -you do not run the task queue, then promises will not be resolved. - -You can run the task queue using the `run()` method of the global task queue -instance. - -```php -// Get the global task queue -$queue = GuzzleHttp\Promise\Utils::queue(); -$queue->run(); -``` - -For example, you could use Guzzle promises with React using a periodic timer: - -```php -$loop = React\EventLoop\Factory::create(); -$loop->addPeriodicTimer(0, [$queue, 'run']); -``` - -*TODO*: Perhaps adding a `futureTick()` on each tick would be faster? - - -# Implementation notes - - -## Promise resolution and chaining is handled iteratively - -By shuffling pending handlers from one owner to another, promises are -resolved iteratively, allowing for "infinite" then chaining. - -```php -then(function ($v) { - // The stack size remains constant (a good thing) - echo xdebug_get_stack_depth() . ', '; - return $v + 1; - }); -} - -$parent->resolve(0); -var_dump($p->wait()); // int(1000) - -``` - -When a promise is fulfilled or rejected with a non-promise value, the promise -then takes ownership of the handlers of each child promise and delivers values -down the chain without using recursion. - -When a promise is resolved with another promise, the original promise transfers -all of its pending handlers to the new promise. When the new promise is -eventually resolved, all of the pending handlers are delivered the forwarded -value. - - -## A promise is the deferred. - -Some promise libraries implement promises using a deferred object to represent -a computation and a promise object to represent the delivery of the result of -the computation. This is a nice separation of computation and delivery because -consumers of the promise cannot modify the value that will be eventually -delivered. - -One side effect of being able to implement promise resolution and chaining -iteratively is that you need to be able for one promise to reach into the state -of another promise to shuffle around ownership of handlers. In order to achieve -this without making the handlers of a promise publicly mutable, a promise is -also the deferred value, allowing promises of the same parent class to reach -into and modify the private properties of promises of the same type. While this -does allow consumers of the value to modify the resolution or rejection of the -deferred, it is a small price to pay for keeping the stack size constant. - -```php -$promise = new Promise(); -$promise->then(function ($value) { echo $value; }); -// The promise is the deferred value, so you can deliver a value to it. -$promise->resolve('foo'); -// prints "foo" -``` - - -## Upgrading from Function API - -A static API was first introduced in 1.4.0, in order to mitigate problems with functions conflicting between global and local copies of the package. The function API will be removed in 2.0.0. A migration table has been provided here for your convenience: - -| Original Function | Replacement Method | -|----------------|----------------| -| `queue` | `Utils::queue` | -| `task` | `Utils::task` | -| `promise_for` | `Create::promiseFor` | -| `rejection_for` | `Create::rejectionFor` | -| `exception_for` | `Create::exceptionFor` | -| `iter_for` | `Create::iterFor` | -| `inspect` | `Utils::inspect` | -| `inspect_all` | `Utils::inspectAll` | -| `unwrap` | `Utils::unwrap` | -| `all` | `Utils::all` | -| `some` | `Utils::some` | -| `any` | `Utils::any` | -| `settle` | `Utils::settle` | -| `each` | `Each::of` | -| `each_limit` | `Each::ofLimit` | -| `each_limit_all` | `Each::ofLimitAll` | -| `!is_fulfilled` | `Is::pending` | -| `is_fulfilled` | `Is::fulfilled` | -| `is_rejected` | `Is::rejected` | -| `is_settled` | `Is::settled` | -| `coroutine` | `Coroutine::of` | diff --git a/plugins/automagic-images/vendor/guzzlehttp/promises/composer.json b/plugins/automagic-images/vendor/guzzlehttp/promises/composer.json deleted file mode 100644 index db44d9e..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/promises/composer.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "name": "guzzlehttp/promises", - "description": "Guzzle promises library", - "keywords": ["promise"], - "license": "MIT", - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "require": { - "php": ">=5.5" - }, - "require-dev": { - "symfony/phpunit-bridge": "^4.4 || ^5.1" - }, - "autoload": { - "psr-4": { - "GuzzleHttp\\Promise\\": "src/" - }, - "files": ["src/functions_include.php"] - }, - "autoload-dev": { - "psr-4": { - "GuzzleHttp\\Promise\\Tests\\": "tests/" - } - }, - "scripts": { - "test": "vendor/bin/simple-phpunit", - "test-ci": "vendor/bin/simple-phpunit --coverage-text" - }, - "extra": { - "branch-alias": { - "dev-master": "1.4-dev" - } - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/promises/src/AggregateException.php b/plugins/automagic-images/vendor/guzzlehttp/promises/src/AggregateException.php deleted file mode 100644 index d2b5712..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/promises/src/AggregateException.php +++ /dev/null @@ -1,17 +0,0 @@ -then(function ($v) { echo $v; }); - * - * @param callable $generatorFn Generator function to wrap into a promise. - * - * @return Promise - * - * @link https://github.com/petkaantonov/bluebird/blob/master/API.md#generators inspiration - */ -final class Coroutine implements PromiseInterface -{ - /** - * @var PromiseInterface|null - */ - private $currentPromise; - - /** - * @var Generator - */ - private $generator; - - /** - * @var Promise - */ - private $result; - - public function __construct(callable $generatorFn) - { - $this->generator = $generatorFn(); - $this->result = new Promise(function () { - while (isset($this->currentPromise)) { - $this->currentPromise->wait(); - } - }); - try { - $this->nextCoroutine($this->generator->current()); - } catch (\Exception $exception) { - $this->result->reject($exception); - } catch (Throwable $throwable) { - $this->result->reject($throwable); - } - } - - /** - * Create a new coroutine. - * - * @return self - */ - public static function of(callable $generatorFn) - { - return new self($generatorFn); - } - - public function then( - callable $onFulfilled = null, - callable $onRejected = null - ) { - return $this->result->then($onFulfilled, $onRejected); - } - - public function otherwise(callable $onRejected) - { - return $this->result->otherwise($onRejected); - } - - public function wait($unwrap = true) - { - return $this->result->wait($unwrap); - } - - public function getState() - { - return $this->result->getState(); - } - - public function resolve($value) - { - $this->result->resolve($value); - } - - public function reject($reason) - { - $this->result->reject($reason); - } - - public function cancel() - { - $this->currentPromise->cancel(); - $this->result->cancel(); - } - - private function nextCoroutine($yielded) - { - $this->currentPromise = Create::promiseFor($yielded) - ->then([$this, '_handleSuccess'], [$this, '_handleFailure']); - } - - /** - * @internal - */ - public function _handleSuccess($value) - { - unset($this->currentPromise); - try { - $next = $this->generator->send($value); - if ($this->generator->valid()) { - $this->nextCoroutine($next); - } else { - $this->result->resolve($value); - } - } catch (Exception $exception) { - $this->result->reject($exception); - } catch (Throwable $throwable) { - $this->result->reject($throwable); - } - } - - /** - * @internal - */ - public function _handleFailure($reason) - { - unset($this->currentPromise); - try { - $nextYield = $this->generator->throw(Create::exceptionFor($reason)); - // The throw was caught, so keep iterating on the coroutine - $this->nextCoroutine($nextYield); - } catch (Exception $exception) { - $this->result->reject($exception); - } catch (Throwable $throwable) { - $this->result->reject($throwable); - } - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/promises/src/Create.php b/plugins/automagic-images/vendor/guzzlehttp/promises/src/Create.php deleted file mode 100644 index 8d038e9..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/promises/src/Create.php +++ /dev/null @@ -1,84 +0,0 @@ -then([$promise, 'resolve'], [$promise, 'reject']); - return $promise; - } - - return new FulfilledPromise($value); - } - - /** - * Creates a rejected promise for a reason if the reason is not a promise. - * If the provided reason is a promise, then it is returned as-is. - * - * @param mixed $reason Promise or reason. - * - * @return PromiseInterface - */ - public static function rejectionFor($reason) - { - if ($reason instanceof PromiseInterface) { - return $reason; - } - - return new RejectedPromise($reason); - } - - /** - * Create an exception for a rejected promise value. - * - * @param mixed $reason - * - * @return \Exception|\Throwable - */ - public static function exceptionFor($reason) - { - if ($reason instanceof \Exception || $reason instanceof \Throwable) { - return $reason; - } - - return new RejectionException($reason); - } - - /** - * Returns an iterator for the given value. - * - * @param mixed $value - * - * @return \Iterator - */ - public static function iterFor($value) - { - if ($value instanceof \Iterator) { - return $value; - } - - if (is_array($value)) { - return new \ArrayIterator($value); - } - - return new \ArrayIterator([$value]); - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/promises/src/Each.php b/plugins/automagic-images/vendor/guzzlehttp/promises/src/Each.php deleted file mode 100644 index 1dda354..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/promises/src/Each.php +++ /dev/null @@ -1,90 +0,0 @@ - $onFulfilled, - 'rejected' => $onRejected - ]))->promise(); - } - - /** - * Like of, but only allows a certain number of outstanding promises at any - * given time. - * - * $concurrency may be an integer or a function that accepts the number of - * pending promises and returns a numeric concurrency limit value to allow - * for dynamic a concurrency size. - * - * @param mixed $iterable - * @param int|callable $concurrency - * @param callable $onFulfilled - * @param callable $onRejected - * - * @return PromiseInterface - */ - public static function ofLimit( - $iterable, - $concurrency, - callable $onFulfilled = null, - callable $onRejected = null - ) { - return (new EachPromise($iterable, [ - 'fulfilled' => $onFulfilled, - 'rejected' => $onRejected, - 'concurrency' => $concurrency - ]))->promise(); - } - - /** - * Like limit, but ensures that no promise in the given $iterable argument - * is rejected. If any promise is rejected, then the aggregate promise is - * rejected with the encountered rejection. - * - * @param mixed $iterable - * @param int|callable $concurrency - * @param callable $onFulfilled - * - * @return PromiseInterface - */ - public static function ofLimitAll( - $iterable, - $concurrency, - callable $onFulfilled = null - ) { - return each_limit( - $iterable, - $concurrency, - $onFulfilled, - function ($reason, $idx, PromiseInterface $aggregate) { - $aggregate->reject($reason); - } - ); - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/promises/src/EachPromise.php b/plugins/automagic-images/vendor/guzzlehttp/promises/src/EachPromise.php deleted file mode 100644 index 748f471..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/promises/src/EachPromise.php +++ /dev/null @@ -1,254 +0,0 @@ -iterable = Create::iterFor($iterable); - - if (isset($config['concurrency'])) { - $this->concurrency = $config['concurrency']; - } - - if (isset($config['fulfilled'])) { - $this->onFulfilled = $config['fulfilled']; - } - - if (isset($config['rejected'])) { - $this->onRejected = $config['rejected']; - } - } - - /** @psalm-suppress InvalidNullableReturnType */ - public function promise() - { - if ($this->aggregate) { - return $this->aggregate; - } - - try { - $this->createPromise(); - /** @psalm-assert Promise $this->aggregate */ - $this->iterable->rewind(); - if (!$this->checkIfFinished()) { - $this->refillPending(); - } - } catch (\Throwable $e) { - /** - * @psalm-suppress NullReference - * @phpstan-ignore-next-line - */ - $this->aggregate->reject($e); - } catch (\Exception $e) { - /** - * @psalm-suppress NullReference - * @phpstan-ignore-next-line - */ - $this->aggregate->reject($e); - } - - /** - * @psalm-suppress NullableReturnStatement - * @phpstan-ignore-next-line - */ - return $this->aggregate; - } - - private function createPromise() - { - $this->mutex = false; - $this->aggregate = new Promise(function () { - reset($this->pending); - // Consume a potentially fluctuating list of promises while - // ensuring that indexes are maintained (precluding array_shift). - while ($promise = current($this->pending)) { - next($this->pending); - $promise->wait(); - if (Is::settled($this->aggregate)) { - return; - } - } - }); - - // Clear the references when the promise is resolved. - $clearFn = function () { - $this->iterable = $this->concurrency = $this->pending = null; - $this->onFulfilled = $this->onRejected = null; - $this->nextPendingIndex = 0; - }; - - $this->aggregate->then($clearFn, $clearFn); - } - - private function refillPending() - { - if (!$this->concurrency) { - // Add all pending promises. - while ($this->addPending() && $this->advanceIterator()); - return; - } - - // Add only up to N pending promises. - $concurrency = is_callable($this->concurrency) - ? call_user_func($this->concurrency, count($this->pending)) - : $this->concurrency; - $concurrency = max($concurrency - count($this->pending), 0); - // Concurrency may be set to 0 to disallow new promises. - if (!$concurrency) { - return; - } - // Add the first pending promise. - $this->addPending(); - // Note this is special handling for concurrency=1 so that we do - // not advance the iterator after adding the first promise. This - // helps work around issues with generators that might not have the - // next value to yield until promise callbacks are called. - while (--$concurrency - && $this->advanceIterator() - && $this->addPending()); - } - - private function addPending() - { - if (!$this->iterable || !$this->iterable->valid()) { - return false; - } - - $promise = Create::promiseFor($this->iterable->current()); - $key = $this->iterable->key(); - - // Iterable keys may not be unique, so we use a counter to - // guarantee uniqueness - $idx = $this->nextPendingIndex++; - - $this->pending[$idx] = $promise->then( - function ($value) use ($idx, $key) { - if ($this->onFulfilled) { - call_user_func( - $this->onFulfilled, - $value, - $key, - $this->aggregate - ); - } - $this->step($idx); - }, - function ($reason) use ($idx, $key) { - if ($this->onRejected) { - call_user_func( - $this->onRejected, - $reason, - $key, - $this->aggregate - ); - } - $this->step($idx); - } - ); - - return true; - } - - private function advanceIterator() - { - // Place a lock on the iterator so that we ensure to not recurse, - // preventing fatal generator errors. - if ($this->mutex) { - return false; - } - - $this->mutex = true; - - try { - $this->iterable->next(); - $this->mutex = false; - return true; - } catch (\Throwable $e) { - $this->aggregate->reject($e); - $this->mutex = false; - return false; - } catch (\Exception $e) { - $this->aggregate->reject($e); - $this->mutex = false; - return false; - } - } - - private function step($idx) - { - // If the promise was already resolved, then ignore this step. - if (Is::settled($this->aggregate)) { - return; - } - - unset($this->pending[$idx]); - - // Only refill pending promises if we are not locked, preventing the - // EachPromise to recursively invoke the provided iterator, which - // cause a fatal error: "Cannot resume an already running generator" - if ($this->advanceIterator() && !$this->checkIfFinished()) { - // Add more pending promises if possible. - $this->refillPending(); - } - } - - private function checkIfFinished() - { - if (!$this->pending && !$this->iterable->valid()) { - // Resolve the promise if there's nothing left to do. - $this->aggregate->resolve(null); - return true; - } - - return false; - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/promises/src/FulfilledPromise.php b/plugins/automagic-images/vendor/guzzlehttp/promises/src/FulfilledPromise.php deleted file mode 100644 index 98f72a6..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/promises/src/FulfilledPromise.php +++ /dev/null @@ -1,84 +0,0 @@ -value = $value; - } - - public function then( - callable $onFulfilled = null, - callable $onRejected = null - ) { - // Return itself if there is no onFulfilled function. - if (!$onFulfilled) { - return $this; - } - - $queue = Utils::queue(); - $p = new Promise([$queue, 'run']); - $value = $this->value; - $queue->add(static function () use ($p, $value, $onFulfilled) { - if (Is::pending($p)) { - try { - $p->resolve($onFulfilled($value)); - } catch (\Throwable $e) { - $p->reject($e); - } catch (\Exception $e) { - $p->reject($e); - } - } - }); - - return $p; - } - - public function otherwise(callable $onRejected) - { - return $this->then(null, $onRejected); - } - - public function wait($unwrap = true, $defaultDelivery = null) - { - return $unwrap ? $this->value : null; - } - - public function getState() - { - return self::FULFILLED; - } - - public function resolve($value) - { - if ($value !== $this->value) { - throw new \LogicException("Cannot resolve a fulfilled promise"); - } - } - - public function reject($reason) - { - throw new \LogicException("Cannot reject a fulfilled promise"); - } - - public function cancel() - { - // pass - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/promises/src/Is.php b/plugins/automagic-images/vendor/guzzlehttp/promises/src/Is.php deleted file mode 100644 index c3ed8d0..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/promises/src/Is.php +++ /dev/null @@ -1,46 +0,0 @@ -getState() === PromiseInterface::PENDING; - } - - /** - * Returns true if a promise is fulfilled or rejected. - * - * @return bool - */ - public static function settled(PromiseInterface $promise) - { - return $promise->getState() !== PromiseInterface::PENDING; - } - - /** - * Returns true if a promise is fulfilled. - * - * @return bool - */ - public static function fulfilled(PromiseInterface $promise) - { - return $promise->getState() === PromiseInterface::FULFILLED; - } - - /** - * Returns true if a promise is rejected. - * - * @return bool - */ - public static function rejected(PromiseInterface $promise) - { - return $promise->getState() === PromiseInterface::REJECTED; - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/promises/src/Promise.php b/plugins/automagic-images/vendor/guzzlehttp/promises/src/Promise.php deleted file mode 100644 index 7593905..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/promises/src/Promise.php +++ /dev/null @@ -1,278 +0,0 @@ -waitFn = $waitFn; - $this->cancelFn = $cancelFn; - } - - public function then( - callable $onFulfilled = null, - callable $onRejected = null - ) { - if ($this->state === self::PENDING) { - $p = new Promise(null, [$this, 'cancel']); - $this->handlers[] = [$p, $onFulfilled, $onRejected]; - $p->waitList = $this->waitList; - $p->waitList[] = $this; - return $p; - } - - // Return a fulfilled promise and immediately invoke any callbacks. - if ($this->state === self::FULFILLED) { - $promise = Create::promiseFor($this->result); - return $onFulfilled ? $promise->then($onFulfilled) : $promise; - } - - // It's either cancelled or rejected, so return a rejected promise - // and immediately invoke any callbacks. - $rejection = Create::rejectionFor($this->result); - return $onRejected ? $rejection->then(null, $onRejected) : $rejection; - } - - public function otherwise(callable $onRejected) - { - return $this->then(null, $onRejected); - } - - public function wait($unwrap = true) - { - $this->waitIfPending(); - - if ($this->result instanceof PromiseInterface) { - return $this->result->wait($unwrap); - } - if ($unwrap) { - if ($this->state === self::FULFILLED) { - return $this->result; - } - // It's rejected so "unwrap" and throw an exception. - throw Create::exceptionFor($this->result); - } - } - - public function getState() - { - return $this->state; - } - - public function cancel() - { - if ($this->state !== self::PENDING) { - return; - } - - $this->waitFn = $this->waitList = null; - - if ($this->cancelFn) { - $fn = $this->cancelFn; - $this->cancelFn = null; - try { - $fn(); - } catch (\Throwable $e) { - $this->reject($e); - } catch (\Exception $e) { - $this->reject($e); - } - } - - // Reject the promise only if it wasn't rejected in a then callback. - /** @psalm-suppress RedundantCondition */ - if ($this->state === self::PENDING) { - $this->reject(new CancellationException('Promise has been cancelled')); - } - } - - public function resolve($value) - { - $this->settle(self::FULFILLED, $value); - } - - public function reject($reason) - { - $this->settle(self::REJECTED, $reason); - } - - private function settle($state, $value) - { - if ($this->state !== self::PENDING) { - // Ignore calls with the same resolution. - if ($state === $this->state && $value === $this->result) { - return; - } - throw $this->state === $state - ? new \LogicException("The promise is already {$state}.") - : new \LogicException("Cannot change a {$this->state} promise to {$state}"); - } - - if ($value === $this) { - throw new \LogicException('Cannot fulfill or reject a promise with itself'); - } - - // Clear out the state of the promise but stash the handlers. - $this->state = $state; - $this->result = $value; - $handlers = $this->handlers; - $this->handlers = null; - $this->waitList = $this->waitFn = null; - $this->cancelFn = null; - - if (!$handlers) { - return; - } - - // If the value was not a settled promise or a thenable, then resolve - // it in the task queue using the correct ID. - if (!is_object($value) || !method_exists($value, 'then')) { - $id = $state === self::FULFILLED ? 1 : 2; - // It's a success, so resolve the handlers in the queue. - Utils::queue()->add(static function () use ($id, $value, $handlers) { - foreach ($handlers as $handler) { - self::callHandler($id, $value, $handler); - } - }); - } elseif ($value instanceof Promise && Is::pending($value)) { - // We can just merge our handlers onto the next promise. - $value->handlers = array_merge($value->handlers, $handlers); - } else { - // Resolve the handlers when the forwarded promise is resolved. - $value->then( - static function ($value) use ($handlers) { - foreach ($handlers as $handler) { - self::callHandler(1, $value, $handler); - } - }, - static function ($reason) use ($handlers) { - foreach ($handlers as $handler) { - self::callHandler(2, $reason, $handler); - } - } - ); - } - } - - /** - * Call a stack of handlers using a specific callback index and value. - * - * @param int $index 1 (resolve) or 2 (reject). - * @param mixed $value Value to pass to the callback. - * @param array $handler Array of handler data (promise and callbacks). - */ - private static function callHandler($index, $value, array $handler) - { - /** @var PromiseInterface $promise */ - $promise = $handler[0]; - - // The promise may have been cancelled or resolved before placing - // this thunk in the queue. - if (Is::settled($promise)) { - return; - } - - try { - if (isset($handler[$index])) { - /* - * If $f throws an exception, then $handler will be in the exception - * stack trace. Since $handler contains a reference to the callable - * itself we get a circular reference. We clear the $handler - * here to avoid that memory leak. - */ - $f = $handler[$index]; - unset($handler); - $promise->resolve($f($value)); - } elseif ($index === 1) { - // Forward resolution values as-is. - $promise->resolve($value); - } else { - // Forward rejections down the chain. - $promise->reject($value); - } - } catch (\Throwable $reason) { - $promise->reject($reason); - } catch (\Exception $reason) { - $promise->reject($reason); - } - } - - private function waitIfPending() - { - if ($this->state !== self::PENDING) { - return; - } elseif ($this->waitFn) { - $this->invokeWaitFn(); - } elseif ($this->waitList) { - $this->invokeWaitList(); - } else { - // If there's no wait function, then reject the promise. - $this->reject('Cannot wait on a promise that has ' - . 'no internal wait function. You must provide a wait ' - . 'function when constructing the promise to be able to ' - . 'wait on a promise.'); - } - - Utils::queue()->run(); - - /** @psalm-suppress RedundantCondition */ - if ($this->state === self::PENDING) { - $this->reject('Invoking the wait callback did not resolve the promise'); - } - } - - private function invokeWaitFn() - { - try { - $wfn = $this->waitFn; - $this->waitFn = null; - $wfn(true); - } catch (\Exception $reason) { - if ($this->state === self::PENDING) { - // The promise has not been resolved yet, so reject the promise - // with the exception. - $this->reject($reason); - } else { - // The promise was already resolved, so there's a problem in - // the application. - throw $reason; - } - } - } - - private function invokeWaitList() - { - $waitList = $this->waitList; - $this->waitList = null; - - foreach ($waitList as $result) { - do { - $result->waitIfPending(); - $result = $result->result; - } while ($result instanceof Promise); - - if ($result instanceof PromiseInterface) { - $result->wait(false); - } - } - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/promises/src/PromiseInterface.php b/plugins/automagic-images/vendor/guzzlehttp/promises/src/PromiseInterface.php deleted file mode 100644 index e598331..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/promises/src/PromiseInterface.php +++ /dev/null @@ -1,97 +0,0 @@ -reason = $reason; - } - - public function then( - callable $onFulfilled = null, - callable $onRejected = null - ) { - // If there's no onRejected callback then just return self. - if (!$onRejected) { - return $this; - } - - $queue = Utils::queue(); - $reason = $this->reason; - $p = new Promise([$queue, 'run']); - $queue->add(static function () use ($p, $reason, $onRejected) { - if (Is::pending($p)) { - try { - // Return a resolved promise if onRejected does not throw. - $p->resolve($onRejected($reason)); - } catch (\Throwable $e) { - // onRejected threw, so return a rejected promise. - $p->reject($e); - } catch (\Exception $e) { - // onRejected threw, so return a rejected promise. - $p->reject($e); - } - } - }); - - return $p; - } - - public function otherwise(callable $onRejected) - { - return $this->then(null, $onRejected); - } - - public function wait($unwrap = true, $defaultDelivery = null) - { - if ($unwrap) { - throw Create::exceptionFor($this->reason); - } - - return null; - } - - public function getState() - { - return self::REJECTED; - } - - public function resolve($value) - { - throw new \LogicException("Cannot resolve a rejected promise"); - } - - public function reject($reason) - { - if ($reason !== $this->reason) { - throw new \LogicException("Cannot reject a rejected promise"); - } - } - - public function cancel() - { - // pass - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/promises/src/RejectionException.php b/plugins/automagic-images/vendor/guzzlehttp/promises/src/RejectionException.php deleted file mode 100644 index e2f1377..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/promises/src/RejectionException.php +++ /dev/null @@ -1,48 +0,0 @@ -reason = $reason; - - $message = 'The promise was rejected'; - - if ($description) { - $message .= ' with reason: ' . $description; - } elseif (is_string($reason) - || (is_object($reason) && method_exists($reason, '__toString')) - ) { - $message .= ' with reason: ' . $this->reason; - } elseif ($reason instanceof \JsonSerializable) { - $message .= ' with reason: ' - . json_encode($this->reason, JSON_PRETTY_PRINT); - } - - parent::__construct($message); - } - - /** - * Returns the rejection reason. - * - * @return mixed - */ - public function getReason() - { - return $this->reason; - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/promises/src/TaskQueue.php b/plugins/automagic-images/vendor/guzzlehttp/promises/src/TaskQueue.php deleted file mode 100644 index f0fba2c..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/promises/src/TaskQueue.php +++ /dev/null @@ -1,67 +0,0 @@ -run(); - */ -class TaskQueue implements TaskQueueInterface -{ - private $enableShutdown = true; - private $queue = []; - - public function __construct($withShutdown = true) - { - if ($withShutdown) { - register_shutdown_function(function () { - if ($this->enableShutdown) { - // Only run the tasks if an E_ERROR didn't occur. - $err = error_get_last(); - if (!$err || ($err['type'] ^ E_ERROR)) { - $this->run(); - } - } - }); - } - } - - public function isEmpty() - { - return !$this->queue; - } - - public function add(callable $task) - { - $this->queue[] = $task; - } - - public function run() - { - while ($task = array_shift($this->queue)) { - /** @var callable $task */ - $task(); - } - } - - /** - * The task queue will be run and exhausted by default when the process - * exits IFF the exit is not the result of a PHP E_ERROR error. - * - * You can disable running the automatic shutdown of the queue by calling - * this function. If you disable the task queue shutdown process, then you - * MUST either run the task queue (as a result of running your event loop - * or manually using the run() method) or wait on each outstanding promise. - * - * Note: This shutdown will occur before any destructors are triggered. - */ - public function disableShutdown() - { - $this->enableShutdown = false; - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/promises/src/TaskQueueInterface.php b/plugins/automagic-images/vendor/guzzlehttp/promises/src/TaskQueueInterface.php deleted file mode 100644 index 723d4d5..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/promises/src/TaskQueueInterface.php +++ /dev/null @@ -1,24 +0,0 @@ - - * while ($eventLoop->isRunning()) { - * GuzzleHttp\Promise\Utils::queue()->run(); - * } - * - * - * @param TaskQueueInterface $assign Optionally specify a new queue instance. - * - * @return TaskQueueInterface - */ - public static function queue(TaskQueueInterface $assign = null) - { - static $queue; - - if ($assign) { - $queue = $assign; - } elseif (!$queue) { - $queue = new TaskQueue(); - } - - return $queue; - } - - /** - * Adds a function to run in the task queue when it is next `run()` and - * returns a promise that is fulfilled or rejected with the result. - * - * @param callable $task Task function to run. - * - * @return PromiseInterface - */ - public static function task(callable $task) - { - $queue = self::queue(); - $promise = new Promise([$queue, 'run']); - $queue->add(function () use ($task, $promise) { - try { - $promise->resolve($task()); - } catch (\Throwable $e) { - $promise->reject($e); - } catch (\Exception $e) { - $promise->reject($e); - } - }); - - return $promise; - } - - /** - * Synchronously waits on a promise to resolve and returns an inspection - * state array. - * - * Returns a state associative array containing a "state" key mapping to a - * valid promise state. If the state of the promise is "fulfilled", the - * array will contain a "value" key mapping to the fulfilled value of the - * promise. If the promise is rejected, the array will contain a "reason" - * key mapping to the rejection reason of the promise. - * - * @param PromiseInterface $promise Promise or value. - * - * @return array - */ - public static function inspect(PromiseInterface $promise) - { - try { - return [ - 'state' => PromiseInterface::FULFILLED, - 'value' => $promise->wait() - ]; - } catch (RejectionException $e) { - return ['state' => PromiseInterface::REJECTED, 'reason' => $e->getReason()]; - } catch (\Throwable $e) { - return ['state' => PromiseInterface::REJECTED, 'reason' => $e]; - } catch (\Exception $e) { - return ['state' => PromiseInterface::REJECTED, 'reason' => $e]; - } - } - - /** - * Waits on all of the provided promises, but does not unwrap rejected - * promises as thrown exception. - * - * Returns an array of inspection state arrays. - * - * @see inspect for the inspection state array format. - * - * @param PromiseInterface[] $promises Traversable of promises to wait upon. - * - * @return array - */ - public static function inspectAll($promises) - { - $results = []; - foreach ($promises as $key => $promise) { - $results[$key] = inspect($promise); - } - - return $results; - } - - /** - * Waits on all of the provided promises and returns the fulfilled values. - * - * Returns an array that contains the value of each promise (in the same - * order the promises were provided). An exception is thrown if any of the - * promises are rejected. - * - * @param iterable $promises Iterable of PromiseInterface objects to wait on. - * - * @return array - * - * @throws \Exception on error - * @throws \Throwable on error in PHP >=7 - */ - public static function unwrap($promises) - { - $results = []; - foreach ($promises as $key => $promise) { - $results[$key] = $promise->wait(); - } - - return $results; - } - - /** - * Given an array of promises, return a promise that is fulfilled when all - * the items in the array are fulfilled. - * - * The promise's fulfillment value is an array with fulfillment values at - * respective positions to the original array. If any promise in the array - * rejects, the returned promise is rejected with the rejection reason. - * - * @param mixed $promises Promises or values. - * @param bool $recursive If true, resolves new promises that might have been added to the stack during its own resolution. - * - * @return PromiseInterface - */ - public static function all($promises, $recursive = false) - { - $results = []; - $promise = Each::of( - $promises, - function ($value, $idx) use (&$results) { - $results[$idx] = $value; - }, - function ($reason, $idx, Promise $aggregate) { - $aggregate->reject($reason); - } - )->then(function () use (&$results) { - ksort($results); - return $results; - }); - - if (true === $recursive) { - $promise = $promise->then(function ($results) use ($recursive, &$promises) { - foreach ($promises as $promise) { - if (Is::pending($promise)) { - return self::all($promises, $recursive); - } - } - return $results; - }); - } - - return $promise; - } - - /** - * Initiate a competitive race between multiple promises or values (values - * will become immediately fulfilled promises). - * - * When count amount of promises have been fulfilled, the returned promise - * is fulfilled with an array that contains the fulfillment values of the - * winners in order of resolution. - * - * This promise is rejected with a {@see AggregateException} if the number - * of fulfilled promises is less than the desired $count. - * - * @param int $count Total number of promises. - * @param mixed $promises Promises or values. - * - * @return PromiseInterface - */ - public static function some($count, $promises) - { - $results = []; - $rejections = []; - - return Each::of( - $promises, - function ($value, $idx, PromiseInterface $p) use (&$results, $count) { - if (Is::settled($p)) { - return; - } - $results[$idx] = $value; - if (count($results) >= $count) { - $p->resolve(null); - } - }, - function ($reason) use (&$rejections) { - $rejections[] = $reason; - } - )->then( - function () use (&$results, &$rejections, $count) { - if (count($results) !== $count) { - throw new AggregateException( - 'Not enough promises to fulfill count', - $rejections - ); - } - ksort($results); - return array_values($results); - } - ); - } - - /** - * Like some(), with 1 as count. However, if the promise fulfills, the - * fulfillment value is not an array of 1 but the value directly. - * - * @param mixed $promises Promises or values. - * - * @return PromiseInterface - */ - public static function any($promises) - { - return self::some(1, $promises)->then(function ($values) { - return $values[0]; - }); - } - - /** - * Returns a promise that is fulfilled when all of the provided promises have - * been fulfilled or rejected. - * - * The returned promise is fulfilled with an array of inspection state arrays. - * - * @see inspect for the inspection state array format. - * - * @param mixed $promises Promises or values. - * - * @return PromiseInterface - */ - public static function settle($promises) - { - $results = []; - - return Each::of( - $promises, - function ($value, $idx) use (&$results) { - $results[$idx] = ['state' => PromiseInterface::FULFILLED, 'value' => $value]; - }, - function ($reason, $idx) use (&$results) { - $results[$idx] = ['state' => PromiseInterface::REJECTED, 'reason' => $reason]; - } - )->then(function () use (&$results) { - ksort($results); - return $results; - }); - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/promises/src/functions.php b/plugins/automagic-images/vendor/guzzlehttp/promises/src/functions.php deleted file mode 100644 index c03d39d..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/promises/src/functions.php +++ /dev/null @@ -1,363 +0,0 @@ - - * while ($eventLoop->isRunning()) { - * GuzzleHttp\Promise\queue()->run(); - * } - * - * - * @param TaskQueueInterface $assign Optionally specify a new queue instance. - * - * @return TaskQueueInterface - * - * @deprecated queue will be removed in guzzlehttp/promises:2.0. Use Utils::queue instead. - */ -function queue(TaskQueueInterface $assign = null) -{ - return Utils::queue($assign); -} - -/** - * Adds a function to run in the task queue when it is next `run()` and returns - * a promise that is fulfilled or rejected with the result. - * - * @param callable $task Task function to run. - * - * @return PromiseInterface - * - * @deprecated task will be removed in guzzlehttp/promises:2.0. Use Utils::task instead. - */ -function task(callable $task) -{ - return Utils::task($task); -} - -/** - * Creates a promise for a value if the value is not a promise. - * - * @param mixed $value Promise or value. - * - * @return PromiseInterface - * - * @deprecated promise_for will be removed in guzzlehttp/promises:2.0. Use Create::promiseFor instead. - */ -function promise_for($value) -{ - return Create::promiseFor($value); -} - -/** - * Creates a rejected promise for a reason if the reason is not a promise. If - * the provided reason is a promise, then it is returned as-is. - * - * @param mixed $reason Promise or reason. - * - * @return PromiseInterface - * - * @deprecated rejection_for will be removed in guzzlehttp/promises:2.0. Use Create::rejectionFor instead. - */ -function rejection_for($reason) -{ - return Create::rejectionFor($reason); -} - -/** - * Create an exception for a rejected promise value. - * - * @param mixed $reason - * - * @return \Exception|\Throwable - * - * @deprecated exception_for will be removed in guzzlehttp/promises:2.0. Use Create::exceptionFor instead. - */ -function exception_for($reason) -{ - return Create::exceptionFor($reason); -} - -/** - * Returns an iterator for the given value. - * - * @param mixed $value - * - * @return \Iterator - * - * @deprecated iter_for will be removed in guzzlehttp/promises:2.0. Use Create::iterFor instead. - */ -function iter_for($value) -{ - return Create::iterFor($value); -} - -/** - * Synchronously waits on a promise to resolve and returns an inspection state - * array. - * - * Returns a state associative array containing a "state" key mapping to a - * valid promise state. If the state of the promise is "fulfilled", the array - * will contain a "value" key mapping to the fulfilled value of the promise. If - * the promise is rejected, the array will contain a "reason" key mapping to - * the rejection reason of the promise. - * - * @param PromiseInterface $promise Promise or value. - * - * @return array - * - * @deprecated inspect will be removed in guzzlehttp/promises:2.0. Use Utils::inspect instead. - */ -function inspect(PromiseInterface $promise) -{ - return Utils::inspect($promise); -} - -/** - * Waits on all of the provided promises, but does not unwrap rejected promises - * as thrown exception. - * - * Returns an array of inspection state arrays. - * - * @see inspect for the inspection state array format. - * - * @param PromiseInterface[] $promises Traversable of promises to wait upon. - * - * @return array - * - * @deprecated inspect will be removed in guzzlehttp/promises:2.0. Use Utils::inspectAll instead. - */ -function inspect_all($promises) -{ - return Utils::inspectAll($promises); -} - -/** - * Waits on all of the provided promises and returns the fulfilled values. - * - * Returns an array that contains the value of each promise (in the same order - * the promises were provided). An exception is thrown if any of the promises - * are rejected. - * - * @param iterable $promises Iterable of PromiseInterface objects to wait on. - * - * @return array - * - * @throws \Exception on error - * @throws \Throwable on error in PHP >=7 - * - * @deprecated unwrap will be removed in guzzlehttp/promises:2.0. Use Utils::unwrap instead. - */ -function unwrap($promises) -{ - return Utils::unwrap($promises); -} - -/** - * Given an array of promises, return a promise that is fulfilled when all the - * items in the array are fulfilled. - * - * The promise's fulfillment value is an array with fulfillment values at - * respective positions to the original array. If any promise in the array - * rejects, the returned promise is rejected with the rejection reason. - * - * @param mixed $promises Promises or values. - * @param bool $recursive If true, resolves new promises that might have been added to the stack during its own resolution. - * - * @return PromiseInterface - * - * @deprecated all will be removed in guzzlehttp/promises:2.0. Use Utils::all instead. - */ -function all($promises, $recursive = false) -{ - return Utils::all($promises, $recursive); -} - -/** - * Initiate a competitive race between multiple promises or values (values will - * become immediately fulfilled promises). - * - * When count amount of promises have been fulfilled, the returned promise is - * fulfilled with an array that contains the fulfillment values of the winners - * in order of resolution. - * - * This promise is rejected with a {@see AggregateException} if the number of - * fulfilled promises is less than the desired $count. - * - * @param int $count Total number of promises. - * @param mixed $promises Promises or values. - * - * @return PromiseInterface - * - * @deprecated some will be removed in guzzlehttp/promises:2.0. Use Utils::some instead. - */ -function some($count, $promises) -{ - return Utils::some($count, $promises); -} - -/** - * Like some(), with 1 as count. However, if the promise fulfills, the - * fulfillment value is not an array of 1 but the value directly. - * - * @param mixed $promises Promises or values. - * - * @return PromiseInterface - * - * @deprecated any will be removed in guzzlehttp/promises:2.0. Use Utils::any instead. - */ -function any($promises) -{ - return Utils::any($promises); -} - -/** - * Returns a promise that is fulfilled when all of the provided promises have - * been fulfilled or rejected. - * - * The returned promise is fulfilled with an array of inspection state arrays. - * - * @see inspect for the inspection state array format. - * - * @param mixed $promises Promises or values. - * - * @return PromiseInterface - * - * @deprecated settle will be removed in guzzlehttp/promises:2.0. Use Utils::settle instead. - */ -function settle($promises) -{ - return Utils::settle($promises); -} - -/** - * Given an iterator that yields promises or values, returns a promise that is - * fulfilled with a null value when the iterator has been consumed or the - * aggregate promise has been fulfilled or rejected. - * - * $onFulfilled is a function that accepts the fulfilled value, iterator index, - * and the aggregate promise. The callback can invoke any necessary side - * effects and choose to resolve or reject the aggregate if needed. - * - * $onRejected is a function that accepts the rejection reason, iterator index, - * and the aggregate promise. The callback can invoke any necessary side - * effects and choose to resolve or reject the aggregate if needed. - * - * @param mixed $iterable Iterator or array to iterate over. - * @param callable $onFulfilled - * @param callable $onRejected - * - * @return PromiseInterface - * - * @deprecated each will be removed in guzzlehttp/promises:2.0. Use Each::of instead. - */ -function each( - $iterable, - callable $onFulfilled = null, - callable $onRejected = null -) { - return Each::of($iterable, $onFulfilled, $onRejected); -} - -/** - * Like each, but only allows a certain number of outstanding promises at any - * given time. - * - * $concurrency may be an integer or a function that accepts the number of - * pending promises and returns a numeric concurrency limit value to allow for - * dynamic a concurrency size. - * - * @param mixed $iterable - * @param int|callable $concurrency - * @param callable $onFulfilled - * @param callable $onRejected - * - * @return PromiseInterface - * - * @deprecated each_limit will be removed in guzzlehttp/promises:2.0. Use Each::ofLimit instead. - */ -function each_limit( - $iterable, - $concurrency, - callable $onFulfilled = null, - callable $onRejected = null -) { - return Each::ofLimit($iterable, $concurrency, $onFulfilled, $onRejected); -} - -/** - * Like each_limit, but ensures that no promise in the given $iterable argument - * is rejected. If any promise is rejected, then the aggregate promise is - * rejected with the encountered rejection. - * - * @param mixed $iterable - * @param int|callable $concurrency - * @param callable $onFulfilled - * - * @return PromiseInterface - * - * @deprecated each_limit_all will be removed in guzzlehttp/promises:2.0. Use Each::ofLimitAll instead. - */ -function each_limit_all( - $iterable, - $concurrency, - callable $onFulfilled = null -) { - return Each::ofLimitAll($iterable, $concurrency, $onFulfilled); -} - -/** - * Returns true if a promise is fulfilled. - * - * @return bool - * - * @deprecated is_fulfilled will be removed in guzzlehttp/promises:2.0. Use Is::fulfilled instead. - */ -function is_fulfilled(PromiseInterface $promise) -{ - return Is::fulfilled($promise); -} - -/** - * Returns true if a promise is rejected. - * - * @return bool - * - * @deprecated is_rejected will be removed in guzzlehttp/promises:2.0. Use Is::rejected instead. - */ -function is_rejected(PromiseInterface $promise) -{ - return Is::rejected($promise); -} - -/** - * Returns true if a promise is fulfilled or rejected. - * - * @return bool - * - * @deprecated is_settled will be removed in guzzlehttp/promises:2.0. Use Is::settled instead. - */ -function is_settled(PromiseInterface $promise) -{ - return Is::settled($promise); -} - -/** - * Create a new coroutine. - * - * @see Coroutine - * - * @return PromiseInterface - * - * @deprecated coroutine will be removed in guzzlehttp/promises:2.0. Use Coroutine::of instead. - */ -function coroutine(callable $generatorFn) -{ - return Coroutine::of($generatorFn); -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/promises/src/functions_include.php b/plugins/automagic-images/vendor/guzzlehttp/promises/src/functions_include.php deleted file mode 100644 index 34cd171..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/promises/src/functions_include.php +++ /dev/null @@ -1,6 +0,0 @@ -withPath('foo')->withHost('example.com')` will throw an exception - because the path of a URI with an authority must start with a slash "/" or be empty - - `(new Uri())->withScheme('http')` will return `'http://localhost'` - -### Deprecated - -- `Uri::resolve` in favor of `UriResolver::resolve` -- `Uri::removeDotSegments` in favor of `UriResolver::removeDotSegments` - -### Fixed - -- `Stream::read` when length parameter <= 0. -- `copy_to_stream` reads bytes in chunks instead of `maxLen` into memory. -- `ServerRequest::getUriFromGlobals` when `Host` header contains port. -- Compatibility of URIs with `file` scheme and empty host. - - -## [1.3.1] - 2016-06-25 - -### Fixed - -- `Uri::__toString` for network path references, e.g. `//example.org`. -- Missing lowercase normalization for host. -- Handling of URI components in case they are `'0'` in a lot of places, - e.g. as a user info password. -- `Uri::withAddedHeader` to correctly merge headers with different case. -- Trimming of header values in `Uri::withAddedHeader`. Header values may - be surrounded by whitespace which should be ignored according to RFC 7230 - Section 3.2.4. This does not apply to header names. -- `Uri::withAddedHeader` with an array of header values. -- `Uri::resolve` when base path has no slash and handling of fragment. -- Handling of encoding in `Uri::with(out)QueryValue` so one can pass the - key/value both in encoded as well as decoded form to those methods. This is - consistent with withPath, withQuery etc. -- `ServerRequest::withoutAttribute` when attribute value is null. - - -## [1.3.0] - 2016-04-13 - -### Added - -- Remaining interfaces needed for full PSR7 compatibility - (ServerRequestInterface, UploadedFileInterface, etc.). -- Support for stream_for from scalars. - -### Changed - -- Can now extend Uri. - -### Fixed -- A bug in validating request methods by making it more permissive. - - -## [1.2.3] - 2016-02-18 - -### Fixed - -- Support in `GuzzleHttp\Psr7\CachingStream` for seeking forward on remote - streams, which can sometimes return fewer bytes than requested with `fread`. -- Handling of gzipped responses with FNAME headers. - - -## [1.2.2] - 2016-01-22 - -### Added - -- Support for URIs without any authority. -- Support for HTTP 451 'Unavailable For Legal Reasons.' -- Support for using '0' as a filename. -- Support for including non-standard ports in Host headers. - - -## [1.2.1] - 2015-11-02 - -### Changes - -- Now supporting negative offsets when seeking to SEEK_END. - - -## [1.2.0] - 2015-08-15 - -### Changed - -- Body as `"0"` is now properly added to a response. -- Now allowing forward seeking in CachingStream. -- Now properly parsing HTTP requests that contain proxy targets in - `parse_request`. -- functions.php is now conditionally required. -- user-info is no longer dropped when resolving URIs. - - -## [1.1.0] - 2015-06-24 - -### Changed - -- URIs can now be relative. -- `multipart/form-data` headers are now overridden case-insensitively. -- URI paths no longer encode the following characters because they are allowed - in URIs: "(", ")", "*", "!", "'" -- A port is no longer added to a URI when the scheme is missing and no port is - present. - - -## 1.0.0 - 2015-05-19 - -Initial release. - -Currently unsupported: - -- `Psr\Http\Message\ServerRequestInterface` -- `Psr\Http\Message\UploadedFileInterface` - - - -[1.6.0]: https://github.com/guzzle/psr7/compare/1.5.2...1.6.0 -[1.5.2]: https://github.com/guzzle/psr7/compare/1.5.1...1.5.2 -[1.5.1]: https://github.com/guzzle/psr7/compare/1.5.0...1.5.1 -[1.5.0]: https://github.com/guzzle/psr7/compare/1.4.2...1.5.0 -[1.4.2]: https://github.com/guzzle/psr7/compare/1.4.1...1.4.2 -[1.4.1]: https://github.com/guzzle/psr7/compare/1.4.0...1.4.1 -[1.4.0]: https://github.com/guzzle/psr7/compare/1.3.1...1.4.0 -[1.3.1]: https://github.com/guzzle/psr7/compare/1.3.0...1.3.1 -[1.3.0]: https://github.com/guzzle/psr7/compare/1.2.3...1.3.0 -[1.2.3]: https://github.com/guzzle/psr7/compare/1.2.2...1.2.3 -[1.2.2]: https://github.com/guzzle/psr7/compare/1.2.1...1.2.2 -[1.2.1]: https://github.com/guzzle/psr7/compare/1.2.0...1.2.1 -[1.2.0]: https://github.com/guzzle/psr7/compare/1.1.0...1.2.0 -[1.1.0]: https://github.com/guzzle/psr7/compare/1.0.0...1.1.0 diff --git a/plugins/automagic-images/vendor/guzzlehttp/psr7/LICENSE b/plugins/automagic-images/vendor/guzzlehttp/psr7/LICENSE deleted file mode 100644 index 581d95f..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/psr7/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2015 Michael Dowling, https://github.com/mtdowling - -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/plugins/automagic-images/vendor/guzzlehttp/psr7/README.md b/plugins/automagic-images/vendor/guzzlehttp/psr7/README.md deleted file mode 100644 index acfabfd..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/psr7/README.md +++ /dev/null @@ -1,809 +0,0 @@ -# PSR-7 Message Implementation - -This repository contains a full [PSR-7](http://www.php-fig.org/psr/psr-7/) -message implementation, several stream decorators, and some helpful -functionality like query string parsing. - - -[![Build Status](https://travis-ci.org/guzzle/psr7.svg?branch=master)](https://travis-ci.org/guzzle/psr7) - - -# Stream implementation - -This package comes with a number of stream implementations and stream -decorators. - - -## AppendStream - -`GuzzleHttp\Psr7\AppendStream` - -Reads from multiple streams, one after the other. - -```php -use GuzzleHttp\Psr7; - -$a = Psr7\Utils::streamFor('abc, '); -$b = Psr7\Utils::streamFor('123.'); -$composed = new Psr7\AppendStream([$a, $b]); - -$composed->addStream(Psr7\Utils::streamFor(' Above all listen to me')); - -echo $composed; // abc, 123. Above all listen to me. -``` - - -## BufferStream - -`GuzzleHttp\Psr7\BufferStream` - -Provides a buffer stream that can be written to fill a buffer, and read -from to remove bytes from the buffer. - -This stream returns a "hwm" metadata value that tells upstream consumers -what the configured high water mark of the stream is, or the maximum -preferred size of the buffer. - -```php -use GuzzleHttp\Psr7; - -// When more than 1024 bytes are in the buffer, it will begin returning -// false to writes. This is an indication that writers should slow down. -$buffer = new Psr7\BufferStream(1024); -``` - - -## CachingStream - -The CachingStream is used to allow seeking over previously read bytes on -non-seekable streams. This can be useful when transferring a non-seekable -entity body fails due to needing to rewind the stream (for example, resulting -from a redirect). Data that is read from the remote stream will be buffered in -a PHP temp stream so that previously read bytes are cached first in memory, -then on disk. - -```php -use GuzzleHttp\Psr7; - -$original = Psr7\Utils::streamFor(fopen('http://www.google.com', 'r')); -$stream = new Psr7\CachingStream($original); - -$stream->read(1024); -echo $stream->tell(); -// 1024 - -$stream->seek(0); -echo $stream->tell(); -// 0 -``` - - -## DroppingStream - -`GuzzleHttp\Psr7\DroppingStream` - -Stream decorator that begins dropping data once the size of the underlying -stream becomes too full. - -```php -use GuzzleHttp\Psr7; - -// Create an empty stream -$stream = Psr7\Utils::streamFor(); - -// Start dropping data when the stream has more than 10 bytes -$dropping = new Psr7\DroppingStream($stream, 10); - -$dropping->write('01234567890123456789'); -echo $stream; // 0123456789 -``` - - -## FnStream - -`GuzzleHttp\Psr7\FnStream` - -Compose stream implementations based on a hash of functions. - -Allows for easy testing and extension of a provided stream without needing -to create a concrete class for a simple extension point. - -```php - -use GuzzleHttp\Psr7; - -$stream = Psr7\Utils::streamFor('hi'); -$fnStream = Psr7\FnStream::decorate($stream, [ - 'rewind' => function () use ($stream) { - echo 'About to rewind - '; - $stream->rewind(); - echo 'rewound!'; - } -]); - -$fnStream->rewind(); -// Outputs: About to rewind - rewound! -``` - - -## InflateStream - -`GuzzleHttp\Psr7\InflateStream` - -Uses PHP's zlib.inflate filter to inflate deflate or gzipped content. - -This stream decorator skips the first 10 bytes of the given stream to remove -the gzip header, converts the provided stream to a PHP stream resource, -then appends the zlib.inflate filter. The stream is then converted back -to a Guzzle stream resource to be used as a Guzzle stream. - - -## LazyOpenStream - -`GuzzleHttp\Psr7\LazyOpenStream` - -Lazily reads or writes to a file that is opened only after an IO operation -take place on the stream. - -```php -use GuzzleHttp\Psr7; - -$stream = new Psr7\LazyOpenStream('/path/to/file', 'r'); -// The file has not yet been opened... - -echo $stream->read(10); -// The file is opened and read from only when needed. -``` - - -## LimitStream - -`GuzzleHttp\Psr7\LimitStream` - -LimitStream can be used to read a subset or slice of an existing stream object. -This can be useful for breaking a large file into smaller pieces to be sent in -chunks (e.g. Amazon S3's multipart upload API). - -```php -use GuzzleHttp\Psr7; - -$original = Psr7\Utils::streamFor(fopen('/tmp/test.txt', 'r+')); -echo $original->getSize(); -// >>> 1048576 - -// Limit the size of the body to 1024 bytes and start reading from byte 2048 -$stream = new Psr7\LimitStream($original, 1024, 2048); -echo $stream->getSize(); -// >>> 1024 -echo $stream->tell(); -// >>> 0 -``` - - -## MultipartStream - -`GuzzleHttp\Psr7\MultipartStream` - -Stream that when read returns bytes for a streaming multipart or -multipart/form-data stream. - - -## NoSeekStream - -`GuzzleHttp\Psr7\NoSeekStream` - -NoSeekStream wraps a stream and does not allow seeking. - -```php -use GuzzleHttp\Psr7; - -$original = Psr7\Utils::streamFor('foo'); -$noSeek = new Psr7\NoSeekStream($original); - -echo $noSeek->read(3); -// foo -var_export($noSeek->isSeekable()); -// false -$noSeek->seek(0); -var_export($noSeek->read(3)); -// NULL -``` - - -## PumpStream - -`GuzzleHttp\Psr7\PumpStream` - -Provides a read only stream that pumps data from a PHP callable. - -When invoking the provided callable, the PumpStream will pass the amount of -data requested to read to the callable. The callable can choose to ignore -this value and return fewer or more bytes than requested. Any extra data -returned by the provided callable is buffered internally until drained using -the read() function of the PumpStream. The provided callable MUST return -false when there is no more data to read. - - -## Implementing stream decorators - -Creating a stream decorator is very easy thanks to the -`GuzzleHttp\Psr7\StreamDecoratorTrait`. This trait provides methods that -implement `Psr\Http\Message\StreamInterface` by proxying to an underlying -stream. Just `use` the `StreamDecoratorTrait` and implement your custom -methods. - -For example, let's say we wanted to call a specific function each time the last -byte is read from a stream. This could be implemented by overriding the -`read()` method. - -```php -use Psr\Http\Message\StreamInterface; -use GuzzleHttp\Psr7\StreamDecoratorTrait; - -class EofCallbackStream implements StreamInterface -{ - use StreamDecoratorTrait; - - private $callback; - - public function __construct(StreamInterface $stream, callable $cb) - { - $this->stream = $stream; - $this->callback = $cb; - } - - public function read($length) - { - $result = $this->stream->read($length); - - // Invoke the callback when EOF is hit. - if ($this->eof()) { - call_user_func($this->callback); - } - - return $result; - } -} -``` - -This decorator could be added to any existing stream and used like so: - -```php -use GuzzleHttp\Psr7; - -$original = Psr7\Utils::streamFor('foo'); - -$eofStream = new EofCallbackStream($original, function () { - echo 'EOF!'; -}); - -$eofStream->read(2); -$eofStream->read(1); -// echoes "EOF!" -$eofStream->seek(0); -$eofStream->read(3); -// echoes "EOF!" -``` - - -## PHP StreamWrapper - -You can use the `GuzzleHttp\Psr7\StreamWrapper` class if you need to use a -PSR-7 stream as a PHP stream resource. - -Use the `GuzzleHttp\Psr7\StreamWrapper::getResource()` method to create a PHP -stream from a PSR-7 stream. - -```php -use GuzzleHttp\Psr7\StreamWrapper; - -$stream = GuzzleHttp\Psr7\Utils::streamFor('hello!'); -$resource = StreamWrapper::getResource($stream); -echo fread($resource, 6); // outputs hello! -``` - - -# Static API - -There are various static methods available under the `GuzzleHttp\Psr7` namespace. - - -## `GuzzleHttp\Psr7\Message::toString` - -`public static function toString(MessageInterface $message): string` - -Returns the string representation of an HTTP message. - -```php -$request = new GuzzleHttp\Psr7\Request('GET', 'http://example.com'); -echo GuzzleHttp\Psr7\Message::toString($request); -``` - - -## `GuzzleHttp\Psr7\Message::bodySummary` - -`public static function bodySummary(MessageInterface $message, int $truncateAt = 120): string|null` - -Get a short summary of the message body. - -Will return `null` if the response is not printable. - - -## `GuzzleHttp\Psr7\Message::rewindBody` - -`public static function rewindBody(MessageInterface $message): void` - -Attempts to rewind a message body and throws an exception on failure. - -The body of the message will only be rewound if a call to `tell()` -returns a value other than `0`. - - -## `GuzzleHttp\Psr7\Message::parseMessage` - -`public static function parseMessage(string $message): array` - -Parses an HTTP message into an associative array. - -The array contains the "start-line" key containing the start line of -the message, "headers" key containing an associative array of header -array values, and a "body" key containing the body of the message. - - -## `GuzzleHttp\Psr7\Message::parseRequestUri` - -`public static function parseRequestUri(string $path, array $headers): string` - -Constructs a URI for an HTTP request message. - - -## `GuzzleHttp\Psr7\Message::parseRequest` - -`public static function parseRequest(string $message): Request` - -Parses a request message string into a request object. - - -## `GuzzleHttp\Psr7\Message::parseResponse` - -`public static function parseResponse(string $message): Response` - -Parses a response message string into a response object. - - -## `GuzzleHttp\Psr7\Header::parse` - -`public static function parse(string|array $header): array` - -Parse an array of header values containing ";" separated data into an -array of associative arrays representing the header key value pair data -of the header. When a parameter does not contain a value, but just -contains a key, this function will inject a key with a '' string value. - - -## `GuzzleHttp\Psr7\Header::normalize` - -`public static function normalize(string|array $header): array` - -Converts an array of header values that may contain comma separated -headers into an array of headers with no comma separated values. - - -## `GuzzleHttp\Psr7\Query::parse` - -`public static function parse(string $str, int|bool $urlEncoding = true): array` - -Parse a query string into an associative array. - -If multiple values are found for the same key, the value of that key -value pair will become an array. This function does not parse nested -PHP style arrays into an associative array (e.g., `foo[a]=1&foo[b]=2` -will be parsed into `['foo[a]' => '1', 'foo[b]' => '2'])`. - - -## `GuzzleHttp\Psr7\Query::build` - -`public static function build(array $params, int|false $encoding = PHP_QUERY_RFC3986): string` - -Build a query string from an array of key value pairs. - -This function can use the return value of `parse()` to build a query -string. This function does not modify the provided keys when an array is -encountered (like `http_build_query()` would). - - -## `GuzzleHttp\Psr7\Utils::caselessRemove` - -`public static function caselessRemove(iterable $keys, $keys, array $data): array` - -Remove the items given by the keys, case insensitively from the data. - - -## `GuzzleHttp\Psr7\Utils::copyToStream` - -`public static function copyToStream(StreamInterface $source, StreamInterface $dest, int $maxLen = -1): void` - -Copy the contents of a stream into another stream until the given number -of bytes have been read. - - -## `GuzzleHttp\Psr7\Utils::copyToString` - -`public static function copyToString(StreamInterface $stream, int $maxLen = -1): string` - -Copy the contents of a stream into a string until the given number of -bytes have been read. - - -## `GuzzleHttp\Psr7\Utils::hash` - -`public static function hash(StreamInterface $stream, string $algo, bool $rawOutput = false): string` - -Calculate a hash of a stream. - -This method reads the entire stream to calculate a rolling hash, based on -PHP's `hash_init` functions. - - -## `GuzzleHttp\Psr7\Utils::modifyRequest` - -`public static function modifyRequest(RequestInterface $request, array $changes): RequestInterface` - -Clone and modify a request with the given changes. - -This method is useful for reducing the number of clones needed to mutate -a message. - -- method: (string) Changes the HTTP method. -- set_headers: (array) Sets the given headers. -- remove_headers: (array) Remove the given headers. -- body: (mixed) Sets the given body. -- uri: (UriInterface) Set the URI. -- query: (string) Set the query string value of the URI. -- version: (string) Set the protocol version. - - -## `GuzzleHttp\Psr7\Utils::readLine` - -`public static function readLine(StreamInterface $stream, int $maxLength = null): string` - -Read a line from the stream up to the maximum allowed buffer length. - - -## `GuzzleHttp\Psr7\Utils::streamFor` - -`public static function streamFor(resource|string|null|int|float|bool|StreamInterface|callable|\Iterator $resource = '', array $options = []): StreamInterface` - -Create a new stream based on the input type. - -Options is an associative array that can contain the following keys: - -- metadata: Array of custom metadata. -- size: Size of the stream. - -This method accepts the following `$resource` types: - -- `Psr\Http\Message\StreamInterface`: Returns the value as-is. -- `string`: Creates a stream object that uses the given string as the contents. -- `resource`: Creates a stream object that wraps the given PHP stream resource. -- `Iterator`: If the provided value implements `Iterator`, then a read-only - stream object will be created that wraps the given iterable. Each time the - stream is read from, data from the iterator will fill a buffer and will be - continuously called until the buffer is equal to the requested read size. - Subsequent read calls will first read from the buffer and then call `next` - on the underlying iterator until it is exhausted. -- `object` with `__toString()`: If the object has the `__toString()` method, - the object will be cast to a string and then a stream will be returned that - uses the string value. -- `NULL`: When `null` is passed, an empty stream object is returned. -- `callable` When a callable is passed, a read-only stream object will be - created that invokes the given callable. The callable is invoked with the - number of suggested bytes to read. The callable can return any number of - bytes, but MUST return `false` when there is no more data to return. The - stream object that wraps the callable will invoke the callable until the - number of requested bytes are available. Any additional bytes will be - buffered and used in subsequent reads. - -```php -$stream = GuzzleHttp\Psr7\Utils::streamFor('foo'); -$stream = GuzzleHttp\Psr7\Utils::streamFor(fopen('/path/to/file', 'r')); - -$generator = function ($bytes) { - for ($i = 0; $i < $bytes; $i++) { - yield ' '; - } -} - -$stream = GuzzleHttp\Psr7\Utils::streamFor($generator(100)); -``` - - -## `GuzzleHttp\Psr7\Utils::tryFopen` - -`public static function tryFopen(string $filename, string $mode): resource` - -Safely opens a PHP stream resource using a filename. - -When fopen fails, PHP normally raises a warning. This function adds an -error handler that checks for errors and throws an exception instead. - - -## `GuzzleHttp\Psr7\Utils::uriFor` - -`public static function uriFor(string|UriInterface $uri): UriInterface` - -Returns a UriInterface for the given value. - -This function accepts a string or UriInterface and returns a -UriInterface for the given value. If the value is already a -UriInterface, it is returned as-is. - - -## `GuzzleHttp\Psr7\MimeType::fromFilename` - -`public static function fromFilename(string $filename): string|null` - -Determines the mimetype of a file by looking at its extension. - - -## `GuzzleHttp\Psr7\MimeType::fromExtension` - -`public static function fromExtension(string $extension): string|null` - -Maps a file extensions to a mimetype. - - -## Upgrading from Function API - -The static API was first introduced in 1.7.0, in order to mitigate problems with functions conflicting between global and local copies of the package. The function API will be removed in 2.0.0. A migration table has been provided here for your convenience: - -| Original Function | Replacement Method | -|----------------|----------------| -| `str` | `Message::toString` | -| `uri_for` | `Utils::uriFor` | -| `stream_for` | `Utils::streamFor` | -| `parse_header` | `Header::parse` | -| `normalize_header` | `Header::normalize` | -| `modify_request` | `Utils::modifyRequest` | -| `rewind_body` | `Message::rewindBody` | -| `try_fopen` | `Utils::tryFopen` | -| `copy_to_string` | `Utils::copyToString` | -| `copy_to_stream` | `Utils::copyToStream` | -| `hash` | `Utils::hash` | -| `readline` | `Utils::readLine` | -| `parse_request` | `Message::parseRequest` | -| `parse_response` | `Message::parseResponse` | -| `parse_query` | `Query::parse` | -| `build_query` | `Query::build` | -| `mimetype_from_filename` | `MimeType::fromFilename` | -| `mimetype_from_extension` | `MimeType::fromExtension` | -| `_parse_message` | `Message::parseMessage` | -| `_parse_request_uri` | `Message::parseRequestUri` | -| `get_message_body_summary` | `Message::bodySummary` | -| `_caseless_remove` | `Utils::caselessRemove` | - - -# Additional URI Methods - -Aside from the standard `Psr\Http\Message\UriInterface` implementation in form of the `GuzzleHttp\Psr7\Uri` class, -this library also provides additional functionality when working with URIs as static methods. - -## URI Types - -An instance of `Psr\Http\Message\UriInterface` can either be an absolute URI or a relative reference. -An absolute URI has a scheme. A relative reference is used to express a URI relative to another URI, -the base URI. Relative references can be divided into several forms according to -[RFC 3986 Section 4.2](https://tools.ietf.org/html/rfc3986#section-4.2): - -- network-path references, e.g. `//example.com/path` -- absolute-path references, e.g. `/path` -- relative-path references, e.g. `subpath` - -The following methods can be used to identify the type of the URI. - -### `GuzzleHttp\Psr7\Uri::isAbsolute` - -`public static function isAbsolute(UriInterface $uri): bool` - -Whether the URI is absolute, i.e. it has a scheme. - -### `GuzzleHttp\Psr7\Uri::isNetworkPathReference` - -`public static function isNetworkPathReference(UriInterface $uri): bool` - -Whether the URI is a network-path reference. A relative reference that begins with two slash characters is -termed an network-path reference. - -### `GuzzleHttp\Psr7\Uri::isAbsolutePathReference` - -`public static function isAbsolutePathReference(UriInterface $uri): bool` - -Whether the URI is a absolute-path reference. A relative reference that begins with a single slash character is -termed an absolute-path reference. - -### `GuzzleHttp\Psr7\Uri::isRelativePathReference` - -`public static function isRelativePathReference(UriInterface $uri): bool` - -Whether the URI is a relative-path reference. A relative reference that does not begin with a slash character is -termed a relative-path reference. - -### `GuzzleHttp\Psr7\Uri::isSameDocumentReference` - -`public static function isSameDocumentReference(UriInterface $uri, UriInterface $base = null): bool` - -Whether the URI is a same-document reference. A same-document reference refers to a URI that is, aside from its -fragment component, identical to the base URI. When no base URI is given, only an empty URI reference -(apart from its fragment) is considered a same-document reference. - -## URI Components - -Additional methods to work with URI components. - -### `GuzzleHttp\Psr7\Uri::isDefaultPort` - -`public static function isDefaultPort(UriInterface $uri): bool` - -Whether the URI has the default port of the current scheme. `Psr\Http\Message\UriInterface::getPort` may return null -or the standard port. This method can be used independently of the implementation. - -### `GuzzleHttp\Psr7\Uri::composeComponents` - -`public static function composeComponents($scheme, $authority, $path, $query, $fragment): string` - -Composes a URI reference string from its various components according to -[RFC 3986 Section 5.3](https://tools.ietf.org/html/rfc3986#section-5.3). Usually this method does not need to be called -manually but instead is used indirectly via `Psr\Http\Message\UriInterface::__toString`. - -### `GuzzleHttp\Psr7\Uri::fromParts` - -`public static function fromParts(array $parts): UriInterface` - -Creates a URI from a hash of [`parse_url`](http://php.net/manual/en/function.parse-url.php) components. - - -### `GuzzleHttp\Psr7\Uri::withQueryValue` - -`public static function withQueryValue(UriInterface $uri, $key, $value): UriInterface` - -Creates a new URI with a specific query string value. Any existing query string values that exactly match the -provided key are removed and replaced with the given key value pair. A value of null will set the query string -key without a value, e.g. "key" instead of "key=value". - -### `GuzzleHttp\Psr7\Uri::withQueryValues` - -`public static function withQueryValues(UriInterface $uri, array $keyValueArray): UriInterface` - -Creates a new URI with multiple query string values. It has the same behavior as `withQueryValue()` but for an -associative array of key => value. - -### `GuzzleHttp\Psr7\Uri::withoutQueryValue` - -`public static function withoutQueryValue(UriInterface $uri, $key): UriInterface` - -Creates a new URI with a specific query string value removed. Any existing query string values that exactly match the -provided key are removed. - -## Reference Resolution - -`GuzzleHttp\Psr7\UriResolver` provides methods to resolve a URI reference in the context of a base URI according -to [RFC 3986 Section 5](https://tools.ietf.org/html/rfc3986#section-5). This is for example also what web browsers -do when resolving a link in a website based on the current request URI. - -### `GuzzleHttp\Psr7\UriResolver::resolve` - -`public static function resolve(UriInterface $base, UriInterface $rel): UriInterface` - -Converts the relative URI into a new URI that is resolved against the base URI. - -### `GuzzleHttp\Psr7\UriResolver::removeDotSegments` - -`public static function removeDotSegments(string $path): string` - -Removes dot segments from a path and returns the new path according to -[RFC 3986 Section 5.2.4](https://tools.ietf.org/html/rfc3986#section-5.2.4). - -### `GuzzleHttp\Psr7\UriResolver::relativize` - -`public static function relativize(UriInterface $base, UriInterface $target): UriInterface` - -Returns the target URI as a relative reference from the base URI. This method is the counterpart to resolve(): - -```php -(string) $target === (string) UriResolver::resolve($base, UriResolver::relativize($base, $target)) -``` - -One use-case is to use the current request URI as base URI and then generate relative links in your documents -to reduce the document size or offer self-contained downloadable document archives. - -```php -$base = new Uri('http://example.com/a/b/'); -echo UriResolver::relativize($base, new Uri('http://example.com/a/b/c')); // prints 'c'. -echo UriResolver::relativize($base, new Uri('http://example.com/a/x/y')); // prints '../x/y'. -echo UriResolver::relativize($base, new Uri('http://example.com/a/b/?q')); // prints '?q'. -echo UriResolver::relativize($base, new Uri('http://example.org/a/b/')); // prints '//example.org/a/b/'. -``` - -## Normalization and Comparison - -`GuzzleHttp\Psr7\UriNormalizer` provides methods to normalize and compare URIs according to -[RFC 3986 Section 6](https://tools.ietf.org/html/rfc3986#section-6). - -### `GuzzleHttp\Psr7\UriNormalizer::normalize` - -`public static function normalize(UriInterface $uri, $flags = self::PRESERVING_NORMALIZATIONS): UriInterface` - -Returns a normalized URI. The scheme and host component are already normalized to lowercase per PSR-7 UriInterface. -This methods adds additional normalizations that can be configured with the `$flags` parameter which is a bitmask -of normalizations to apply. The following normalizations are available: - -- `UriNormalizer::PRESERVING_NORMALIZATIONS` - - Default normalizations which only include the ones that preserve semantics. - -- `UriNormalizer::CAPITALIZE_PERCENT_ENCODING` - - All letters within a percent-encoding triplet (e.g., "%3A") are case-insensitive, and should be capitalized. - - Example: `http://example.org/a%c2%b1b` → `http://example.org/a%C2%B1b` - -- `UriNormalizer::DECODE_UNRESERVED_CHARACTERS` - - Decodes percent-encoded octets of unreserved characters. For consistency, percent-encoded octets in the ranges of - ALPHA (%41–%5A and %61–%7A), DIGIT (%30–%39), hyphen (%2D), period (%2E), underscore (%5F), or tilde (%7E) should - not be created by URI producers and, when found in a URI, should be decoded to their corresponding unreserved - characters by URI normalizers. - - Example: `http://example.org/%7Eusern%61me/` → `http://example.org/~username/` - -- `UriNormalizer::CONVERT_EMPTY_PATH` - - Converts the empty path to "/" for http and https URIs. - - Example: `http://example.org` → `http://example.org/` - -- `UriNormalizer::REMOVE_DEFAULT_HOST` - - Removes the default host of the given URI scheme from the URI. Only the "file" scheme defines the default host - "localhost". All of `file:/myfile`, `file:///myfile`, and `file://localhost/myfile` are equivalent according to - RFC 3986. - - Example: `file://localhost/myfile` → `file:///myfile` - -- `UriNormalizer::REMOVE_DEFAULT_PORT` - - Removes the default port of the given URI scheme from the URI. - - Example: `http://example.org:80/` → `http://example.org/` - -- `UriNormalizer::REMOVE_DOT_SEGMENTS` - - Removes unnecessary dot-segments. Dot-segments in relative-path references are not removed as it would - change the semantics of the URI reference. - - Example: `http://example.org/../a/b/../c/./d.html` → `http://example.org/a/c/d.html` - -- `UriNormalizer::REMOVE_DUPLICATE_SLASHES` - - Paths which include two or more adjacent slashes are converted to one. Webservers usually ignore duplicate slashes - and treat those URIs equivalent. But in theory those URIs do not need to be equivalent. So this normalization - may change the semantics. Encoded slashes (%2F) are not removed. - - Example: `http://example.org//foo///bar.html` → `http://example.org/foo/bar.html` - -- `UriNormalizer::SORT_QUERY_PARAMETERS` - - Sort query parameters with their values in alphabetical order. However, the order of parameters in a URI may be - significant (this is not defined by the standard). So this normalization is not safe and may change the semantics - of the URI. - - Example: `?lang=en&article=fred` → `?article=fred&lang=en` - -### `GuzzleHttp\Psr7\UriNormalizer::isEquivalent` - -`public static function isEquivalent(UriInterface $uri1, UriInterface $uri2, $normalizations = self::PRESERVING_NORMALIZATIONS): bool` - -Whether two URIs can be considered equivalent. Both URIs are normalized automatically before comparison with the given -`$normalizations` bitmask. The method also accepts relative URI references and returns true when they are equivalent. -This of course assumes they will be resolved against the same base URI. If this is not the case, determination of -equivalence or difference of relative references does not mean anything. diff --git a/plugins/automagic-images/vendor/guzzlehttp/psr7/composer.json b/plugins/automagic-images/vendor/guzzlehttp/psr7/composer.json deleted file mode 100644 index 58dcb07..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/psr7/composer.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "name": "guzzlehttp/psr7", - "type": "library", - "description": "PSR-7 message implementation that also provides common utility methods", - "keywords": ["request", "response", "message", "stream", "http", "uri", "url", "psr-7"], - "license": "MIT", - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - }, - { - "name": "Tobias Schultze", - "homepage": "https://github.com/Tobion" - } - ], - "require": { - "php": ">=5.4.0", - "psr/http-message": "~1.0", - "ralouphie/getallheaders": "^2.0.5 || ^3.0.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10", - "ext-zlib": "*" - }, - "provide": { - "psr/http-message-implementation": "1.0" - }, - "suggest": { - "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" - }, - "autoload": { - "psr-4": { - "GuzzleHttp\\Psr7\\": "src/" - }, - "files": ["src/functions_include.php"] - }, - "autoload-dev": { - "psr-4": { - "GuzzleHttp\\Tests\\Psr7\\": "tests/" - } - }, - "extra": { - "branch-alias": { - "dev-master": "1.7-dev" - } - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/AppendStream.php b/plugins/automagic-images/vendor/guzzlehttp/psr7/src/AppendStream.php deleted file mode 100644 index fa9153d..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/AppendStream.php +++ /dev/null @@ -1,246 +0,0 @@ -addStream($stream); - } - } - - public function __toString() - { - try { - $this->rewind(); - return $this->getContents(); - } catch (\Exception $e) { - return ''; - } - } - - /** - * Add a stream to the AppendStream - * - * @param StreamInterface $stream Stream to append. Must be readable. - * - * @throws \InvalidArgumentException if the stream is not readable - */ - public function addStream(StreamInterface $stream) - { - if (!$stream->isReadable()) { - throw new \InvalidArgumentException('Each stream must be readable'); - } - - // The stream is only seekable if all streams are seekable - if (!$stream->isSeekable()) { - $this->seekable = false; - } - - $this->streams[] = $stream; - } - - public function getContents() - { - return Utils::copyToString($this); - } - - /** - * Closes each attached stream. - * - * {@inheritdoc} - */ - public function close() - { - $this->pos = $this->current = 0; - $this->seekable = true; - - foreach ($this->streams as $stream) { - $stream->close(); - } - - $this->streams = []; - } - - /** - * Detaches each attached stream. - * - * Returns null as it's not clear which underlying stream resource to return. - * - * {@inheritdoc} - */ - public function detach() - { - $this->pos = $this->current = 0; - $this->seekable = true; - - foreach ($this->streams as $stream) { - $stream->detach(); - } - - $this->streams = []; - - return null; - } - - public function tell() - { - return $this->pos; - } - - /** - * Tries to calculate the size by adding the size of each stream. - * - * If any of the streams do not return a valid number, then the size of the - * append stream cannot be determined and null is returned. - * - * {@inheritdoc} - */ - public function getSize() - { - $size = 0; - - foreach ($this->streams as $stream) { - $s = $stream->getSize(); - if ($s === null) { - return null; - } - $size += $s; - } - - return $size; - } - - public function eof() - { - return !$this->streams || - ($this->current >= count($this->streams) - 1 && - $this->streams[$this->current]->eof()); - } - - public function rewind() - { - $this->seek(0); - } - - /** - * Attempts to seek to the given position. Only supports SEEK_SET. - * - * {@inheritdoc} - */ - public function seek($offset, $whence = SEEK_SET) - { - if (!$this->seekable) { - throw new \RuntimeException('This AppendStream is not seekable'); - } elseif ($whence !== SEEK_SET) { - throw new \RuntimeException('The AppendStream can only seek with SEEK_SET'); - } - - $this->pos = $this->current = 0; - - // Rewind each stream - foreach ($this->streams as $i => $stream) { - try { - $stream->rewind(); - } catch (\Exception $e) { - throw new \RuntimeException('Unable to seek stream ' - . $i . ' of the AppendStream', 0, $e); - } - } - - // Seek to the actual position by reading from each stream - while ($this->pos < $offset && !$this->eof()) { - $result = $this->read(min(8096, $offset - $this->pos)); - if ($result === '') { - break; - } - } - } - - /** - * Reads from all of the appended streams until the length is met or EOF. - * - * {@inheritdoc} - */ - public function read($length) - { - $buffer = ''; - $total = count($this->streams) - 1; - $remaining = $length; - $progressToNext = false; - - while ($remaining > 0) { - - // Progress to the next stream if needed. - if ($progressToNext || $this->streams[$this->current]->eof()) { - $progressToNext = false; - if ($this->current === $total) { - break; - } - $this->current++; - } - - $result = $this->streams[$this->current]->read($remaining); - - // Using a loose comparison here to match on '', false, and null - if ($result == null) { - $progressToNext = true; - continue; - } - - $buffer .= $result; - $remaining = $length - strlen($buffer); - } - - $this->pos += strlen($buffer); - - return $buffer; - } - - public function isReadable() - { - return true; - } - - public function isWritable() - { - return false; - } - - public function isSeekable() - { - return $this->seekable; - } - - public function write($string) - { - throw new \RuntimeException('Cannot write to an AppendStream'); - } - - public function getMetadata($key = null) - { - return $key ? null : []; - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/BufferStream.php b/plugins/automagic-images/vendor/guzzlehttp/psr7/src/BufferStream.php deleted file mode 100644 index 783859c..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/BufferStream.php +++ /dev/null @@ -1,142 +0,0 @@ -hwm = $hwm; - } - - public function __toString() - { - return $this->getContents(); - } - - public function getContents() - { - $buffer = $this->buffer; - $this->buffer = ''; - - return $buffer; - } - - public function close() - { - $this->buffer = ''; - } - - public function detach() - { - $this->close(); - - return null; - } - - public function getSize() - { - return strlen($this->buffer); - } - - public function isReadable() - { - return true; - } - - public function isWritable() - { - return true; - } - - public function isSeekable() - { - return false; - } - - public function rewind() - { - $this->seek(0); - } - - public function seek($offset, $whence = SEEK_SET) - { - throw new \RuntimeException('Cannot seek a BufferStream'); - } - - public function eof() - { - return strlen($this->buffer) === 0; - } - - public function tell() - { - throw new \RuntimeException('Cannot determine the position of a BufferStream'); - } - - /** - * Reads data from the buffer. - */ - public function read($length) - { - $currentLength = strlen($this->buffer); - - if ($length >= $currentLength) { - // No need to slice the buffer because we don't have enough data. - $result = $this->buffer; - $this->buffer = ''; - } else { - // Slice up the result to provide a subset of the buffer. - $result = substr($this->buffer, 0, $length); - $this->buffer = substr($this->buffer, $length); - } - - return $result; - } - - /** - * Writes data to the buffer. - */ - public function write($string) - { - $this->buffer .= $string; - - // TODO: What should happen here? - if (strlen($this->buffer) >= $this->hwm) { - return false; - } - - return strlen($string); - } - - public function getMetadata($key = null) - { - if ($key == 'hwm') { - return $this->hwm; - } - - return $key ? null : []; - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/CachingStream.php b/plugins/automagic-images/vendor/guzzlehttp/psr7/src/CachingStream.php deleted file mode 100644 index fe749e9..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/CachingStream.php +++ /dev/null @@ -1,141 +0,0 @@ -remoteStream = $stream; - $this->stream = $target ?: new Stream(Utils::tryFopen('php://temp', 'r+')); - } - - public function getSize() - { - return max($this->stream->getSize(), $this->remoteStream->getSize()); - } - - public function rewind() - { - $this->seek(0); - } - - public function seek($offset, $whence = SEEK_SET) - { - if ($whence == SEEK_SET) { - $byte = $offset; - } elseif ($whence == SEEK_CUR) { - $byte = $offset + $this->tell(); - } elseif ($whence == SEEK_END) { - $size = $this->remoteStream->getSize(); - if ($size === null) { - $size = $this->cacheEntireStream(); - } - $byte = $size + $offset; - } else { - throw new \InvalidArgumentException('Invalid whence'); - } - - $diff = $byte - $this->stream->getSize(); - - if ($diff > 0) { - // Read the remoteStream until we have read in at least the amount - // of bytes requested, or we reach the end of the file. - while ($diff > 0 && !$this->remoteStream->eof()) { - $this->read($diff); - $diff = $byte - $this->stream->getSize(); - } - } else { - // We can just do a normal seek since we've already seen this byte. - $this->stream->seek($byte); - } - } - - public function read($length) - { - // Perform a regular read on any previously read data from the buffer - $data = $this->stream->read($length); - $remaining = $length - strlen($data); - - // More data was requested so read from the remote stream - if ($remaining) { - // If data was written to the buffer in a position that would have - // been filled from the remote stream, then we must skip bytes on - // the remote stream to emulate overwriting bytes from that - // position. This mimics the behavior of other PHP stream wrappers. - $remoteData = $this->remoteStream->read( - $remaining + $this->skipReadBytes - ); - - if ($this->skipReadBytes) { - $len = strlen($remoteData); - $remoteData = substr($remoteData, $this->skipReadBytes); - $this->skipReadBytes = max(0, $this->skipReadBytes - $len); - } - - $data .= $remoteData; - $this->stream->write($remoteData); - } - - return $data; - } - - public function write($string) - { - // When appending to the end of the currently read stream, you'll want - // to skip bytes from being read from the remote stream to emulate - // other stream wrappers. Basically replacing bytes of data of a fixed - // length. - $overflow = (strlen($string) + $this->tell()) - $this->remoteStream->tell(); - if ($overflow > 0) { - $this->skipReadBytes += $overflow; - } - - return $this->stream->write($string); - } - - public function eof() - { - return $this->stream->eof() && $this->remoteStream->eof(); - } - - /** - * Close both the remote stream and buffer stream - */ - public function close() - { - $this->remoteStream->close() && $this->stream->close(); - } - - private function cacheEntireStream() - { - $target = new FnStream(['write' => 'strlen']); - Utils::copyToStream($this, $target); - - return $this->tell(); - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/DroppingStream.php b/plugins/automagic-images/vendor/guzzlehttp/psr7/src/DroppingStream.php deleted file mode 100644 index 9f7420c..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/DroppingStream.php +++ /dev/null @@ -1,45 +0,0 @@ -stream = $stream; - $this->maxLength = $maxLength; - } - - public function write($string) - { - $diff = $this->maxLength - $this->stream->getSize(); - - // Begin returning 0 when the underlying stream is too large. - if ($diff <= 0) { - return 0; - } - - // Write the stream or a subset of the stream if needed. - if (strlen($string) < $diff) { - return $this->stream->write($string); - } - - return $this->stream->write(substr($string, 0, $diff)); - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/FnStream.php b/plugins/automagic-images/vendor/guzzlehttp/psr7/src/FnStream.php deleted file mode 100644 index 76a8cc7..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/FnStream.php +++ /dev/null @@ -1,163 +0,0 @@ -methods = $methods; - - // Create the functions on the class - foreach ($methods as $name => $fn) { - $this->{'_fn_' . $name} = $fn; - } - } - - /** - * Lazily determine which methods are not implemented. - * - * @throws \BadMethodCallException - */ - public function __get($name) - { - throw new \BadMethodCallException(str_replace('_fn_', '', $name) - . '() is not implemented in the FnStream'); - } - - /** - * The close method is called on the underlying stream only if possible. - */ - public function __destruct() - { - if (isset($this->_fn_close)) { - call_user_func($this->_fn_close); - } - } - - /** - * An unserialize would allow the __destruct to run when the unserialized value goes out of scope. - * - * @throws \LogicException - */ - public function __wakeup() - { - throw new \LogicException('FnStream should never be unserialized'); - } - - /** - * Adds custom functionality to an underlying stream by intercepting - * specific method calls. - * - * @param StreamInterface $stream Stream to decorate - * @param array $methods Hash of method name to a closure - * - * @return FnStream - */ - public static function decorate(StreamInterface $stream, array $methods) - { - // If any of the required methods were not provided, then simply - // proxy to the decorated stream. - foreach (array_diff(self::$slots, array_keys($methods)) as $diff) { - $methods[$diff] = [$stream, $diff]; - } - - return new self($methods); - } - - public function __toString() - { - return call_user_func($this->_fn___toString); - } - - public function close() - { - return call_user_func($this->_fn_close); - } - - public function detach() - { - return call_user_func($this->_fn_detach); - } - - public function getSize() - { - return call_user_func($this->_fn_getSize); - } - - public function tell() - { - return call_user_func($this->_fn_tell); - } - - public function eof() - { - return call_user_func($this->_fn_eof); - } - - public function isSeekable() - { - return call_user_func($this->_fn_isSeekable); - } - - public function rewind() - { - call_user_func($this->_fn_rewind); - } - - public function seek($offset, $whence = SEEK_SET) - { - call_user_func($this->_fn_seek, $offset, $whence); - } - - public function isWritable() - { - return call_user_func($this->_fn_isWritable); - } - - public function write($string) - { - return call_user_func($this->_fn_write, $string); - } - - public function isReadable() - { - return call_user_func($this->_fn_isReadable); - } - - public function read($length) - { - return call_user_func($this->_fn_read, $length); - } - - public function getContents() - { - return call_user_func($this->_fn_getContents); - } - - public function getMetadata($key = null) - { - return call_user_func($this->_fn_getMetadata, $key); - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/Header.php b/plugins/automagic-images/vendor/guzzlehttp/psr7/src/Header.php deleted file mode 100644 index 865d742..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/Header.php +++ /dev/null @@ -1,71 +0,0 @@ -]+>|[^=]+/', $kvp, $matches)) { - $m = $matches[0]; - if (isset($m[1])) { - $part[trim($m[0], $trimmed)] = trim($m[1], $trimmed); - } else { - $part[] = trim($m[0], $trimmed); - } - } - } - if ($part) { - $params[] = $part; - } - } - - return $params; - } - - /** - * Converts an array of header values that may contain comma separated - * headers into an array of headers with no comma separated values. - * - * @param string|array $header Header to normalize. - * - * @return array Returns the normalized header field values. - */ - public static function normalize($header) - { - if (!is_array($header)) { - return array_map('trim', explode(',', $header)); - } - - $result = []; - foreach ($header as $value) { - foreach ((array) $value as $v) { - if (strpos($v, ',') === false) { - $result[] = $v; - continue; - } - foreach (preg_split('/,(?=([^"]*"[^"]*")*[^"]*$)/', $v) as $vv) { - $result[] = trim($vv); - } - } - } - - return $result; - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/InflateStream.php b/plugins/automagic-images/vendor/guzzlehttp/psr7/src/InflateStream.php deleted file mode 100644 index 0cbd2cc..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/InflateStream.php +++ /dev/null @@ -1,56 +0,0 @@ -read(10); - $filenameHeaderLength = $this->getLengthOfPossibleFilenameHeader($stream, $header); - // Skip the header, that is 10 + length of filename + 1 (nil) bytes - $stream = new LimitStream($stream, -1, 10 + $filenameHeaderLength); - $resource = StreamWrapper::getResource($stream); - stream_filter_append($resource, 'zlib.inflate', STREAM_FILTER_READ); - $this->stream = $stream->isSeekable() ? new Stream($resource) : new NoSeekStream(new Stream($resource)); - } - - /** - * @param StreamInterface $stream - * @param $header - * - * @return int - */ - private function getLengthOfPossibleFilenameHeader(StreamInterface $stream, $header) - { - $filename_header_length = 0; - - if (substr(bin2hex($header), 6, 2) === '08') { - // we have a filename, read until nil - $filename_header_length = 1; - while ($stream->read(1) !== chr(0)) { - $filename_header_length++; - } - } - - return $filename_header_length; - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/LazyOpenStream.php b/plugins/automagic-images/vendor/guzzlehttp/psr7/src/LazyOpenStream.php deleted file mode 100644 index 911e127..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/LazyOpenStream.php +++ /dev/null @@ -1,42 +0,0 @@ -filename = $filename; - $this->mode = $mode; - } - - /** - * Creates the underlying stream lazily when required. - * - * @return StreamInterface - */ - protected function createStream() - { - return Utils::streamFor(Utils::tryFopen($this->filename, $this->mode)); - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/LimitStream.php b/plugins/automagic-images/vendor/guzzlehttp/psr7/src/LimitStream.php deleted file mode 100644 index 1173ec4..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/LimitStream.php +++ /dev/null @@ -1,157 +0,0 @@ -stream = $stream; - $this->setLimit($limit); - $this->setOffset($offset); - } - - public function eof() - { - // Always return true if the underlying stream is EOF - if ($this->stream->eof()) { - return true; - } - - // No limit and the underlying stream is not at EOF - if ($this->limit == -1) { - return false; - } - - return $this->stream->tell() >= $this->offset + $this->limit; - } - - /** - * Returns the size of the limited subset of data - * {@inheritdoc} - */ - public function getSize() - { - if (null === ($length = $this->stream->getSize())) { - return null; - } elseif ($this->limit == -1) { - return $length - $this->offset; - } else { - return min($this->limit, $length - $this->offset); - } - } - - /** - * Allow for a bounded seek on the read limited stream - * {@inheritdoc} - */ - public function seek($offset, $whence = SEEK_SET) - { - if ($whence !== SEEK_SET || $offset < 0) { - throw new \RuntimeException(sprintf( - 'Cannot seek to offset %s with whence %s', - $offset, - $whence - )); - } - - $offset += $this->offset; - - if ($this->limit !== -1) { - if ($offset > $this->offset + $this->limit) { - $offset = $this->offset + $this->limit; - } - } - - $this->stream->seek($offset); - } - - /** - * Give a relative tell() - * {@inheritdoc} - */ - public function tell() - { - return $this->stream->tell() - $this->offset; - } - - /** - * Set the offset to start limiting from - * - * @param int $offset Offset to seek to and begin byte limiting from - * - * @throws \RuntimeException if the stream cannot be seeked. - */ - public function setOffset($offset) - { - $current = $this->stream->tell(); - - if ($current !== $offset) { - // If the stream cannot seek to the offset position, then read to it - if ($this->stream->isSeekable()) { - $this->stream->seek($offset); - } elseif ($current > $offset) { - throw new \RuntimeException("Could not seek to stream offset $offset"); - } else { - $this->stream->read($offset - $current); - } - } - - $this->offset = $offset; - } - - /** - * Set the limit of bytes that the decorator allows to be read from the - * stream. - * - * @param int $limit Number of bytes to allow to be read from the stream. - * Use -1 for no limit. - */ - public function setLimit($limit) - { - $this->limit = $limit; - } - - public function read($length) - { - if ($this->limit == -1) { - return $this->stream->read($length); - } - - // Check if the current position is less than the total allowed - // bytes + original offset - $remaining = ($this->offset + $this->limit) - $this->stream->tell(); - if ($remaining > 0) { - // Only return the amount of requested data, ensuring that the byte - // limit is not exceeded - return $this->stream->read(min($remaining, $length)); - } - - return ''; - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/Message.php b/plugins/automagic-images/vendor/guzzlehttp/psr7/src/Message.php deleted file mode 100644 index 516d1cb..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/Message.php +++ /dev/null @@ -1,252 +0,0 @@ -getMethod() . ' ' - . $message->getRequestTarget()) - . ' HTTP/' . $message->getProtocolVersion(); - if (!$message->hasHeader('host')) { - $msg .= "\r\nHost: " . $message->getUri()->getHost(); - } - } elseif ($message instanceof ResponseInterface) { - $msg = 'HTTP/' . $message->getProtocolVersion() . ' ' - . $message->getStatusCode() . ' ' - . $message->getReasonPhrase(); - } else { - throw new \InvalidArgumentException('Unknown message type'); - } - - foreach ($message->getHeaders() as $name => $values) { - if (strtolower($name) === 'set-cookie') { - foreach ($values as $value) { - $msg .= "\r\n{$name}: " . $value; - } - } else { - $msg .= "\r\n{$name}: " . implode(', ', $values); - } - } - - return "{$msg}\r\n\r\n" . $message->getBody(); - } - - /** - * Get a short summary of the message body. - * - * Will return `null` if the response is not printable. - * - * @param MessageInterface $message The message to get the body summary - * @param int $truncateAt The maximum allowed size of the summary - * - * @return string|null - */ - public static function bodySummary(MessageInterface $message, $truncateAt = 120) - { - $body = $message->getBody(); - - if (!$body->isSeekable() || !$body->isReadable()) { - return null; - } - - $size = $body->getSize(); - - if ($size === 0) { - return null; - } - - $summary = $body->read($truncateAt); - $body->rewind(); - - if ($size > $truncateAt) { - $summary .= ' (truncated...)'; - } - - // Matches any printable character, including unicode characters: - // letters, marks, numbers, punctuation, spacing, and separators. - if (preg_match('/[^\pL\pM\pN\pP\pS\pZ\n\r\t]/u', $summary)) { - return null; - } - - return $summary; - } - - /** - * Attempts to rewind a message body and throws an exception on failure. - * - * The body of the message will only be rewound if a call to `tell()` - * returns a value other than `0`. - * - * @param MessageInterface $message Message to rewind - * - * @throws \RuntimeException - */ - public static function rewindBody(MessageInterface $message) - { - $body = $message->getBody(); - - if ($body->tell()) { - $body->rewind(); - } - } - - /** - * Parses an HTTP message into an associative array. - * - * The array contains the "start-line" key containing the start line of - * the message, "headers" key containing an associative array of header - * array values, and a "body" key containing the body of the message. - * - * @param string $message HTTP request or response to parse. - * - * @return array - */ - public static function parseMessage($message) - { - if (!$message) { - throw new \InvalidArgumentException('Invalid message'); - } - - $message = ltrim($message, "\r\n"); - - $messageParts = preg_split("/\r?\n\r?\n/", $message, 2); - - if ($messageParts === false || count($messageParts) !== 2) { - throw new \InvalidArgumentException('Invalid message: Missing header delimiter'); - } - - list($rawHeaders, $body) = $messageParts; - $rawHeaders .= "\r\n"; // Put back the delimiter we split previously - $headerParts = preg_split("/\r?\n/", $rawHeaders, 2); - - if ($headerParts === false || count($headerParts) !== 2) { - throw new \InvalidArgumentException('Invalid message: Missing status line'); - } - - list($startLine, $rawHeaders) = $headerParts; - - if (preg_match("/(?:^HTTP\/|^[A-Z]+ \S+ HTTP\/)(\d+(?:\.\d+)?)/i", $startLine, $matches) && $matches[1] === '1.0') { - // Header folding is deprecated for HTTP/1.1, but allowed in HTTP/1.0 - $rawHeaders = preg_replace(Rfc7230::HEADER_FOLD_REGEX, ' ', $rawHeaders); - } - - /** @var array[] $headerLines */ - $count = preg_match_all(Rfc7230::HEADER_REGEX, $rawHeaders, $headerLines, PREG_SET_ORDER); - - // If these aren't the same, then one line didn't match and there's an invalid header. - if ($count !== substr_count($rawHeaders, "\n")) { - // Folding is deprecated, see https://tools.ietf.org/html/rfc7230#section-3.2.4 - if (preg_match(Rfc7230::HEADER_FOLD_REGEX, $rawHeaders)) { - throw new \InvalidArgumentException('Invalid header syntax: Obsolete line folding'); - } - - throw new \InvalidArgumentException('Invalid header syntax'); - } - - $headers = []; - - foreach ($headerLines as $headerLine) { - $headers[$headerLine[1]][] = $headerLine[2]; - } - - return [ - 'start-line' => $startLine, - 'headers' => $headers, - 'body' => $body, - ]; - } - - /** - * Constructs a URI for an HTTP request message. - * - * @param string $path Path from the start-line - * @param array $headers Array of headers (each value an array). - * - * @return string - */ - public static function parseRequestUri($path, array $headers) - { - $hostKey = array_filter(array_keys($headers), function ($k) { - return strtolower($k) === 'host'; - }); - - // If no host is found, then a full URI cannot be constructed. - if (!$hostKey) { - return $path; - } - - $host = $headers[reset($hostKey)][0]; - $scheme = substr($host, -4) === ':443' ? 'https' : 'http'; - - return $scheme . '://' . $host . '/' . ltrim($path, '/'); - } - - /** - * Parses a request message string into a request object. - * - * @param string $message Request message string. - * - * @return Request - */ - public static function parseRequest($message) - { - $data = self::parseMessage($message); - $matches = []; - if (!preg_match('/^[\S]+\s+([a-zA-Z]+:\/\/|\/).*/', $data['start-line'], $matches)) { - throw new \InvalidArgumentException('Invalid request string'); - } - $parts = explode(' ', $data['start-line'], 3); - $version = isset($parts[2]) ? explode('/', $parts[2])[1] : '1.1'; - - $request = new Request( - $parts[0], - $matches[1] === '/' ? self::parseRequestUri($parts[1], $data['headers']) : $parts[1], - $data['headers'], - $data['body'], - $version - ); - - return $matches[1] === '/' ? $request : $request->withRequestTarget($parts[1]); - } - - /** - * Parses a response message string into a response object. - * - * @param string $message Response message string. - * - * @return Response - */ - public static function parseResponse($message) - { - $data = self::parseMessage($message); - // According to https://tools.ietf.org/html/rfc7230#section-3.1.2 the space - // between status-code and reason-phrase is required. But browsers accept - // responses without space and reason as well. - if (!preg_match('/^HTTP\/.* [0-9]{3}( .*|$)/', $data['start-line'])) { - throw new \InvalidArgumentException('Invalid response string: ' . $data['start-line']); - } - $parts = explode(' ', $data['start-line'], 3); - - return new Response( - (int) $parts[1], - $data['headers'], - $data['body'], - explode('/', $parts[0])[1], - isset($parts[2]) ? $parts[2] : null - ); - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/MessageTrait.php b/plugins/automagic-images/vendor/guzzlehttp/psr7/src/MessageTrait.php deleted file mode 100644 index 99203bb..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/MessageTrait.php +++ /dev/null @@ -1,214 +0,0 @@ - array of values */ - private $headers = []; - - /** @var array Map of lowercase header name => original name at registration */ - private $headerNames = []; - - /** @var string */ - private $protocol = '1.1'; - - /** @var StreamInterface|null */ - private $stream; - - public function getProtocolVersion() - { - return $this->protocol; - } - - public function withProtocolVersion($version) - { - if ($this->protocol === $version) { - return $this; - } - - $new = clone $this; - $new->protocol = $version; - return $new; - } - - public function getHeaders() - { - return $this->headers; - } - - public function hasHeader($header) - { - return isset($this->headerNames[strtolower($header)]); - } - - public function getHeader($header) - { - $header = strtolower($header); - - if (!isset($this->headerNames[$header])) { - return []; - } - - $header = $this->headerNames[$header]; - - return $this->headers[$header]; - } - - public function getHeaderLine($header) - { - return implode(', ', $this->getHeader($header)); - } - - public function withHeader($header, $value) - { - $this->assertHeader($header); - $value = $this->normalizeHeaderValue($value); - $normalized = strtolower($header); - - $new = clone $this; - if (isset($new->headerNames[$normalized])) { - unset($new->headers[$new->headerNames[$normalized]]); - } - $new->headerNames[$normalized] = $header; - $new->headers[$header] = $value; - - return $new; - } - - public function withAddedHeader($header, $value) - { - $this->assertHeader($header); - $value = $this->normalizeHeaderValue($value); - $normalized = strtolower($header); - - $new = clone $this; - if (isset($new->headerNames[$normalized])) { - $header = $this->headerNames[$normalized]; - $new->headers[$header] = array_merge($this->headers[$header], $value); - } else { - $new->headerNames[$normalized] = $header; - $new->headers[$header] = $value; - } - - return $new; - } - - public function withoutHeader($header) - { - $normalized = strtolower($header); - - if (!isset($this->headerNames[$normalized])) { - return $this; - } - - $header = $this->headerNames[$normalized]; - - $new = clone $this; - unset($new->headers[$header], $new->headerNames[$normalized]); - - return $new; - } - - public function getBody() - { - if (!$this->stream) { - $this->stream = Utils::streamFor(''); - } - - return $this->stream; - } - - public function withBody(StreamInterface $body) - { - if ($body === $this->stream) { - return $this; - } - - $new = clone $this; - $new->stream = $body; - return $new; - } - - private function setHeaders(array $headers) - { - $this->headerNames = $this->headers = []; - foreach ($headers as $header => $value) { - if (is_int($header)) { - // Numeric array keys are converted to int by PHP but having a header name '123' is not forbidden by the spec - // and also allowed in withHeader(). So we need to cast it to string again for the following assertion to pass. - $header = (string) $header; - } - $this->assertHeader($header); - $value = $this->normalizeHeaderValue($value); - $normalized = strtolower($header); - if (isset($this->headerNames[$normalized])) { - $header = $this->headerNames[$normalized]; - $this->headers[$header] = array_merge($this->headers[$header], $value); - } else { - $this->headerNames[$normalized] = $header; - $this->headers[$header] = $value; - } - } - } - - private function normalizeHeaderValue($value) - { - if (!is_array($value)) { - return $this->trimHeaderValues([$value]); - } - - if (count($value) === 0) { - throw new \InvalidArgumentException('Header value can not be an empty array.'); - } - - return $this->trimHeaderValues($value); - } - - /** - * Trims whitespace from the header values. - * - * Spaces and tabs ought to be excluded by parsers when extracting the field value from a header field. - * - * header-field = field-name ":" OWS field-value OWS - * OWS = *( SP / HTAB ) - * - * @param string[] $values Header values - * - * @return string[] Trimmed header values - * - * @see https://tools.ietf.org/html/rfc7230#section-3.2.4 - */ - private function trimHeaderValues(array $values) - { - return array_map(function ($value) { - if (!is_scalar($value) && null !== $value) { - throw new \InvalidArgumentException(sprintf( - 'Header value must be scalar or null but %s provided.', - is_object($value) ? get_class($value) : gettype($value) - )); - } - - return trim((string) $value, " \t"); - }, array_values($values)); - } - - private function assertHeader($header) - { - if (!is_string($header)) { - throw new \InvalidArgumentException(sprintf( - 'Header name must be a string but %s provided.', - is_object($header) ? get_class($header) : gettype($header) - )); - } - - if ($header === '') { - throw new \InvalidArgumentException('Header name can not be empty.'); - } - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/MimeType.php b/plugins/automagic-images/vendor/guzzlehttp/psr7/src/MimeType.php deleted file mode 100644 index 205c7b1..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/MimeType.php +++ /dev/null @@ -1,140 +0,0 @@ - 'video/3gpp', - '7z' => 'application/x-7z-compressed', - 'aac' => 'audio/x-aac', - 'ai' => 'application/postscript', - 'aif' => 'audio/x-aiff', - 'asc' => 'text/plain', - 'asf' => 'video/x-ms-asf', - 'atom' => 'application/atom+xml', - 'avi' => 'video/x-msvideo', - 'bmp' => 'image/bmp', - 'bz2' => 'application/x-bzip2', - 'cer' => 'application/pkix-cert', - 'crl' => 'application/pkix-crl', - 'crt' => 'application/x-x509-ca-cert', - 'css' => 'text/css', - 'csv' => 'text/csv', - 'cu' => 'application/cu-seeme', - 'deb' => 'application/x-debian-package', - 'doc' => 'application/msword', - 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', - 'dvi' => 'application/x-dvi', - 'eot' => 'application/vnd.ms-fontobject', - 'eps' => 'application/postscript', - 'epub' => 'application/epub+zip', - 'etx' => 'text/x-setext', - 'flac' => 'audio/flac', - 'flv' => 'video/x-flv', - 'gif' => 'image/gif', - 'gz' => 'application/gzip', - 'htm' => 'text/html', - 'html' => 'text/html', - 'ico' => 'image/x-icon', - 'ics' => 'text/calendar', - 'ini' => 'text/plain', - 'iso' => 'application/x-iso9660-image', - 'jar' => 'application/java-archive', - 'jpe' => 'image/jpeg', - 'jpeg' => 'image/jpeg', - 'jpg' => 'image/jpeg', - 'js' => 'text/javascript', - 'json' => 'application/json', - 'latex' => 'application/x-latex', - 'log' => 'text/plain', - 'm4a' => 'audio/mp4', - 'm4v' => 'video/mp4', - 'mid' => 'audio/midi', - 'midi' => 'audio/midi', - 'mov' => 'video/quicktime', - 'mkv' => 'video/x-matroska', - 'mp3' => 'audio/mpeg', - 'mp4' => 'video/mp4', - 'mp4a' => 'audio/mp4', - 'mp4v' => 'video/mp4', - 'mpe' => 'video/mpeg', - 'mpeg' => 'video/mpeg', - 'mpg' => 'video/mpeg', - 'mpg4' => 'video/mp4', - 'oga' => 'audio/ogg', - 'ogg' => 'audio/ogg', - 'ogv' => 'video/ogg', - 'ogx' => 'application/ogg', - 'pbm' => 'image/x-portable-bitmap', - 'pdf' => 'application/pdf', - 'pgm' => 'image/x-portable-graymap', - 'png' => 'image/png', - 'pnm' => 'image/x-portable-anymap', - 'ppm' => 'image/x-portable-pixmap', - 'ppt' => 'application/vnd.ms-powerpoint', - 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', - 'ps' => 'application/postscript', - 'qt' => 'video/quicktime', - 'rar' => 'application/x-rar-compressed', - 'ras' => 'image/x-cmu-raster', - 'rss' => 'application/rss+xml', - 'rtf' => 'application/rtf', - 'sgm' => 'text/sgml', - 'sgml' => 'text/sgml', - 'svg' => 'image/svg+xml', - 'swf' => 'application/x-shockwave-flash', - 'tar' => 'application/x-tar', - 'tif' => 'image/tiff', - 'tiff' => 'image/tiff', - 'torrent' => 'application/x-bittorrent', - 'ttf' => 'application/x-font-ttf', - 'txt' => 'text/plain', - 'wav' => 'audio/x-wav', - 'webm' => 'video/webm', - 'webp' => 'image/webp', - 'wma' => 'audio/x-ms-wma', - 'wmv' => 'video/x-ms-wmv', - 'woff' => 'application/x-font-woff', - 'wsdl' => 'application/wsdl+xml', - 'xbm' => 'image/x-xbitmap', - 'xls' => 'application/vnd.ms-excel', - 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', - 'xml' => 'application/xml', - 'xpm' => 'image/x-xpixmap', - 'xwd' => 'image/x-xwindowdump', - 'yaml' => 'text/yaml', - 'yml' => 'text/yaml', - 'zip' => 'application/zip', - ]; - - $extension = strtolower($extension); - - return isset($mimetypes[$extension]) - ? $mimetypes[$extension] - : null; - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/MultipartStream.php b/plugins/automagic-images/vendor/guzzlehttp/psr7/src/MultipartStream.php deleted file mode 100644 index 5a6079a..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/MultipartStream.php +++ /dev/null @@ -1,158 +0,0 @@ -boundary = $boundary ?: sha1(uniqid('', true)); - $this->stream = $this->createStream($elements); - } - - /** - * Get the boundary - * - * @return string - */ - public function getBoundary() - { - return $this->boundary; - } - - public function isWritable() - { - return false; - } - - /** - * Get the headers needed before transferring the content of a POST file - */ - private function getHeaders(array $headers) - { - $str = ''; - foreach ($headers as $key => $value) { - $str .= "{$key}: {$value}\r\n"; - } - - return "--{$this->boundary}\r\n" . trim($str) . "\r\n\r\n"; - } - - /** - * Create the aggregate stream that will be used to upload the POST data - */ - protected function createStream(array $elements) - { - $stream = new AppendStream(); - - foreach ($elements as $element) { - $this->addElement($stream, $element); - } - - // Add the trailing boundary with CRLF - $stream->addStream(Utils::streamFor("--{$this->boundary}--\r\n")); - - return $stream; - } - - private function addElement(AppendStream $stream, array $element) - { - foreach (['contents', 'name'] as $key) { - if (!array_key_exists($key, $element)) { - throw new \InvalidArgumentException("A '{$key}' key is required"); - } - } - - $element['contents'] = Utils::streamFor($element['contents']); - - if (empty($element['filename'])) { - $uri = $element['contents']->getMetadata('uri'); - if (substr($uri, 0, 6) !== 'php://') { - $element['filename'] = $uri; - } - } - - list($body, $headers) = $this->createElement( - $element['name'], - $element['contents'], - isset($element['filename']) ? $element['filename'] : null, - isset($element['headers']) ? $element['headers'] : [] - ); - - $stream->addStream(Utils::streamFor($this->getHeaders($headers))); - $stream->addStream($body); - $stream->addStream(Utils::streamFor("\r\n")); - } - - /** - * @return array - */ - private function createElement($name, StreamInterface $stream, $filename, array $headers) - { - // Set a default content-disposition header if one was no provided - $disposition = $this->getHeader($headers, 'content-disposition'); - if (!$disposition) { - $headers['Content-Disposition'] = ($filename === '0' || $filename) - ? sprintf( - 'form-data; name="%s"; filename="%s"', - $name, - basename($filename) - ) - : "form-data; name=\"{$name}\""; - } - - // Set a default content-length header if one was no provided - $length = $this->getHeader($headers, 'content-length'); - if (!$length) { - if ($length = $stream->getSize()) { - $headers['Content-Length'] = (string) $length; - } - } - - // Set a default Content-Type if one was not supplied - $type = $this->getHeader($headers, 'content-type'); - if (!$type && ($filename === '0' || $filename)) { - if ($type = MimeType::fromFilename($filename)) { - $headers['Content-Type'] = $type; - } - } - - return [$stream, $headers]; - } - - private function getHeader(array $headers, $key) - { - $lowercaseHeader = strtolower($key); - foreach ($headers as $k => $v) { - if (strtolower($k) === $lowercaseHeader) { - return $v; - } - } - - return null; - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/NoSeekStream.php b/plugins/automagic-images/vendor/guzzlehttp/psr7/src/NoSeekStream.php deleted file mode 100644 index d66bdde..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/NoSeekStream.php +++ /dev/null @@ -1,25 +0,0 @@ -source = $source; - $this->size = isset($options['size']) ? $options['size'] : null; - $this->metadata = isset($options['metadata']) ? $options['metadata'] : []; - $this->buffer = new BufferStream(); - } - - public function __toString() - { - try { - return Utils::copyToString($this); - } catch (\Exception $e) { - return ''; - } - } - - public function close() - { - $this->detach(); - } - - public function detach() - { - $this->tellPos = false; - $this->source = null; - - return null; - } - - public function getSize() - { - return $this->size; - } - - public function tell() - { - return $this->tellPos; - } - - public function eof() - { - return !$this->source; - } - - public function isSeekable() - { - return false; - } - - public function rewind() - { - $this->seek(0); - } - - public function seek($offset, $whence = SEEK_SET) - { - throw new \RuntimeException('Cannot seek a PumpStream'); - } - - public function isWritable() - { - return false; - } - - public function write($string) - { - throw new \RuntimeException('Cannot write to a PumpStream'); - } - - public function isReadable() - { - return true; - } - - public function read($length) - { - $data = $this->buffer->read($length); - $readLen = strlen($data); - $this->tellPos += $readLen; - $remaining = $length - $readLen; - - if ($remaining) { - $this->pump($remaining); - $data .= $this->buffer->read($remaining); - $this->tellPos += strlen($data) - $readLen; - } - - return $data; - } - - public function getContents() - { - $result = ''; - while (!$this->eof()) { - $result .= $this->read(1000000); - } - - return $result; - } - - public function getMetadata($key = null) - { - if (!$key) { - return $this->metadata; - } - - return isset($this->metadata[$key]) ? $this->metadata[$key] : null; - } - - private function pump($length) - { - if ($this->source) { - do { - $data = call_user_func($this->source, $length); - if ($data === false || $data === null) { - $this->source = null; - return; - } - $this->buffer->write($data); - $length -= strlen($data); - } while ($length > 0); - } - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/Query.php b/plugins/automagic-images/vendor/guzzlehttp/psr7/src/Query.php deleted file mode 100644 index 5a7cc03..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/Query.php +++ /dev/null @@ -1,113 +0,0 @@ - '1', 'foo[b]' => '2'])`. - * - * @param string $str Query string to parse - * @param int|bool $urlEncoding How the query string is encoded - * - * @return array - */ - public static function parse($str, $urlEncoding = true) - { - $result = []; - - if ($str === '') { - return $result; - } - - if ($urlEncoding === true) { - $decoder = function ($value) { - return rawurldecode(str_replace('+', ' ', $value)); - }; - } elseif ($urlEncoding === PHP_QUERY_RFC3986) { - $decoder = 'rawurldecode'; - } elseif ($urlEncoding === PHP_QUERY_RFC1738) { - $decoder = 'urldecode'; - } else { - $decoder = function ($str) { - return $str; - }; - } - - foreach (explode('&', $str) as $kvp) { - $parts = explode('=', $kvp, 2); - $key = $decoder($parts[0]); - $value = isset($parts[1]) ? $decoder($parts[1]) : null; - if (!isset($result[$key])) { - $result[$key] = $value; - } else { - if (!is_array($result[$key])) { - $result[$key] = [$result[$key]]; - } - $result[$key][] = $value; - } - } - - return $result; - } - - /** - * Build a query string from an array of key value pairs. - * - * This function can use the return value of `parse()` to build a query - * string. This function does not modify the provided keys when an array is - * encountered (like `http_build_query()` would). - * - * @param array $params Query string parameters. - * @param int|false $encoding Set to false to not encode, PHP_QUERY_RFC3986 - * to encode using RFC3986, or PHP_QUERY_RFC1738 - * to encode using RFC1738. - * - * @return string - */ - public static function build(array $params, $encoding = PHP_QUERY_RFC3986) - { - if (!$params) { - return ''; - } - - if ($encoding === false) { - $encoder = function ($str) { - return $str; - }; - } elseif ($encoding === PHP_QUERY_RFC3986) { - $encoder = 'rawurlencode'; - } elseif ($encoding === PHP_QUERY_RFC1738) { - $encoder = 'urlencode'; - } else { - throw new \InvalidArgumentException('Invalid type'); - } - - $qs = ''; - foreach ($params as $k => $v) { - $k = $encoder($k); - if (!is_array($v)) { - $qs .= $k; - if ($v !== null) { - $qs .= '=' . $encoder($v); - } - $qs .= '&'; - } else { - foreach ($v as $vv) { - $qs .= $k; - if ($vv !== null) { - $qs .= '=' . $encoder($vv); - } - $qs .= '&'; - } - } - } - - return $qs ? (string) substr($qs, 0, -1) : ''; - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/Request.php b/plugins/automagic-images/vendor/guzzlehttp/psr7/src/Request.php deleted file mode 100644 index c1cdaeb..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/Request.php +++ /dev/null @@ -1,152 +0,0 @@ -assertMethod($method); - if (!($uri instanceof UriInterface)) { - $uri = new Uri($uri); - } - - $this->method = strtoupper($method); - $this->uri = $uri; - $this->setHeaders($headers); - $this->protocol = $version; - - if (!isset($this->headerNames['host'])) { - $this->updateHostFromUri(); - } - - if ($body !== '' && $body !== null) { - $this->stream = Utils::streamFor($body); - } - } - - public function getRequestTarget() - { - if ($this->requestTarget !== null) { - return $this->requestTarget; - } - - $target = $this->uri->getPath(); - if ($target == '') { - $target = '/'; - } - if ($this->uri->getQuery() != '') { - $target .= '?' . $this->uri->getQuery(); - } - - return $target; - } - - public function withRequestTarget($requestTarget) - { - if (preg_match('#\s#', $requestTarget)) { - throw new InvalidArgumentException( - 'Invalid request target provided; cannot contain whitespace' - ); - } - - $new = clone $this; - $new->requestTarget = $requestTarget; - return $new; - } - - public function getMethod() - { - return $this->method; - } - - public function withMethod($method) - { - $this->assertMethod($method); - $new = clone $this; - $new->method = strtoupper($method); - return $new; - } - - public function getUri() - { - return $this->uri; - } - - public function withUri(UriInterface $uri, $preserveHost = false) - { - if ($uri === $this->uri) { - return $this; - } - - $new = clone $this; - $new->uri = $uri; - - if (!$preserveHost || !isset($this->headerNames['host'])) { - $new->updateHostFromUri(); - } - - return $new; - } - - private function updateHostFromUri() - { - $host = $this->uri->getHost(); - - if ($host == '') { - return; - } - - if (($port = $this->uri->getPort()) !== null) { - $host .= ':' . $port; - } - - if (isset($this->headerNames['host'])) { - $header = $this->headerNames['host']; - } else { - $header = 'Host'; - $this->headerNames['host'] = 'Host'; - } - // Ensure Host is the first header. - // See: http://tools.ietf.org/html/rfc7230#section-5.4 - $this->headers = [$header => [$host]] + $this->headers; - } - - private function assertMethod($method) - { - if (!is_string($method) || $method === '') { - throw new \InvalidArgumentException('Method must be a non-empty string.'); - } - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/Response.php b/plugins/automagic-images/vendor/guzzlehttp/psr7/src/Response.php deleted file mode 100644 index 8c01a0f..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/Response.php +++ /dev/null @@ -1,155 +0,0 @@ - 'Continue', - 101 => 'Switching Protocols', - 102 => 'Processing', - 200 => 'OK', - 201 => 'Created', - 202 => 'Accepted', - 203 => 'Non-Authoritative Information', - 204 => 'No Content', - 205 => 'Reset Content', - 206 => 'Partial Content', - 207 => 'Multi-status', - 208 => 'Already Reported', - 300 => 'Multiple Choices', - 301 => 'Moved Permanently', - 302 => 'Found', - 303 => 'See Other', - 304 => 'Not Modified', - 305 => 'Use Proxy', - 306 => 'Switch Proxy', - 307 => 'Temporary Redirect', - 400 => 'Bad Request', - 401 => 'Unauthorized', - 402 => 'Payment Required', - 403 => 'Forbidden', - 404 => 'Not Found', - 405 => 'Method Not Allowed', - 406 => 'Not Acceptable', - 407 => 'Proxy Authentication Required', - 408 => 'Request Time-out', - 409 => 'Conflict', - 410 => 'Gone', - 411 => 'Length Required', - 412 => 'Precondition Failed', - 413 => 'Request Entity Too Large', - 414 => 'Request-URI Too Large', - 415 => 'Unsupported Media Type', - 416 => 'Requested range not satisfiable', - 417 => 'Expectation Failed', - 418 => 'I\'m a teapot', - 422 => 'Unprocessable Entity', - 423 => 'Locked', - 424 => 'Failed Dependency', - 425 => 'Unordered Collection', - 426 => 'Upgrade Required', - 428 => 'Precondition Required', - 429 => 'Too Many Requests', - 431 => 'Request Header Fields Too Large', - 451 => 'Unavailable For Legal Reasons', - 500 => 'Internal Server Error', - 501 => 'Not Implemented', - 502 => 'Bad Gateway', - 503 => 'Service Unavailable', - 504 => 'Gateway Time-out', - 505 => 'HTTP Version not supported', - 506 => 'Variant Also Negotiates', - 507 => 'Insufficient Storage', - 508 => 'Loop Detected', - 511 => 'Network Authentication Required', - ]; - - /** @var string */ - private $reasonPhrase = ''; - - /** @var int */ - private $statusCode = 200; - - /** - * @param int $status Status code - * @param array $headers Response headers - * @param string|resource|StreamInterface|null $body Response body - * @param string $version Protocol version - * @param string|null $reason Reason phrase (when empty a default will be used based on the status code) - */ - public function __construct( - $status = 200, - array $headers = [], - $body = null, - $version = '1.1', - $reason = null - ) { - $this->assertStatusCodeIsInteger($status); - $status = (int) $status; - $this->assertStatusCodeRange($status); - - $this->statusCode = $status; - - if ($body !== '' && $body !== null) { - $this->stream = Utils::streamFor($body); - } - - $this->setHeaders($headers); - if ($reason == '' && isset(self::$phrases[$this->statusCode])) { - $this->reasonPhrase = self::$phrases[$this->statusCode]; - } else { - $this->reasonPhrase = (string) $reason; - } - - $this->protocol = $version; - } - - public function getStatusCode() - { - return $this->statusCode; - } - - public function getReasonPhrase() - { - return $this->reasonPhrase; - } - - public function withStatus($code, $reasonPhrase = '') - { - $this->assertStatusCodeIsInteger($code); - $code = (int) $code; - $this->assertStatusCodeRange($code); - - $new = clone $this; - $new->statusCode = $code; - if ($reasonPhrase == '' && isset(self::$phrases[$new->statusCode])) { - $reasonPhrase = self::$phrases[$new->statusCode]; - } - $new->reasonPhrase = (string) $reasonPhrase; - return $new; - } - - private function assertStatusCodeIsInteger($statusCode) - { - if (filter_var($statusCode, FILTER_VALIDATE_INT) === false) { - throw new \InvalidArgumentException('Status code must be an integer value.'); - } - } - - private function assertStatusCodeRange($statusCode) - { - if ($statusCode < 100 || $statusCode >= 600) { - throw new \InvalidArgumentException('Status code must be an integer value between 1xx and 5xx.'); - } - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/Rfc7230.php b/plugins/automagic-images/vendor/guzzlehttp/psr7/src/Rfc7230.php deleted file mode 100644 index 51b571f..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/Rfc7230.php +++ /dev/null @@ -1,19 +0,0 @@ -@,;:\\\"/[\]?={}\x01-\x20\x7F]++):[ \t]*+((?:[ \t]*+[\x21-\x7E\x80-\xFF]++)*+)[ \t]*+\r?\n)m"; - const HEADER_FOLD_REGEX = "(\r?\n[ \t]++)"; -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/ServerRequest.php b/plugins/automagic-images/vendor/guzzlehttp/psr7/src/ServerRequest.php deleted file mode 100644 index e6d26f5..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/ServerRequest.php +++ /dev/null @@ -1,379 +0,0 @@ -serverParams = $serverParams; - - parent::__construct($method, $uri, $headers, $body, $version); - } - - /** - * Return an UploadedFile instance array. - * - * @param array $files A array which respect $_FILES structure - * - * @return array - * - * @throws InvalidArgumentException for unrecognized values - */ - public static function normalizeFiles(array $files) - { - $normalized = []; - - foreach ($files as $key => $value) { - if ($value instanceof UploadedFileInterface) { - $normalized[$key] = $value; - } elseif (is_array($value) && isset($value['tmp_name'])) { - $normalized[$key] = self::createUploadedFileFromSpec($value); - } elseif (is_array($value)) { - $normalized[$key] = self::normalizeFiles($value); - continue; - } else { - throw new InvalidArgumentException('Invalid value in files specification'); - } - } - - return $normalized; - } - - /** - * Create and return an UploadedFile instance from a $_FILES specification. - * - * If the specification represents an array of values, this method will - * delegate to normalizeNestedFileSpec() and return that return value. - * - * @param array $value $_FILES struct - * - * @return array|UploadedFileInterface - */ - private static function createUploadedFileFromSpec(array $value) - { - if (is_array($value['tmp_name'])) { - return self::normalizeNestedFileSpec($value); - } - - return new UploadedFile( - $value['tmp_name'], - (int) $value['size'], - (int) $value['error'], - $value['name'], - $value['type'] - ); - } - - /** - * Normalize an array of file specifications. - * - * Loops through all nested files and returns a normalized array of - * UploadedFileInterface instances. - * - * @param array $files - * - * @return UploadedFileInterface[] - */ - private static function normalizeNestedFileSpec(array $files = []) - { - $normalizedFiles = []; - - foreach (array_keys($files['tmp_name']) as $key) { - $spec = [ - 'tmp_name' => $files['tmp_name'][$key], - 'size' => $files['size'][$key], - 'error' => $files['error'][$key], - 'name' => $files['name'][$key], - 'type' => $files['type'][$key], - ]; - $normalizedFiles[$key] = self::createUploadedFileFromSpec($spec); - } - - return $normalizedFiles; - } - - /** - * Return a ServerRequest populated with superglobals: - * $_GET - * $_POST - * $_COOKIE - * $_FILES - * $_SERVER - * - * @return ServerRequestInterface - */ - public static function fromGlobals() - { - $method = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : 'GET'; - $headers = getallheaders(); - $uri = self::getUriFromGlobals(); - $body = new CachingStream(new LazyOpenStream('php://input', 'r+')); - $protocol = isset($_SERVER['SERVER_PROTOCOL']) ? str_replace('HTTP/', '', $_SERVER['SERVER_PROTOCOL']) : '1.1'; - - $serverRequest = new ServerRequest($method, $uri, $headers, $body, $protocol, $_SERVER); - - return $serverRequest - ->withCookieParams($_COOKIE) - ->withQueryParams($_GET) - ->withParsedBody($_POST) - ->withUploadedFiles(self::normalizeFiles($_FILES)); - } - - private static function extractHostAndPortFromAuthority($authority) - { - $uri = 'http://' . $authority; - $parts = parse_url($uri); - if (false === $parts) { - return [null, null]; - } - - $host = isset($parts['host']) ? $parts['host'] : null; - $port = isset($parts['port']) ? $parts['port'] : null; - - return [$host, $port]; - } - - /** - * Get a Uri populated with values from $_SERVER. - * - * @return UriInterface - */ - public static function getUriFromGlobals() - { - $uri = new Uri(''); - - $uri = $uri->withScheme(!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' ? 'https' : 'http'); - - $hasPort = false; - if (isset($_SERVER['HTTP_HOST'])) { - list($host, $port) = self::extractHostAndPortFromAuthority($_SERVER['HTTP_HOST']); - if ($host !== null) { - $uri = $uri->withHost($host); - } - - if ($port !== null) { - $hasPort = true; - $uri = $uri->withPort($port); - } - } elseif (isset($_SERVER['SERVER_NAME'])) { - $uri = $uri->withHost($_SERVER['SERVER_NAME']); - } elseif (isset($_SERVER['SERVER_ADDR'])) { - $uri = $uri->withHost($_SERVER['SERVER_ADDR']); - } - - if (!$hasPort && isset($_SERVER['SERVER_PORT'])) { - $uri = $uri->withPort($_SERVER['SERVER_PORT']); - } - - $hasQuery = false; - if (isset($_SERVER['REQUEST_URI'])) { - $requestUriParts = explode('?', $_SERVER['REQUEST_URI'], 2); - $uri = $uri->withPath($requestUriParts[0]); - if (isset($requestUriParts[1])) { - $hasQuery = true; - $uri = $uri->withQuery($requestUriParts[1]); - } - } - - if (!$hasQuery && isset($_SERVER['QUERY_STRING'])) { - $uri = $uri->withQuery($_SERVER['QUERY_STRING']); - } - - return $uri; - } - - /** - * {@inheritdoc} - */ - public function getServerParams() - { - return $this->serverParams; - } - - /** - * {@inheritdoc} - */ - public function getUploadedFiles() - { - return $this->uploadedFiles; - } - - /** - * {@inheritdoc} - */ - public function withUploadedFiles(array $uploadedFiles) - { - $new = clone $this; - $new->uploadedFiles = $uploadedFiles; - - return $new; - } - - /** - * {@inheritdoc} - */ - public function getCookieParams() - { - return $this->cookieParams; - } - - /** - * {@inheritdoc} - */ - public function withCookieParams(array $cookies) - { - $new = clone $this; - $new->cookieParams = $cookies; - - return $new; - } - - /** - * {@inheritdoc} - */ - public function getQueryParams() - { - return $this->queryParams; - } - - /** - * {@inheritdoc} - */ - public function withQueryParams(array $query) - { - $new = clone $this; - $new->queryParams = $query; - - return $new; - } - - /** - * {@inheritdoc} - */ - public function getParsedBody() - { - return $this->parsedBody; - } - - /** - * {@inheritdoc} - */ - public function withParsedBody($data) - { - $new = clone $this; - $new->parsedBody = $data; - - return $new; - } - - /** - * {@inheritdoc} - */ - public function getAttributes() - { - return $this->attributes; - } - - /** - * {@inheritdoc} - */ - public function getAttribute($attribute, $default = null) - { - if (false === array_key_exists($attribute, $this->attributes)) { - return $default; - } - - return $this->attributes[$attribute]; - } - - /** - * {@inheritdoc} - */ - public function withAttribute($attribute, $value) - { - $new = clone $this; - $new->attributes[$attribute] = $value; - - return $new; - } - - /** - * {@inheritdoc} - */ - public function withoutAttribute($attribute) - { - if (false === array_key_exists($attribute, $this->attributes)) { - return $this; - } - - $new = clone $this; - unset($new->attributes[$attribute]); - - return $new; - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/Stream.php b/plugins/automagic-images/vendor/guzzlehttp/psr7/src/Stream.php deleted file mode 100644 index 3865d6d..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/Stream.php +++ /dev/null @@ -1,270 +0,0 @@ -size = $options['size']; - } - - $this->customMetadata = isset($options['metadata']) - ? $options['metadata'] - : []; - - $this->stream = $stream; - $meta = stream_get_meta_data($this->stream); - $this->seekable = $meta['seekable']; - $this->readable = (bool)preg_match(self::READABLE_MODES, $meta['mode']); - $this->writable = (bool)preg_match(self::WRITABLE_MODES, $meta['mode']); - $this->uri = $this->getMetadata('uri'); - } - - /** - * Closes the stream when the destructed - */ - public function __destruct() - { - $this->close(); - } - - public function __toString() - { - try { - if ($this->isSeekable()) { - $this->seek(0); - } - return $this->getContents(); - } catch (\Exception $e) { - return ''; - } - } - - public function getContents() - { - if (!isset($this->stream)) { - throw new \RuntimeException('Stream is detached'); - } - - $contents = stream_get_contents($this->stream); - - if ($contents === false) { - throw new \RuntimeException('Unable to read stream contents'); - } - - return $contents; - } - - public function close() - { - if (isset($this->stream)) { - if (is_resource($this->stream)) { - fclose($this->stream); - } - $this->detach(); - } - } - - public function detach() - { - if (!isset($this->stream)) { - return null; - } - - $result = $this->stream; - unset($this->stream); - $this->size = $this->uri = null; - $this->readable = $this->writable = $this->seekable = false; - - return $result; - } - - public function getSize() - { - if ($this->size !== null) { - return $this->size; - } - - if (!isset($this->stream)) { - return null; - } - - // Clear the stat cache if the stream has a URI - if ($this->uri) { - clearstatcache(true, $this->uri); - } - - $stats = fstat($this->stream); - if (isset($stats['size'])) { - $this->size = $stats['size']; - return $this->size; - } - - return null; - } - - public function isReadable() - { - return $this->readable; - } - - public function isWritable() - { - return $this->writable; - } - - public function isSeekable() - { - return $this->seekable; - } - - public function eof() - { - if (!isset($this->stream)) { - throw new \RuntimeException('Stream is detached'); - } - - return feof($this->stream); - } - - public function tell() - { - if (!isset($this->stream)) { - throw new \RuntimeException('Stream is detached'); - } - - $result = ftell($this->stream); - - if ($result === false) { - throw new \RuntimeException('Unable to determine stream position'); - } - - return $result; - } - - public function rewind() - { - $this->seek(0); - } - - public function seek($offset, $whence = SEEK_SET) - { - $whence = (int) $whence; - - if (!isset($this->stream)) { - throw new \RuntimeException('Stream is detached'); - } - if (!$this->seekable) { - throw new \RuntimeException('Stream is not seekable'); - } - if (fseek($this->stream, $offset, $whence) === -1) { - throw new \RuntimeException('Unable to seek to stream position ' - . $offset . ' with whence ' . var_export($whence, true)); - } - } - - public function read($length) - { - if (!isset($this->stream)) { - throw new \RuntimeException('Stream is detached'); - } - if (!$this->readable) { - throw new \RuntimeException('Cannot read from non-readable stream'); - } - if ($length < 0) { - throw new \RuntimeException('Length parameter cannot be negative'); - } - - if (0 === $length) { - return ''; - } - - $string = fread($this->stream, $length); - if (false === $string) { - throw new \RuntimeException('Unable to read from stream'); - } - - return $string; - } - - public function write($string) - { - if (!isset($this->stream)) { - throw new \RuntimeException('Stream is detached'); - } - if (!$this->writable) { - throw new \RuntimeException('Cannot write to a non-writable stream'); - } - - // We can't know the size after writing anything - $this->size = null; - $result = fwrite($this->stream, $string); - - if ($result === false) { - throw new \RuntimeException('Unable to write to stream'); - } - - return $result; - } - - public function getMetadata($key = null) - { - if (!isset($this->stream)) { - return $key ? null : []; - } elseif (!$key) { - return $this->customMetadata + stream_get_meta_data($this->stream); - } elseif (isset($this->customMetadata[$key])) { - return $this->customMetadata[$key]; - } - - $meta = stream_get_meta_data($this->stream); - - return isset($meta[$key]) ? $meta[$key] : null; - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/StreamDecoratorTrait.php b/plugins/automagic-images/vendor/guzzlehttp/psr7/src/StreamDecoratorTrait.php deleted file mode 100644 index 5025dd6..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/StreamDecoratorTrait.php +++ /dev/null @@ -1,152 +0,0 @@ -stream = $stream; - } - - /** - * Magic method used to create a new stream if streams are not added in - * the constructor of a decorator (e.g., LazyOpenStream). - * - * @param string $name Name of the property (allows "stream" only). - * - * @return StreamInterface - */ - public function __get($name) - { - if ($name == 'stream') { - $this->stream = $this->createStream(); - return $this->stream; - } - - throw new \UnexpectedValueException("$name not found on class"); - } - - public function __toString() - { - try { - if ($this->isSeekable()) { - $this->seek(0); - } - return $this->getContents(); - } catch (\Exception $e) { - // Really, PHP? https://bugs.php.net/bug.php?id=53648 - trigger_error('StreamDecorator::__toString exception: ' - . (string) $e, E_USER_ERROR); - return ''; - } - } - - public function getContents() - { - return Utils::copyToString($this); - } - - /** - * Allow decorators to implement custom methods - * - * @param string $method Missing method name - * @param array $args Method arguments - * - * @return mixed - */ - public function __call($method, array $args) - { - $result = call_user_func_array([$this->stream, $method], $args); - - // Always return the wrapped object if the result is a return $this - return $result === $this->stream ? $this : $result; - } - - public function close() - { - $this->stream->close(); - } - - public function getMetadata($key = null) - { - return $this->stream->getMetadata($key); - } - - public function detach() - { - return $this->stream->detach(); - } - - public function getSize() - { - return $this->stream->getSize(); - } - - public function eof() - { - return $this->stream->eof(); - } - - public function tell() - { - return $this->stream->tell(); - } - - public function isReadable() - { - return $this->stream->isReadable(); - } - - public function isWritable() - { - return $this->stream->isWritable(); - } - - public function isSeekable() - { - return $this->stream->isSeekable(); - } - - public function rewind() - { - $this->seek(0); - } - - public function seek($offset, $whence = SEEK_SET) - { - $this->stream->seek($offset, $whence); - } - - public function read($length) - { - return $this->stream->read($length); - } - - public function write($string) - { - return $this->stream->write($string); - } - - /** - * Implement in subclasses to dynamically create streams when requested. - * - * @return StreamInterface - * - * @throws \BadMethodCallException - */ - protected function createStream() - { - throw new \BadMethodCallException('Not implemented'); - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/StreamWrapper.php b/plugins/automagic-images/vendor/guzzlehttp/psr7/src/StreamWrapper.php deleted file mode 100644 index fc7cb96..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/StreamWrapper.php +++ /dev/null @@ -1,165 +0,0 @@ -isReadable()) { - $mode = $stream->isWritable() ? 'r+' : 'r'; - } elseif ($stream->isWritable()) { - $mode = 'w'; - } else { - throw new \InvalidArgumentException('The stream must be readable, ' - . 'writable, or both.'); - } - - return fopen('guzzle://stream', $mode, null, self::createStreamContext($stream)); - } - - /** - * Creates a stream context that can be used to open a stream as a php stream resource. - * - * @param StreamInterface $stream - * - * @return resource - */ - public static function createStreamContext(StreamInterface $stream) - { - return stream_context_create([ - 'guzzle' => ['stream' => $stream] - ]); - } - - /** - * Registers the stream wrapper if needed - */ - public static function register() - { - if (!in_array('guzzle', stream_get_wrappers())) { - stream_wrapper_register('guzzle', __CLASS__); - } - } - - public function stream_open($path, $mode, $options, &$opened_path) - { - $options = stream_context_get_options($this->context); - - if (!isset($options['guzzle']['stream'])) { - return false; - } - - $this->mode = $mode; - $this->stream = $options['guzzle']['stream']; - - return true; - } - - public function stream_read($count) - { - return $this->stream->read($count); - } - - public function stream_write($data) - { - return (int) $this->stream->write($data); - } - - public function stream_tell() - { - return $this->stream->tell(); - } - - public function stream_eof() - { - return $this->stream->eof(); - } - - public function stream_seek($offset, $whence) - { - $this->stream->seek($offset, $whence); - - return true; - } - - public function stream_cast($cast_as) - { - $stream = clone($this->stream); - - return $stream->detach(); - } - - public function stream_stat() - { - static $modeMap = [ - 'r' => 33060, - 'rb' => 33060, - 'r+' => 33206, - 'w' => 33188, - 'wb' => 33188 - ]; - - return [ - 'dev' => 0, - 'ino' => 0, - 'mode' => $modeMap[$this->mode], - 'nlink' => 0, - 'uid' => 0, - 'gid' => 0, - 'rdev' => 0, - 'size' => $this->stream->getSize() ?: 0, - 'atime' => 0, - 'mtime' => 0, - 'ctime' => 0, - 'blksize' => 0, - 'blocks' => 0 - ]; - } - - public function url_stat($path, $flags) - { - return [ - 'dev' => 0, - 'ino' => 0, - 'mode' => 0, - 'nlink' => 0, - 'uid' => 0, - 'gid' => 0, - 'rdev' => 0, - 'size' => 0, - 'atime' => 0, - 'mtime' => 0, - 'ctime' => 0, - 'blksize' => 0, - 'blocks' => 0 - ]; - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/UploadedFile.php b/plugins/automagic-images/vendor/guzzlehttp/psr7/src/UploadedFile.php deleted file mode 100644 index bf342c4..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/UploadedFile.php +++ /dev/null @@ -1,328 +0,0 @@ -setError($errorStatus); - $this->setSize($size); - $this->setClientFilename($clientFilename); - $this->setClientMediaType($clientMediaType); - - if ($this->isOk()) { - $this->setStreamOrFile($streamOrFile); - } - } - - /** - * Depending on the value set file or stream variable - * - * @param mixed $streamOrFile - * - * @throws InvalidArgumentException - */ - private function setStreamOrFile($streamOrFile) - { - if (is_string($streamOrFile)) { - $this->file = $streamOrFile; - } elseif (is_resource($streamOrFile)) { - $this->stream = new Stream($streamOrFile); - } elseif ($streamOrFile instanceof StreamInterface) { - $this->stream = $streamOrFile; - } else { - throw new InvalidArgumentException( - 'Invalid stream or file provided for UploadedFile' - ); - } - } - - /** - * @param int $error - * - * @throws InvalidArgumentException - */ - private function setError($error) - { - if (false === is_int($error)) { - throw new InvalidArgumentException( - 'Upload file error status must be an integer' - ); - } - - if (false === in_array($error, UploadedFile::$errors)) { - throw new InvalidArgumentException( - 'Invalid error status for UploadedFile' - ); - } - - $this->error = $error; - } - - /** - * @param int $size - * - * @throws InvalidArgumentException - */ - private function setSize($size) - { - if (false === is_int($size)) { - throw new InvalidArgumentException( - 'Upload file size must be an integer' - ); - } - - $this->size = $size; - } - - /** - * @param mixed $param - * - * @return bool - */ - private function isStringOrNull($param) - { - return in_array(gettype($param), ['string', 'NULL']); - } - - /** - * @param mixed $param - * - * @return bool - */ - private function isStringNotEmpty($param) - { - return is_string($param) && false === empty($param); - } - - /** - * @param string|null $clientFilename - * - * @throws InvalidArgumentException - */ - private function setClientFilename($clientFilename) - { - if (false === $this->isStringOrNull($clientFilename)) { - throw new InvalidArgumentException( - 'Upload file client filename must be a string or null' - ); - } - - $this->clientFilename = $clientFilename; - } - - /** - * @param string|null $clientMediaType - * - * @throws InvalidArgumentException - */ - private function setClientMediaType($clientMediaType) - { - if (false === $this->isStringOrNull($clientMediaType)) { - throw new InvalidArgumentException( - 'Upload file client media type must be a string or null' - ); - } - - $this->clientMediaType = $clientMediaType; - } - - /** - * Return true if there is no upload error - * - * @return bool - */ - private function isOk() - { - return $this->error === UPLOAD_ERR_OK; - } - - /** - * @return bool - */ - public function isMoved() - { - return $this->moved; - } - - /** - * @throws RuntimeException if is moved or not ok - */ - private function validateActive() - { - if (false === $this->isOk()) { - throw new RuntimeException('Cannot retrieve stream due to upload error'); - } - - if ($this->isMoved()) { - throw new RuntimeException('Cannot retrieve stream after it has already been moved'); - } - } - - /** - * {@inheritdoc} - * - * @throws RuntimeException if the upload was not successful. - */ - public function getStream() - { - $this->validateActive(); - - if ($this->stream instanceof StreamInterface) { - return $this->stream; - } - - return new LazyOpenStream($this->file, 'r+'); - } - - /** - * {@inheritdoc} - * - * @see http://php.net/is_uploaded_file - * @see http://php.net/move_uploaded_file - * - * @param string $targetPath Path to which to move the uploaded file. - * - * @throws RuntimeException if the upload was not successful. - * @throws InvalidArgumentException if the $path specified is invalid. - * @throws RuntimeException on any error during the move operation, or on - * the second or subsequent call to the method. - */ - public function moveTo($targetPath) - { - $this->validateActive(); - - if (false === $this->isStringNotEmpty($targetPath)) { - throw new InvalidArgumentException( - 'Invalid path provided for move operation; must be a non-empty string' - ); - } - - if ($this->file) { - $this->moved = php_sapi_name() == 'cli' - ? rename($this->file, $targetPath) - : move_uploaded_file($this->file, $targetPath); - } else { - Utils::copyToStream( - $this->getStream(), - new LazyOpenStream($targetPath, 'w') - ); - - $this->moved = true; - } - - if (false === $this->moved) { - throw new RuntimeException( - sprintf('Uploaded file could not be moved to %s', $targetPath) - ); - } - } - - /** - * {@inheritdoc} - * - * @return int|null The file size in bytes or null if unknown. - */ - public function getSize() - { - return $this->size; - } - - /** - * {@inheritdoc} - * - * @see http://php.net/manual/en/features.file-upload.errors.php - * - * @return int One of PHP's UPLOAD_ERR_XXX constants. - */ - public function getError() - { - return $this->error; - } - - /** - * {@inheritdoc} - * - * @return string|null The filename sent by the client or null if none - * was provided. - */ - public function getClientFilename() - { - return $this->clientFilename; - } - - /** - * {@inheritdoc} - */ - public function getClientMediaType() - { - return $this->clientMediaType; - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/Uri.php b/plugins/automagic-images/vendor/guzzlehttp/psr7/src/Uri.php deleted file mode 100644 index 0f9f020..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/Uri.php +++ /dev/null @@ -1,810 +0,0 @@ - 80, - 'https' => 443, - 'ftp' => 21, - 'gopher' => 70, - 'nntp' => 119, - 'news' => 119, - 'telnet' => 23, - 'tn3270' => 23, - 'imap' => 143, - 'pop' => 110, - 'ldap' => 389, - ]; - - private static $charUnreserved = 'a-zA-Z0-9_\-\.~'; - private static $charSubDelims = '!\$&\'\(\)\*\+,;='; - private static $replaceQuery = ['=' => '%3D', '&' => '%26']; - - /** @var string Uri scheme. */ - private $scheme = ''; - - /** @var string Uri user info. */ - private $userInfo = ''; - - /** @var string Uri host. */ - private $host = ''; - - /** @var int|null Uri port. */ - private $port; - - /** @var string Uri path. */ - private $path = ''; - - /** @var string Uri query string. */ - private $query = ''; - - /** @var string Uri fragment. */ - private $fragment = ''; - - /** - * @param string $uri URI to parse - */ - public function __construct($uri = '') - { - // weak type check to also accept null until we can add scalar type hints - if ($uri != '') { - $parts = self::parse($uri); - if ($parts === false) { - throw new \InvalidArgumentException("Unable to parse URI: $uri"); - } - $this->applyParts($parts); - } - } - - /** - * UTF-8 aware \parse_url() replacement. - * - * The internal function produces broken output for non ASCII domain names - * (IDN) when used with locales other than "C". - * - * On the other hand, cURL understands IDN correctly only when UTF-8 locale - * is configured ("C.UTF-8", "en_US.UTF-8", etc.). - * - * @see https://bugs.php.net/bug.php?id=52923 - * @see https://www.php.net/manual/en/function.parse-url.php#114817 - * @see https://curl.haxx.se/libcurl/c/CURLOPT_URL.html#ENCODING - * - * @param string $url - * - * @return array|false - */ - private static function parse($url) - { - // If IPv6 - $prefix = ''; - if (preg_match('%^(.*://\[[0-9:a-f]+\])(.*?)$%', $url, $matches)) { - $prefix = $matches[1]; - $url = $matches[2]; - } - - $encodedUrl = preg_replace_callback( - '%[^:/@?&=#]+%usD', - static function ($matches) { - return urlencode($matches[0]); - }, - $url - ); - - $result = parse_url($prefix . $encodedUrl); - - if ($result === false) { - return false; - } - - return array_map('urldecode', $result); - } - - public function __toString() - { - return self::composeComponents( - $this->scheme, - $this->getAuthority(), - $this->path, - $this->query, - $this->fragment - ); - } - - /** - * Composes a URI reference string from its various components. - * - * Usually this method does not need to be called manually but instead is used indirectly via - * `Psr\Http\Message\UriInterface::__toString`. - * - * PSR-7 UriInterface treats an empty component the same as a missing component as - * getQuery(), getFragment() etc. always return a string. This explains the slight - * difference to RFC 3986 Section 5.3. - * - * Another adjustment is that the authority separator is added even when the authority is missing/empty - * for the "file" scheme. This is because PHP stream functions like `file_get_contents` only work with - * `file:///myfile` but not with `file:/myfile` although they are equivalent according to RFC 3986. But - * `file:///` is the more common syntax for the file scheme anyway (Chrome for example redirects to - * that format). - * - * @param string $scheme - * @param string $authority - * @param string $path - * @param string $query - * @param string $fragment - * - * @return string - * - * @link https://tools.ietf.org/html/rfc3986#section-5.3 - */ - public static function composeComponents($scheme, $authority, $path, $query, $fragment) - { - $uri = ''; - - // weak type checks to also accept null until we can add scalar type hints - if ($scheme != '') { - $uri .= $scheme . ':'; - } - - if ($authority != ''|| $scheme === 'file') { - $uri .= '//' . $authority; - } - - $uri .= $path; - - if ($query != '') { - $uri .= '?' . $query; - } - - if ($fragment != '') { - $uri .= '#' . $fragment; - } - - return $uri; - } - - /** - * Whether the URI has the default port of the current scheme. - * - * `Psr\Http\Message\UriInterface::getPort` may return null or the standard port. This method can be used - * independently of the implementation. - * - * @param UriInterface $uri - * - * @return bool - */ - public static function isDefaultPort(UriInterface $uri) - { - return $uri->getPort() === null - || (isset(self::$defaultPorts[$uri->getScheme()]) && $uri->getPort() === self::$defaultPorts[$uri->getScheme()]); - } - - /** - * Whether the URI is absolute, i.e. it has a scheme. - * - * An instance of UriInterface can either be an absolute URI or a relative reference. This method returns true - * if it is the former. An absolute URI has a scheme. A relative reference is used to express a URI relative - * to another URI, the base URI. Relative references can be divided into several forms: - * - network-path references, e.g. '//example.com/path' - * - absolute-path references, e.g. '/path' - * - relative-path references, e.g. 'subpath' - * - * @param UriInterface $uri - * - * @return bool - * - * @see Uri::isNetworkPathReference - * @see Uri::isAbsolutePathReference - * @see Uri::isRelativePathReference - * @link https://tools.ietf.org/html/rfc3986#section-4 - */ - public static function isAbsolute(UriInterface $uri) - { - return $uri->getScheme() !== ''; - } - - /** - * Whether the URI is a network-path reference. - * - * A relative reference that begins with two slash characters is termed an network-path reference. - * - * @param UriInterface $uri - * - * @return bool - * - * @link https://tools.ietf.org/html/rfc3986#section-4.2 - */ - public static function isNetworkPathReference(UriInterface $uri) - { - return $uri->getScheme() === '' && $uri->getAuthority() !== ''; - } - - /** - * Whether the URI is a absolute-path reference. - * - * A relative reference that begins with a single slash character is termed an absolute-path reference. - * - * @param UriInterface $uri - * - * @return bool - * - * @link https://tools.ietf.org/html/rfc3986#section-4.2 - */ - public static function isAbsolutePathReference(UriInterface $uri) - { - return $uri->getScheme() === '' - && $uri->getAuthority() === '' - && isset($uri->getPath()[0]) - && $uri->getPath()[0] === '/'; - } - - /** - * Whether the URI is a relative-path reference. - * - * A relative reference that does not begin with a slash character is termed a relative-path reference. - * - * @param UriInterface $uri - * - * @return bool - * - * @link https://tools.ietf.org/html/rfc3986#section-4.2 - */ - public static function isRelativePathReference(UriInterface $uri) - { - return $uri->getScheme() === '' - && $uri->getAuthority() === '' - && (!isset($uri->getPath()[0]) || $uri->getPath()[0] !== '/'); - } - - /** - * Whether the URI is a same-document reference. - * - * A same-document reference refers to a URI that is, aside from its fragment - * component, identical to the base URI. When no base URI is given, only an empty - * URI reference (apart from its fragment) is considered a same-document reference. - * - * @param UriInterface $uri The URI to check - * @param UriInterface|null $base An optional base URI to compare against - * - * @return bool - * - * @link https://tools.ietf.org/html/rfc3986#section-4.4 - */ - public static function isSameDocumentReference(UriInterface $uri, UriInterface $base = null) - { - if ($base !== null) { - $uri = UriResolver::resolve($base, $uri); - - return ($uri->getScheme() === $base->getScheme()) - && ($uri->getAuthority() === $base->getAuthority()) - && ($uri->getPath() === $base->getPath()) - && ($uri->getQuery() === $base->getQuery()); - } - - return $uri->getScheme() === '' && $uri->getAuthority() === '' && $uri->getPath() === '' && $uri->getQuery() === ''; - } - - /** - * Removes dot segments from a path and returns the new path. - * - * @param string $path - * - * @return string - * - * @deprecated since version 1.4. Use UriResolver::removeDotSegments instead. - * @see UriResolver::removeDotSegments - */ - public static function removeDotSegments($path) - { - return UriResolver::removeDotSegments($path); - } - - /** - * Converts the relative URI into a new URI that is resolved against the base URI. - * - * @param UriInterface $base Base URI - * @param string|UriInterface $rel Relative URI - * - * @return UriInterface - * - * @deprecated since version 1.4. Use UriResolver::resolve instead. - * @see UriResolver::resolve - */ - public static function resolve(UriInterface $base, $rel) - { - if (!($rel instanceof UriInterface)) { - $rel = new self($rel); - } - - return UriResolver::resolve($base, $rel); - } - - /** - * Creates a new URI with a specific query string value removed. - * - * Any existing query string values that exactly match the provided key are - * removed. - * - * @param UriInterface $uri URI to use as a base. - * @param string $key Query string key to remove. - * - * @return UriInterface - */ - public static function withoutQueryValue(UriInterface $uri, $key) - { - $result = self::getFilteredQueryString($uri, [$key]); - - return $uri->withQuery(implode('&', $result)); - } - - /** - * Creates a new URI with a specific query string value. - * - * Any existing query string values that exactly match the provided key are - * removed and replaced with the given key value pair. - * - * A value of null will set the query string key without a value, e.g. "key" - * instead of "key=value". - * - * @param UriInterface $uri URI to use as a base. - * @param string $key Key to set. - * @param string|null $value Value to set - * - * @return UriInterface - */ - public static function withQueryValue(UriInterface $uri, $key, $value) - { - $result = self::getFilteredQueryString($uri, [$key]); - - $result[] = self::generateQueryString($key, $value); - - return $uri->withQuery(implode('&', $result)); - } - - /** - * Creates a new URI with multiple specific query string values. - * - * It has the same behavior as withQueryValue() but for an associative array of key => value. - * - * @param UriInterface $uri URI to use as a base. - * @param array $keyValueArray Associative array of key and values - * - * @return UriInterface - */ - public static function withQueryValues(UriInterface $uri, array $keyValueArray) - { - $result = self::getFilteredQueryString($uri, array_keys($keyValueArray)); - - foreach ($keyValueArray as $key => $value) { - $result[] = self::generateQueryString($key, $value); - } - - return $uri->withQuery(implode('&', $result)); - } - - /** - * Creates a URI from a hash of `parse_url` components. - * - * @param array $parts - * - * @return UriInterface - * - * @link http://php.net/manual/en/function.parse-url.php - * - * @throws \InvalidArgumentException If the components do not form a valid URI. - */ - public static function fromParts(array $parts) - { - $uri = new self(); - $uri->applyParts($parts); - $uri->validateState(); - - return $uri; - } - - public function getScheme() - { - return $this->scheme; - } - - public function getAuthority() - { - $authority = $this->host; - if ($this->userInfo !== '') { - $authority = $this->userInfo . '@' . $authority; - } - - if ($this->port !== null) { - $authority .= ':' . $this->port; - } - - return $authority; - } - - public function getUserInfo() - { - return $this->userInfo; - } - - public function getHost() - { - return $this->host; - } - - public function getPort() - { - return $this->port; - } - - public function getPath() - { - return $this->path; - } - - public function getQuery() - { - return $this->query; - } - - public function getFragment() - { - return $this->fragment; - } - - public function withScheme($scheme) - { - $scheme = $this->filterScheme($scheme); - - if ($this->scheme === $scheme) { - return $this; - } - - $new = clone $this; - $new->scheme = $scheme; - $new->removeDefaultPort(); - $new->validateState(); - - return $new; - } - - public function withUserInfo($user, $password = null) - { - $info = $this->filterUserInfoComponent($user); - if ($password !== null) { - $info .= ':' . $this->filterUserInfoComponent($password); - } - - if ($this->userInfo === $info) { - return $this; - } - - $new = clone $this; - $new->userInfo = $info; - $new->validateState(); - - return $new; - } - - public function withHost($host) - { - $host = $this->filterHost($host); - - if ($this->host === $host) { - return $this; - } - - $new = clone $this; - $new->host = $host; - $new->validateState(); - - return $new; - } - - public function withPort($port) - { - $port = $this->filterPort($port); - - if ($this->port === $port) { - return $this; - } - - $new = clone $this; - $new->port = $port; - $new->removeDefaultPort(); - $new->validateState(); - - return $new; - } - - public function withPath($path) - { - $path = $this->filterPath($path); - - if ($this->path === $path) { - return $this; - } - - $new = clone $this; - $new->path = $path; - $new->validateState(); - - return $new; - } - - public function withQuery($query) - { - $query = $this->filterQueryAndFragment($query); - - if ($this->query === $query) { - return $this; - } - - $new = clone $this; - $new->query = $query; - - return $new; - } - - public function withFragment($fragment) - { - $fragment = $this->filterQueryAndFragment($fragment); - - if ($this->fragment === $fragment) { - return $this; - } - - $new = clone $this; - $new->fragment = $fragment; - - return $new; - } - - /** - * Apply parse_url parts to a URI. - * - * @param array $parts Array of parse_url parts to apply. - */ - private function applyParts(array $parts) - { - $this->scheme = isset($parts['scheme']) - ? $this->filterScheme($parts['scheme']) - : ''; - $this->userInfo = isset($parts['user']) - ? $this->filterUserInfoComponent($parts['user']) - : ''; - $this->host = isset($parts['host']) - ? $this->filterHost($parts['host']) - : ''; - $this->port = isset($parts['port']) - ? $this->filterPort($parts['port']) - : null; - $this->path = isset($parts['path']) - ? $this->filterPath($parts['path']) - : ''; - $this->query = isset($parts['query']) - ? $this->filterQueryAndFragment($parts['query']) - : ''; - $this->fragment = isset($parts['fragment']) - ? $this->filterQueryAndFragment($parts['fragment']) - : ''; - if (isset($parts['pass'])) { - $this->userInfo .= ':' . $this->filterUserInfoComponent($parts['pass']); - } - - $this->removeDefaultPort(); - } - - /** - * @param string $scheme - * - * @return string - * - * @throws \InvalidArgumentException If the scheme is invalid. - */ - private function filterScheme($scheme) - { - if (!is_string($scheme)) { - throw new \InvalidArgumentException('Scheme must be a string'); - } - - return \strtr($scheme, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'); - } - - /** - * @param string $component - * - * @return string - * - * @throws \InvalidArgumentException If the user info is invalid. - */ - private function filterUserInfoComponent($component) - { - if (!is_string($component)) { - throw new \InvalidArgumentException('User info must be a string'); - } - - return preg_replace_callback( - '/(?:[^%' . self::$charUnreserved . self::$charSubDelims . ']+|%(?![A-Fa-f0-9]{2}))/', - [$this, 'rawurlencodeMatchZero'], - $component - ); - } - - /** - * @param string $host - * - * @return string - * - * @throws \InvalidArgumentException If the host is invalid. - */ - private function filterHost($host) - { - if (!is_string($host)) { - throw new \InvalidArgumentException('Host must be a string'); - } - - return \strtr($host, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'); - } - - /** - * @param int|null $port - * - * @return int|null - * - * @throws \InvalidArgumentException If the port is invalid. - */ - private function filterPort($port) - { - if ($port === null) { - return null; - } - - $port = (int) $port; - if (0 > $port || 0xffff < $port) { - throw new \InvalidArgumentException( - sprintf('Invalid port: %d. Must be between 0 and 65535', $port) - ); - } - - return $port; - } - - /** - * @param UriInterface $uri - * @param array $keys - * - * @return array - */ - private static function getFilteredQueryString(UriInterface $uri, array $keys) - { - $current = $uri->getQuery(); - - if ($current === '') { - return []; - } - - $decodedKeys = array_map('rawurldecode', $keys); - - return array_filter(explode('&', $current), function ($part) use ($decodedKeys) { - return !in_array(rawurldecode(explode('=', $part)[0]), $decodedKeys, true); - }); - } - - /** - * @param string $key - * @param string|null $value - * - * @return string - */ - private static function generateQueryString($key, $value) - { - // Query string separators ("=", "&") within the key or value need to be encoded - // (while preventing double-encoding) before setting the query string. All other - // chars that need percent-encoding will be encoded by withQuery(). - $queryString = strtr($key, self::$replaceQuery); - - if ($value !== null) { - $queryString .= '=' . strtr($value, self::$replaceQuery); - } - - return $queryString; - } - - private function removeDefaultPort() - { - if ($this->port !== null && self::isDefaultPort($this)) { - $this->port = null; - } - } - - /** - * Filters the path of a URI - * - * @param string $path - * - * @return string - * - * @throws \InvalidArgumentException If the path is invalid. - */ - private function filterPath($path) - { - if (!is_string($path)) { - throw new \InvalidArgumentException('Path must be a string'); - } - - return preg_replace_callback( - '/(?:[^' . self::$charUnreserved . self::$charSubDelims . '%:@\/]++|%(?![A-Fa-f0-9]{2}))/', - [$this, 'rawurlencodeMatchZero'], - $path - ); - } - - /** - * Filters the query string or fragment of a URI. - * - * @param string $str - * - * @return string - * - * @throws \InvalidArgumentException If the query or fragment is invalid. - */ - private function filterQueryAndFragment($str) - { - if (!is_string($str)) { - throw new \InvalidArgumentException('Query and fragment must be a string'); - } - - return preg_replace_callback( - '/(?:[^' . self::$charUnreserved . self::$charSubDelims . '%:@\/\?]++|%(?![A-Fa-f0-9]{2}))/', - [$this, 'rawurlencodeMatchZero'], - $str - ); - } - - private function rawurlencodeMatchZero(array $match) - { - return rawurlencode($match[0]); - } - - private function validateState() - { - if ($this->host === '' && ($this->scheme === 'http' || $this->scheme === 'https')) { - $this->host = self::HTTP_DEFAULT_HOST; - } - - if ($this->getAuthority() === '') { - if (0 === strpos($this->path, '//')) { - throw new \InvalidArgumentException('The path of a URI without an authority must not start with two slashes "//"'); - } - if ($this->scheme === '' && false !== strpos(explode('/', $this->path, 2)[0], ':')) { - throw new \InvalidArgumentException('A relative URI must not have a path beginning with a segment containing a colon'); - } - } elseif (isset($this->path[0]) && $this->path[0] !== '/') { - @trigger_error( - 'The path of a URI with an authority must start with a slash "/" or be empty. Automagically fixing the URI ' . - 'by adding a leading slash to the path is deprecated since version 1.4 and will throw an exception instead.', - E_USER_DEPRECATED - ); - $this->path = '/' . $this->path; - //throw new \InvalidArgumentException('The path of a URI with an authority must start with a slash "/" or be empty'); - } - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/UriNormalizer.php b/plugins/automagic-images/vendor/guzzlehttp/psr7/src/UriNormalizer.php deleted file mode 100644 index 81419ea..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/UriNormalizer.php +++ /dev/null @@ -1,219 +0,0 @@ -getPath() === '' && - ($uri->getScheme() === 'http' || $uri->getScheme() === 'https') - ) { - $uri = $uri->withPath('/'); - } - - if ($flags & self::REMOVE_DEFAULT_HOST && $uri->getScheme() === 'file' && $uri->getHost() === 'localhost') { - $uri = $uri->withHost(''); - } - - if ($flags & self::REMOVE_DEFAULT_PORT && $uri->getPort() !== null && Uri::isDefaultPort($uri)) { - $uri = $uri->withPort(null); - } - - if ($flags & self::REMOVE_DOT_SEGMENTS && !Uri::isRelativePathReference($uri)) { - $uri = $uri->withPath(UriResolver::removeDotSegments($uri->getPath())); - } - - if ($flags & self::REMOVE_DUPLICATE_SLASHES) { - $uri = $uri->withPath(preg_replace('#//++#', '/', $uri->getPath())); - } - - if ($flags & self::SORT_QUERY_PARAMETERS && $uri->getQuery() !== '') { - $queryKeyValues = explode('&', $uri->getQuery()); - sort($queryKeyValues); - $uri = $uri->withQuery(implode('&', $queryKeyValues)); - } - - return $uri; - } - - /** - * Whether two URIs can be considered equivalent. - * - * Both URIs are normalized automatically before comparison with the given $normalizations bitmask. The method also - * accepts relative URI references and returns true when they are equivalent. This of course assumes they will be - * resolved against the same base URI. If this is not the case, determination of equivalence or difference of - * relative references does not mean anything. - * - * @param UriInterface $uri1 An URI to compare - * @param UriInterface $uri2 An URI to compare - * @param int $normalizations A bitmask of normalizations to apply, see constants - * - * @return bool - * - * @link https://tools.ietf.org/html/rfc3986#section-6.1 - */ - public static function isEquivalent(UriInterface $uri1, UriInterface $uri2, $normalizations = self::PRESERVING_NORMALIZATIONS) - { - return (string) self::normalize($uri1, $normalizations) === (string) self::normalize($uri2, $normalizations); - } - - private static function capitalizePercentEncoding(UriInterface $uri) - { - $regex = '/(?:%[A-Fa-f0-9]{2})++/'; - - $callback = function (array $match) { - return strtoupper($match[0]); - }; - - return - $uri->withPath( - preg_replace_callback($regex, $callback, $uri->getPath()) - )->withQuery( - preg_replace_callback($regex, $callback, $uri->getQuery()) - ); - } - - private static function decodeUnreservedCharacters(UriInterface $uri) - { - $regex = '/%(?:2D|2E|5F|7E|3[0-9]|[46][1-9A-F]|[57][0-9A])/i'; - - $callback = function (array $match) { - return rawurldecode($match[0]); - }; - - return - $uri->withPath( - preg_replace_callback($regex, $callback, $uri->getPath()) - )->withQuery( - preg_replace_callback($regex, $callback, $uri->getQuery()) - ); - } - - private function __construct() - { - // cannot be instantiated - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/UriResolver.php b/plugins/automagic-images/vendor/guzzlehttp/psr7/src/UriResolver.php deleted file mode 100644 index a3cb15d..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/UriResolver.php +++ /dev/null @@ -1,222 +0,0 @@ -getScheme() != '') { - return $rel->withPath(self::removeDotSegments($rel->getPath())); - } - - if ($rel->getAuthority() != '') { - $targetAuthority = $rel->getAuthority(); - $targetPath = self::removeDotSegments($rel->getPath()); - $targetQuery = $rel->getQuery(); - } else { - $targetAuthority = $base->getAuthority(); - if ($rel->getPath() === '') { - $targetPath = $base->getPath(); - $targetQuery = $rel->getQuery() != '' ? $rel->getQuery() : $base->getQuery(); - } else { - if ($rel->getPath()[0] === '/') { - $targetPath = $rel->getPath(); - } else { - if ($targetAuthority != '' && $base->getPath() === '') { - $targetPath = '/' . $rel->getPath(); - } else { - $lastSlashPos = strrpos($base->getPath(), '/'); - if ($lastSlashPos === false) { - $targetPath = $rel->getPath(); - } else { - $targetPath = substr($base->getPath(), 0, $lastSlashPos + 1) . $rel->getPath(); - } - } - } - $targetPath = self::removeDotSegments($targetPath); - $targetQuery = $rel->getQuery(); - } - } - - return new Uri(Uri::composeComponents( - $base->getScheme(), - $targetAuthority, - $targetPath, - $targetQuery, - $rel->getFragment() - )); - } - - /** - * Returns the target URI as a relative reference from the base URI. - * - * This method is the counterpart to resolve(): - * - * (string) $target === (string) UriResolver::resolve($base, UriResolver::relativize($base, $target)) - * - * One use-case is to use the current request URI as base URI and then generate relative links in your documents - * to reduce the document size or offer self-contained downloadable document archives. - * - * $base = new Uri('http://example.com/a/b/'); - * echo UriResolver::relativize($base, new Uri('http://example.com/a/b/c')); // prints 'c'. - * echo UriResolver::relativize($base, new Uri('http://example.com/a/x/y')); // prints '../x/y'. - * echo UriResolver::relativize($base, new Uri('http://example.com/a/b/?q')); // prints '?q'. - * echo UriResolver::relativize($base, new Uri('http://example.org/a/b/')); // prints '//example.org/a/b/'. - * - * This method also accepts a target that is already relative and will try to relativize it further. Only a - * relative-path reference will be returned as-is. - * - * echo UriResolver::relativize($base, new Uri('/a/b/c')); // prints 'c' as well - * - * @param UriInterface $base Base URI - * @param UriInterface $target Target URI - * - * @return UriInterface The relative URI reference - */ - public static function relativize(UriInterface $base, UriInterface $target) - { - if ($target->getScheme() !== '' && - ($base->getScheme() !== $target->getScheme() || $target->getAuthority() === '' && $base->getAuthority() !== '') - ) { - return $target; - } - - if (Uri::isRelativePathReference($target)) { - // As the target is already highly relative we return it as-is. It would be possible to resolve - // the target with `$target = self::resolve($base, $target);` and then try make it more relative - // by removing a duplicate query. But let's not do that automatically. - return $target; - } - - if ($target->getAuthority() !== '' && $base->getAuthority() !== $target->getAuthority()) { - return $target->withScheme(''); - } - - // We must remove the path before removing the authority because if the path starts with two slashes, the URI - // would turn invalid. And we also cannot set a relative path before removing the authority, as that is also - // invalid. - $emptyPathUri = $target->withScheme('')->withPath('')->withUserInfo('')->withPort(null)->withHost(''); - - if ($base->getPath() !== $target->getPath()) { - return $emptyPathUri->withPath(self::getRelativePath($base, $target)); - } - - if ($base->getQuery() === $target->getQuery()) { - // Only the target fragment is left. And it must be returned even if base and target fragment are the same. - return $emptyPathUri->withQuery(''); - } - - // If the base URI has a query but the target has none, we cannot return an empty path reference as it would - // inherit the base query component when resolving. - if ($target->getQuery() === '') { - $segments = explode('/', $target->getPath()); - $lastSegment = end($segments); - - return $emptyPathUri->withPath($lastSegment === '' ? './' : $lastSegment); - } - - return $emptyPathUri; - } - - private static function getRelativePath(UriInterface $base, UriInterface $target) - { - $sourceSegments = explode('/', $base->getPath()); - $targetSegments = explode('/', $target->getPath()); - array_pop($sourceSegments); - $targetLastSegment = array_pop($targetSegments); - foreach ($sourceSegments as $i => $segment) { - if (isset($targetSegments[$i]) && $segment === $targetSegments[$i]) { - unset($sourceSegments[$i], $targetSegments[$i]); - } else { - break; - } - } - $targetSegments[] = $targetLastSegment; - $relativePath = str_repeat('../', count($sourceSegments)) . implode('/', $targetSegments); - - // A reference to am empty last segment or an empty first sub-segment must be prefixed with "./". - // This also applies to a segment with a colon character (e.g., "file:colon") that cannot be used - // as the first segment of a relative-path reference, as it would be mistaken for a scheme name. - if ('' === $relativePath || false !== strpos(explode('/', $relativePath, 2)[0], ':')) { - $relativePath = "./$relativePath"; - } elseif ('/' === $relativePath[0]) { - if ($base->getAuthority() != '' && $base->getPath() === '') { - // In this case an extra slash is added by resolve() automatically. So we must not add one here. - $relativePath = ".$relativePath"; - } else { - $relativePath = "./$relativePath"; - } - } - - return $relativePath; - } - - private function __construct() - { - // cannot be instantiated - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/Utils.php b/plugins/automagic-images/vendor/guzzlehttp/psr7/src/Utils.php deleted file mode 100644 index 6b6c8cc..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/Utils.php +++ /dev/null @@ -1,428 +0,0 @@ - $keys - * - * @return array - */ - public static function caselessRemove($keys, array $data) - { - $result = []; - - foreach ($keys as &$key) { - $key = strtolower($key); - } - - foreach ($data as $k => $v) { - if (!in_array(strtolower($k), $keys)) { - $result[$k] = $v; - } - } - - return $result; - } - - /** - * Copy the contents of a stream into another stream until the given number - * of bytes have been read. - * - * @param StreamInterface $source Stream to read from - * @param StreamInterface $dest Stream to write to - * @param int $maxLen Maximum number of bytes to read. Pass -1 - * to read the entire stream. - * - * @throws \RuntimeException on error. - */ - public static function copyToStream(StreamInterface $source, StreamInterface $dest, $maxLen = -1) - { - $bufferSize = 8192; - - if ($maxLen === -1) { - while (!$source->eof()) { - if (!$dest->write($source->read($bufferSize))) { - break; - } - } - } else { - $remaining = $maxLen; - while ($remaining > 0 && !$source->eof()) { - $buf = $source->read(min($bufferSize, $remaining)); - $len = strlen($buf); - if (!$len) { - break; - } - $remaining -= $len; - $dest->write($buf); - } - } - } - - /** - * Copy the contents of a stream into a string until the given number of - * bytes have been read. - * - * @param StreamInterface $stream Stream to read - * @param int $maxLen Maximum number of bytes to read. Pass -1 - * to read the entire stream. - * - * @return string - * - * @throws \RuntimeException on error. - */ - public static function copyToString(StreamInterface $stream, $maxLen = -1) - { - $buffer = ''; - - if ($maxLen === -1) { - while (!$stream->eof()) { - $buf = $stream->read(1048576); - // Using a loose equality here to match on '' and false. - if ($buf == null) { - break; - } - $buffer .= $buf; - } - return $buffer; - } - - $len = 0; - while (!$stream->eof() && $len < $maxLen) { - $buf = $stream->read($maxLen - $len); - // Using a loose equality here to match on '' and false. - if ($buf == null) { - break; - } - $buffer .= $buf; - $len = strlen($buffer); - } - - return $buffer; - } - - /** - * Calculate a hash of a stream. - * - * This method reads the entire stream to calculate a rolling hash, based - * on PHP's `hash_init` functions. - * - * @param StreamInterface $stream Stream to calculate the hash for - * @param string $algo Hash algorithm (e.g. md5, crc32, etc) - * @param bool $rawOutput Whether or not to use raw output - * - * @return string Returns the hash of the stream - * - * @throws \RuntimeException on error. - */ - public static function hash(StreamInterface $stream, $algo, $rawOutput = false) - { - $pos = $stream->tell(); - - if ($pos > 0) { - $stream->rewind(); - } - - $ctx = hash_init($algo); - while (!$stream->eof()) { - hash_update($ctx, $stream->read(1048576)); - } - - $out = hash_final($ctx, (bool) $rawOutput); - $stream->seek($pos); - - return $out; - } - - /** - * Clone and modify a request with the given changes. - * - * This method is useful for reducing the number of clones needed to mutate - * a message. - * - * The changes can be one of: - * - method: (string) Changes the HTTP method. - * - set_headers: (array) Sets the given headers. - * - remove_headers: (array) Remove the given headers. - * - body: (mixed) Sets the given body. - * - uri: (UriInterface) Set the URI. - * - query: (string) Set the query string value of the URI. - * - version: (string) Set the protocol version. - * - * @param RequestInterface $request Request to clone and modify. - * @param array $changes Changes to apply. - * - * @return RequestInterface - */ - public static function modifyRequest(RequestInterface $request, array $changes) - { - if (!$changes) { - return $request; - } - - $headers = $request->getHeaders(); - - if (!isset($changes['uri'])) { - $uri = $request->getUri(); - } else { - // Remove the host header if one is on the URI - if ($host = $changes['uri']->getHost()) { - $changes['set_headers']['Host'] = $host; - - if ($port = $changes['uri']->getPort()) { - $standardPorts = ['http' => 80, 'https' => 443]; - $scheme = $changes['uri']->getScheme(); - if (isset($standardPorts[$scheme]) && $port != $standardPorts[$scheme]) { - $changes['set_headers']['Host'] .= ':' . $port; - } - } - } - $uri = $changes['uri']; - } - - if (!empty($changes['remove_headers'])) { - $headers = self::caselessRemove($changes['remove_headers'], $headers); - } - - if (!empty($changes['set_headers'])) { - $headers = self::caselessRemove(array_keys($changes['set_headers']), $headers); - $headers = $changes['set_headers'] + $headers; - } - - if (isset($changes['query'])) { - $uri = $uri->withQuery($changes['query']); - } - - if ($request instanceof ServerRequestInterface) { - $new = (new ServerRequest( - isset($changes['method']) ? $changes['method'] : $request->getMethod(), - $uri, - $headers, - isset($changes['body']) ? $changes['body'] : $request->getBody(), - isset($changes['version']) - ? $changes['version'] - : $request->getProtocolVersion(), - $request->getServerParams() - )) - ->withParsedBody($request->getParsedBody()) - ->withQueryParams($request->getQueryParams()) - ->withCookieParams($request->getCookieParams()) - ->withUploadedFiles($request->getUploadedFiles()); - - foreach ($request->getAttributes() as $key => $value) { - $new = $new->withAttribute($key, $value); - } - - return $new; - } - - return new Request( - isset($changes['method']) ? $changes['method'] : $request->getMethod(), - $uri, - $headers, - isset($changes['body']) ? $changes['body'] : $request->getBody(), - isset($changes['version']) - ? $changes['version'] - : $request->getProtocolVersion() - ); - } - - /** - * Read a line from the stream up to the maximum allowed buffer length. - * - * @param StreamInterface $stream Stream to read from - * @param int|null $maxLength Maximum buffer length - * - * @return string - */ - public static function readLine(StreamInterface $stream, $maxLength = null) - { - $buffer = ''; - $size = 0; - - while (!$stream->eof()) { - // Using a loose equality here to match on '' and false. - if (null == ($byte = $stream->read(1))) { - return $buffer; - } - $buffer .= $byte; - // Break when a new line is found or the max length - 1 is reached - if ($byte === "\n" || ++$size === $maxLength - 1) { - break; - } - } - - return $buffer; - } - - /** - * Create a new stream based on the input type. - * - * Options is an associative array that can contain the following keys: - * - metadata: Array of custom metadata. - * - size: Size of the stream. - * - * This method accepts the following `$resource` types: - * - `Psr\Http\Message\StreamInterface`: Returns the value as-is. - * - `string`: Creates a stream object that uses the given string as the contents. - * - `resource`: Creates a stream object that wraps the given PHP stream resource. - * - `Iterator`: If the provided value implements `Iterator`, then a read-only - * stream object will be created that wraps the given iterable. Each time the - * stream is read from, data from the iterator will fill a buffer and will be - * continuously called until the buffer is equal to the requested read size. - * Subsequent read calls will first read from the buffer and then call `next` - * on the underlying iterator until it is exhausted. - * - `object` with `__toString()`: If the object has the `__toString()` method, - * the object will be cast to a string and then a stream will be returned that - * uses the string value. - * - `NULL`: When `null` is passed, an empty stream object is returned. - * - `callable` When a callable is passed, a read-only stream object will be - * created that invokes the given callable. The callable is invoked with the - * number of suggested bytes to read. The callable can return any number of - * bytes, but MUST return `false` when there is no more data to return. The - * stream object that wraps the callable will invoke the callable until the - * number of requested bytes are available. Any additional bytes will be - * buffered and used in subsequent reads. - * - * @param resource|string|int|float|bool|StreamInterface|callable|\Iterator|null $resource Entity body data - * @param array $options Additional options - * - * @return StreamInterface - * - * @throws \InvalidArgumentException if the $resource arg is not valid. - */ - public static function streamFor($resource = '', array $options = []) - { - if (is_scalar($resource)) { - $stream = self::tryFopen('php://temp', 'r+'); - if ($resource !== '') { - fwrite($stream, $resource); - fseek($stream, 0); - } - return new Stream($stream, $options); - } - - switch (gettype($resource)) { - case 'resource': - /* - * The 'php://input' is a special stream with quirks and inconsistencies. - * We avoid using that stream by reading it into php://temp - */ - $metaData = \stream_get_meta_data($resource); - if (isset($metaData['uri']) && $metaData['uri'] === 'php://input') { - $stream = self::tryFopen('php://temp', 'w+'); - fwrite($stream, stream_get_contents($resource)); - fseek($stream, 0); - $resource = $stream; - } - return new Stream($resource, $options); - case 'object': - if ($resource instanceof StreamInterface) { - return $resource; - } elseif ($resource instanceof \Iterator) { - return new PumpStream(function () use ($resource) { - if (!$resource->valid()) { - return false; - } - $result = $resource->current(); - $resource->next(); - return $result; - }, $options); - } elseif (method_exists($resource, '__toString')) { - return Utils::streamFor((string) $resource, $options); - } - break; - case 'NULL': - return new Stream(self::tryFopen('php://temp', 'r+'), $options); - } - - if (is_callable($resource)) { - return new PumpStream($resource, $options); - } - - throw new \InvalidArgumentException('Invalid resource type: ' . gettype($resource)); - } - - /** - * Safely opens a PHP stream resource using a filename. - * - * When fopen fails, PHP normally raises a warning. This function adds an - * error handler that checks for errors and throws an exception instead. - * - * @param string $filename File to open - * @param string $mode Mode used to open the file - * - * @return resource - * - * @throws \RuntimeException if the file cannot be opened - */ - public static function tryFopen($filename, $mode) - { - $ex = null; - set_error_handler(function () use ($filename, $mode, &$ex) { - $ex = new \RuntimeException(sprintf( - 'Unable to open "%s" using mode "%s": %s', - $filename, - $mode, - func_get_args()[1] - )); - - return true; - }); - - try { - $handle = fopen($filename, $mode); - } catch (\Throwable $e) { - $ex = new \RuntimeException(sprintf( - 'Unable to open "%s" using mode "%s": %s', - $filename, - $mode, - $e->getMessage() - ), 0, $e); - } - - restore_error_handler(); - - if ($ex) { - /** @var $ex \RuntimeException */ - throw $ex; - } - - return $handle; - } - - /** - * Returns a UriInterface for the given value. - * - * This function accepts a string or UriInterface and returns a - * UriInterface for the given value. If the value is already a - * UriInterface, it is returned as-is. - * - * @param string|UriInterface $uri - * - * @return UriInterface - * - * @throws \InvalidArgumentException - */ - public static function uriFor($uri) - { - if ($uri instanceof UriInterface) { - return $uri; - } - - if (is_string($uri)) { - return new Uri($uri); - } - - throw new \InvalidArgumentException('URI must be a string or UriInterface'); - } -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/functions.php b/plugins/automagic-images/vendor/guzzlehttp/psr7/src/functions.php deleted file mode 100644 index b0901fa..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/functions.php +++ /dev/null @@ -1,422 +0,0 @@ - '1', 'foo[b]' => '2'])`. - * - * @param string $str Query string to parse - * @param int|bool $urlEncoding How the query string is encoded - * - * @return array - * - * @deprecated parse_query will be removed in guzzlehttp/psr7:2.0. Use Query::parse instead. - */ -function parse_query($str, $urlEncoding = true) -{ - return Query::parse($str, $urlEncoding); -} - -/** - * Build a query string from an array of key value pairs. - * - * This function can use the return value of `parse_query()` to build a query - * string. This function does not modify the provided keys when an array is - * encountered (like `http_build_query()` would). - * - * @param array $params Query string parameters. - * @param int|false $encoding Set to false to not encode, PHP_QUERY_RFC3986 - * to encode using RFC3986, or PHP_QUERY_RFC1738 - * to encode using RFC1738. - * - * @return string - * - * @deprecated build_query will be removed in guzzlehttp/psr7:2.0. Use Query::build instead. - */ -function build_query(array $params, $encoding = PHP_QUERY_RFC3986) -{ - return Query::build($params, $encoding); -} - -/** - * Determines the mimetype of a file by looking at its extension. - * - * @param string $filename - * - * @return string|null - * - * @deprecated mimetype_from_filename will be removed in guzzlehttp/psr7:2.0. Use MimeType::fromFilename instead. - */ -function mimetype_from_filename($filename) -{ - return MimeType::fromFilename($filename); -} - -/** - * Maps a file extensions to a mimetype. - * - * @param $extension string The file extension. - * - * @return string|null - * - * @link http://svn.apache.org/repos/asf/httpd/httpd/branches/1.3.x/conf/mime.types - * @deprecated mimetype_from_extension will be removed in guzzlehttp/psr7:2.0. Use MimeType::fromExtension instead. - */ -function mimetype_from_extension($extension) -{ - return MimeType::fromExtension($extension); -} - -/** - * Parses an HTTP message into an associative array. - * - * The array contains the "start-line" key containing the start line of - * the message, "headers" key containing an associative array of header - * array values, and a "body" key containing the body of the message. - * - * @param string $message HTTP request or response to parse. - * - * @return array - * - * @internal - * - * @deprecated _parse_message will be removed in guzzlehttp/psr7:2.0. Use Message::parseMessage instead. - */ -function _parse_message($message) -{ - return Message::parseMessage($message); -} - -/** - * Constructs a URI for an HTTP request message. - * - * @param string $path Path from the start-line - * @param array $headers Array of headers (each value an array). - * - * @return string - * - * @internal - * - * @deprecated _parse_request_uri will be removed in guzzlehttp/psr7:2.0. Use Message::parseRequestUri instead. - */ -function _parse_request_uri($path, array $headers) -{ - return Message::parseRequestUri($path, $headers); -} - -/** - * Get a short summary of the message body. - * - * Will return `null` if the response is not printable. - * - * @param MessageInterface $message The message to get the body summary - * @param int $truncateAt The maximum allowed size of the summary - * - * @return string|null - * - * @deprecated get_message_body_summary will be removed in guzzlehttp/psr7:2.0. Use Message::bodySummary instead. - */ -function get_message_body_summary(MessageInterface $message, $truncateAt = 120) -{ - return Message::bodySummary($message, $truncateAt); -} - -/** - * Remove the items given by the keys, case insensitively from the data. - * - * @param iterable $keys - * - * @return array - * - * @internal - * - * @deprecated _caseless_remove will be removed in guzzlehttp/psr7:2.0. Use Utils::caselessRemove instead. - */ -function _caseless_remove($keys, array $data) -{ - return Utils::caselessRemove($keys, $data); -} diff --git a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/functions_include.php b/plugins/automagic-images/vendor/guzzlehttp/psr7/src/functions_include.php deleted file mode 100644 index 96a4a83..0000000 --- a/plugins/automagic-images/vendor/guzzlehttp/psr7/src/functions_include.php +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/plugins/automagic-images/vendor/myclabs/php-enum/src/Enum.php b/plugins/automagic-images/vendor/myclabs/php-enum/src/Enum.php deleted file mode 100644 index a16aa23..0000000 --- a/plugins/automagic-images/vendor/myclabs/php-enum/src/Enum.php +++ /dev/null @@ -1,305 +0,0 @@ - - * @author Daniel Costa - * @author Mirosław Filip - * - * @psalm-template T - * @psalm-immutable - * @psalm-consistent-constructor - */ -abstract class Enum implements \JsonSerializable -{ - /** - * Enum value - * - * @var mixed - * @psalm-var T - */ - protected $value; - - /** - * Enum key, the constant name - * - * @var string - */ - private $key; - - /** - * Store existing constants in a static cache per object. - * - * - * @var array - * @psalm-var array> - */ - protected static $cache = []; - - /** - * Cache of instances of the Enum class - * - * @var array - * @psalm-var array> - */ - protected static $instances = []; - - /** - * Creates a new value of some type - * - * @psalm-pure - * @param mixed $value - * - * @psalm-param T $value - * @throws \UnexpectedValueException if incompatible type is given. - */ - public function __construct($value) - { - if ($value instanceof static) { - /** @psalm-var T */ - $value = $value->getValue(); - } - - $this->key = static::assertValidValueReturningKey($value); - - /** @psalm-var T */ - $this->value = $value; - } - - public function __wakeup() - { - if ($this->key === null) { - $this->key = static::search($this->value); - } - } - - /** - * @param mixed $value - * @return static - * @psalm-return static - */ - public static function from($value): self - { - $key = static::assertValidValueReturningKey($value); - - return self::__callStatic($key, []); - } - - /** - * @psalm-pure - * @return mixed - * @psalm-return T - */ - public function getValue() - { - return $this->value; - } - - /** - * Returns the enum key (i.e. the constant name). - * - * @psalm-pure - * @return string - */ - public function getKey() - { - return $this->key; - } - - /** - * @psalm-pure - * @psalm-suppress InvalidCast - * @return string - */ - public function __toString() - { - return (string)$this->value; - } - - /** - * Determines if Enum should be considered equal with the variable passed as a parameter. - * Returns false if an argument is an object of different class or not an object. - * - * This method is final, for more information read https://github.com/myclabs/php-enum/issues/4 - * - * @psalm-pure - * @psalm-param mixed $variable - * @return bool - */ - final public function equals($variable = null): bool - { - return $variable instanceof self - && $this->getValue() === $variable->getValue() - && static::class === \get_class($variable); - } - - /** - * Returns the names (keys) of all constants in the Enum class - * - * @psalm-pure - * @psalm-return list - * @return array - */ - public static function keys() - { - return \array_keys(static::toArray()); - } - - /** - * Returns instances of the Enum class of all Enum constants - * - * @psalm-pure - * @psalm-return array - * @return static[] Constant name in key, Enum instance in value - */ - public static function values() - { - $values = array(); - - /** @psalm-var T $value */ - foreach (static::toArray() as $key => $value) { - $values[$key] = new static($value); - } - - return $values; - } - - /** - * Returns all possible values as an array - * - * @psalm-pure - * @psalm-suppress ImpureStaticProperty - * - * @psalm-return array - * @return array Constant name in key, constant value in value - */ - public static function toArray() - { - $class = static::class; - - if (!isset(static::$cache[$class])) { - /** @psalm-suppress ImpureMethodCall this reflection API usage has no side-effects here */ - $reflection = new \ReflectionClass($class); - /** @psalm-suppress ImpureMethodCall this reflection API usage has no side-effects here */ - static::$cache[$class] = $reflection->getConstants(); - } - - return static::$cache[$class]; - } - - /** - * Check if is valid enum value - * - * @param $value - * @psalm-param mixed $value - * @psalm-pure - * @psalm-assert-if-true T $value - * @return bool - */ - public static function isValid($value) - { - return \in_array($value, static::toArray(), true); - } - - /** - * Asserts valid enum value - * - * @psalm-pure - * @psalm-assert T $value - */ - public static function assertValidValue($value): void - { - self::assertValidValueReturningKey($value); - } - - /** - * Asserts valid enum value - * - * @psalm-pure - * @psalm-assert T $value - */ - private static function assertValidValueReturningKey($value): string - { - if (false === ($key = static::search($value))) { - throw new \UnexpectedValueException("Value '$value' is not part of the enum " . static::class); - } - - return $key; - } - - /** - * Check if is valid enum key - * - * @param $key - * @psalm-param string $key - * @psalm-pure - * @return bool - */ - public static function isValidKey($key) - { - $array = static::toArray(); - - return isset($array[$key]) || \array_key_exists($key, $array); - } - - /** - * Return key for value - * - * @param mixed $value - * - * @psalm-param mixed $value - * @psalm-pure - * @return string|false - */ - public static function search($value) - { - return \array_search($value, static::toArray(), true); - } - - /** - * Returns a value when called statically like so: MyEnum::SOME_VALUE() given SOME_VALUE is a class constant - * - * @param string $name - * @param array $arguments - * - * @return static - * @throws \BadMethodCallException - * - * @psalm-pure - */ - public static function __callStatic($name, $arguments) - { - $class = static::class; - if (!isset(self::$instances[$class][$name])) { - $array = static::toArray(); - if (!isset($array[$name]) && !\array_key_exists($name, $array)) { - $message = "No static method or enum constant '$name' in class " . static::class; - throw new \BadMethodCallException($message); - } - return self::$instances[$class][$name] = new static($array[$name]); - } - return clone self::$instances[$class][$name]; - } - - /** - * Specify data which should be serialized to JSON. This method returns data that can be serialized by json_encode() - * natively. - * - * @return mixed - * @link http://php.net/manual/en/jsonserializable.jsonserialize.php - * @psalm-pure - */ - public function jsonSerialize() - { - return $this->getValue(); - } -} diff --git a/plugins/automagic-images/vendor/myclabs/php-enum/src/PHPUnit/Comparator.php b/plugins/automagic-images/vendor/myclabs/php-enum/src/PHPUnit/Comparator.php deleted file mode 100644 index 302bf80..0000000 --- a/plugins/automagic-images/vendor/myclabs/php-enum/src/PHPUnit/Comparator.php +++ /dev/null @@ -1,54 +0,0 @@ -register(new \MyCLabs\Enum\PHPUnit\Comparator()); - */ -final class Comparator extends \SebastianBergmann\Comparator\Comparator -{ - public function accepts($expected, $actual) - { - return $expected instanceof Enum && ( - $actual instanceof Enum || $actual === null - ); - } - - /** - * @param Enum $expected - * @param Enum|null $actual - * - * @return void - */ - public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false) - { - if ($expected->equals($actual)) { - return; - } - - throw new ComparisonFailure( - $expected, - $actual, - $this->formatEnum($expected), - $this->formatEnum($actual), - false, - 'Failed asserting that two Enums are equal.' - ); - } - - private function formatEnum(Enum $enum = null) - { - if ($enum === null) { - return "null"; - } - - return get_class($enum)."::{$enum->getKey()}()"; - } -} diff --git a/plugins/automagic-images/vendor/paquettg/php-html-parser/SECURITY.md b/plugins/automagic-images/vendor/paquettg/php-html-parser/SECURITY.md deleted file mode 100644 index 3fc4dfc..0000000 --- a/plugins/automagic-images/vendor/paquettg/php-html-parser/SECURITY.md +++ /dev/null @@ -1,11 +0,0 @@ -# Security Policy - -## Supported Versions - -We only support the most recent version with security fixes. - -## Reporting a Vulnerability - -If you have found any issues that might have security implications, please refer to https://tidelift.com/security - -Do not report security reports publicly. diff --git a/plugins/automagic-images/vendor/paquettg/php-html-parser/composer.json b/plugins/automagic-images/vendor/paquettg/php-html-parser/composer.json deleted file mode 100644 index 166886f..0000000 --- a/plugins/automagic-images/vendor/paquettg/php-html-parser/composer.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "name": "paquettg/php-html-parser", - "type": "library", - "description": "An HTML DOM parser. It allows you to manipulate HTML. Find tags on an HTML page with selectors just like jQuery.", - "keywords": ["html", "dom", "parser"], - "homepage": "https://github.com/paquettg/php-html-parser", - "license": "MIT", - "authors": [ - { - "name": "Gilles Paquette", - "email": "paquettg@gmail.com", - "homepage": "http://gillespaquette.ca" - } - ], - "require": { - "php": ">=7.2", - "ext-mbstring": "*", - "ext-zlib": "*", - "ext-curl": "*", - "paquettg/string-encode": "~1.0.0", - "php-http/httplug": "^2.1", - "guzzlehttp/guzzle": "^7.0", - "guzzlehttp/psr7": "^1.6", - "myclabs/php-enum": "^1.7" - }, - "require-dev": { - "phpunit/phpunit": "^7.5.1", - "mockery/mockery": "^1.2", - "infection/infection": "^0.13.4", - "phan/phan": "^2.4", - "friendsofphp/php-cs-fixer": "^2.16" - }, - "autoload": { - "psr-4": { - "PHPHtmlParser\\": "src/PHPHtmlParser" - } - } -} diff --git a/plugins/automagic-images/vendor/paquettg/php-html-parser/src/PHPHtmlParser/Content.php b/plugins/automagic-images/vendor/paquettg/php-html-parser/src/PHPHtmlParser/Content.php deleted file mode 100644 index f133217..0000000 --- a/plugins/automagic-images/vendor/paquettg/php-html-parser/src/PHPHtmlParser/Content.php +++ /dev/null @@ -1,257 +0,0 @@ -'; - protected $slash = " />\r\n\t"; - protected $attr = ' >'; - - /** - * Content constructor. - */ - public function __construct(string $content = '') - { - $this->content = $content; - $this->size = \strlen($content); - $this->pos = 0; - } - - /** - * Returns the current position of the content. - */ - public function getPosition(): int - { - return $this->pos; - } - - /** - * Gets the current character we are at. - * - * @param ?int $char - */ - public function char(?int $char = null): string - { - return $this->content[$char ?? $this->pos] ?? ''; - } - - /** - * Gets a string from the current character position. - * - * @param int $length - * @return string - */ - public function string(int $length = 1): string - { - $string = ''; - $position = $this->pos; - do { - $string .= $this->char($position++); - } while ($position < $this->pos + $length); - return $string; - } - - /** - * Moves the current position forward. - * - * @throws ContentLengthException - */ - public function fastForward(int $count): Content - { - if (!$this->canFastForward($count)) { - // trying to go over the content length, throw exception - throw new ContentLengthException('Attempt to fastForward pass the length of the content.'); - } - $this->pos += $count; - - return $this; - } - - /** - * Checks if we can move the position forward. - */ - public function canFastForward(int $count): bool - { - return \strlen($this->content) >= $this->pos + $count; - } - - /** - * Moves the current position backward. - */ - public function rewind(int $count): Content - { - $this->pos -= $count; - if ($this->pos < 0) { - $this->pos = 0; - } - - return $this; - } - - /** - * Copy the content until we find the given string. - */ - public function copyUntil(string $string, bool $char = false, bool $escape = false): string - { - if ($this->pos >= $this->size) { - // nothing left - return ''; - } - - if ($escape) { - $position = $this->pos; - $found = false; - while (!$found) { - $position = \strpos($this->content, $string, $position); - if ($position === false) { - // reached the end - break; - } - - if ($this->char($position - 1) == '\\') { - // this character is escaped - ++$position; - continue; - } - - $found = true; - } - } elseif ($char) { - $position = \strcspn($this->content, $string, $this->pos); - $position += $this->pos; - } else { - $position = \strpos($this->content, $string, $this->pos); - } - - if ($position === false) { - // could not find character, just return the remaining of the content - $return = \substr($this->content, $this->pos, $this->size - $this->pos); - if ($return === false) { - throw new LogicalException('Substr returned false with position ' . $this->pos . '.'); - } - $this->pos = $this->size; - - return $return; - } - - if ($position == $this->pos) { - // we are at the right place - return ''; - } - - $return = \substr($this->content, $this->pos, $position - $this->pos); - if ($return === false) { - throw new LogicalException('Substr returned false with position ' . $this->pos . '.'); - } - // set the new position - $this->pos = $position; - - return $return; - } - - /** - * Copies the content until the string is found and return it - * unless the 'unless' is found in the substring. - */ - public function copyUntilUnless(string $string, string $unless): string - { - $lastPos = $this->pos; - $this->fastForward(1); - $foundString = $this->copyUntil($string, true, true); - - $position = \strcspn($foundString, $unless); - if ($position == \strlen($foundString)) { - return $string . $foundString; - } - // rewind changes and return nothing - $this->pos = $lastPos; - - return ''; - } - - /** - * Copies the content until it reaches the token string.,. - * - * @uses $this->copyUntil() - */ - public function copyByToken(StringToken $stringToken, bool $char = false, bool $escape = false): string - { - $string = $stringToken->getValue(); - - return $this->copyUntil($string, $char, $escape); - } - - /** - * Skip a given set of characters. - * - * @throws LogicalException - */ - public function skip(string $string, bool $copy = false): string - { - $len = \strspn($this->content, $string, $this->pos); - if ($len === false) { - throw new LogicalException('Strspn returned false with position ' . $this->pos . '.'); - } - $return = ''; - if ($copy) { - $return = \substr($this->content, $this->pos, $len); - if ($return === false) { - throw new LogicalException('Substr returned false with position ' . $this->pos . '.'); - } - } - - // update the position - $this->pos += $len; - - return $return; - } - - /** - * Skip a given token of pre-defined characters. - * - * @uses $this->skip() - */ - public function skipByToken(StringToken $skipToken, bool $copy = false): string - { - $string = $skipToken->getValue(); - - return $this->skip($string, $copy); - } -} diff --git a/plugins/automagic-images/vendor/paquettg/php-html-parser/src/PHPHtmlParser/Contracts/Dom/CleanerInterface.php b/plugins/automagic-images/vendor/paquettg/php-html-parser/src/PHPHtmlParser/Contracts/Dom/CleanerInterface.php deleted file mode 100644 index 725a8a4..0000000 --- a/plugins/automagic-images/vendor/paquettg/php-html-parser/src/PHPHtmlParser/Contracts/Dom/CleanerInterface.php +++ /dev/null @@ -1,16 +0,0 @@ -parsedSelectorDTO[] = $parsedSelectorDTO; - } - } - } - - /** - * @param ParsedSelectorDTO[] $parsedSelectorDTOs - */ - public static function makeCollection(array $parsedSelectorDTOs): ParsedSelectorCollectionDTO - { - return new ParsedSelectorCollectionDTO($parsedSelectorDTOs); - } - - /** - * @return ParsedSelectorDTO[] - */ - public function getParsedSelectorDTO(): array - { - return $this->parsedSelectorDTO; - } -} diff --git a/plugins/automagic-images/vendor/paquettg/php-html-parser/src/PHPHtmlParser/DTO/Selector/ParsedSelectorDTO.php b/plugins/automagic-images/vendor/paquettg/php-html-parser/src/PHPHtmlParser/DTO/Selector/ParsedSelectorDTO.php deleted file mode 100644 index bce0721..0000000 --- a/plugins/automagic-images/vendor/paquettg/php-html-parser/src/PHPHtmlParser/DTO/Selector/ParsedSelectorDTO.php +++ /dev/null @@ -1,41 +0,0 @@ -rules[] = $ruleDTO; - } - } - } - - /** - * @param RuleDTO[] $ruleDTOs - */ - public static function makeFromRules(array $ruleDTOs): ParsedSelectorDTO - { - return new ParsedSelectorDTO($ruleDTOs); - } - - /** - * @return RuleDTO[] - */ - public function getRules(): array - { - return $this->rules; - } -} diff --git a/plugins/automagic-images/vendor/paquettg/php-html-parser/src/PHPHtmlParser/DTO/Selector/RuleDTO.php b/plugins/automagic-images/vendor/paquettg/php-html-parser/src/PHPHtmlParser/DTO/Selector/RuleDTO.php deleted file mode 100644 index 5299e3a..0000000 --- a/plugins/automagic-images/vendor/paquettg/php-html-parser/src/PHPHtmlParser/DTO/Selector/RuleDTO.php +++ /dev/null @@ -1,100 +0,0 @@ -tag = $values['tag']; - $this->operator = $values['operator']; - $this->key = $values['key']; - $this->value = $values['value']; - $this->noKey = $values['noKey']; - $this->alterNext = $values['alterNext']; - } - - /** - * @param string|array|null $key - * @param string|array|null $value - */ - public static function makeFromPrimitives(string $tag, string $operator, $key, $value, bool $noKey, bool $alterNext): RuleDTO - { - return new RuleDTO([ - 'tag' => $tag, - 'operator' => $operator, - 'key' => $key, - 'value' => $value, - 'noKey' => $noKey, - 'alterNext' => $alterNext, - ]); - } - - public function getTag(): string - { - return $this->tag; - } - - public function getOperator(): string - { - return $this->operator; - } - - /** - * @return string|array|null - */ - public function getKey() - { - return $this->key; - } - - /** - * @return string|array|null - */ - public function getValue() - { - return $this->value; - } - - public function isNoKey(): bool - { - return $this->noKey; - } - - public function isAlterNext(): bool - { - return $this->alterNext; - } -} diff --git a/plugins/automagic-images/vendor/paquettg/php-html-parser/src/PHPHtmlParser/DTO/Tag/AttributeDTO.php b/plugins/automagic-images/vendor/paquettg/php-html-parser/src/PHPHtmlParser/DTO/Tag/AttributeDTO.php deleted file mode 100644 index 3e7e182..0000000 --- a/plugins/automagic-images/vendor/paquettg/php-html-parser/src/PHPHtmlParser/DTO/Tag/AttributeDTO.php +++ /dev/null @@ -1,60 +0,0 @@ -value = $values['value']; - $this->doubleQuote = $values['doubleQuote'] ?? true; - } - - public static function makeFromPrimitives(?string $value, bool $doubleQuote = true): AttributeDTO - { - return new AttributeDTO([ - 'value' => $value, - 'doubleQuote' => $doubleQuote, - ]); - } - - public function getValue(): ?string - { - return $this->value; - } - - public function isDoubleQuote(): bool - { - return $this->doubleQuote; - } - - public function htmlspecialcharsDecode(): void - { - if (!\is_null($this->value)) { - $this->value = \htmlspecialchars_decode($this->value); - } - } - - /** - * @throws Exception - */ - public function encodeValue(Encode $encode) - { - $this->value = $encode->convert($this->value); - } -} diff --git a/plugins/automagic-images/vendor/paquettg/php-html-parser/src/PHPHtmlParser/DTO/TagDTO.php b/plugins/automagic-images/vendor/paquettg/php-html-parser/src/PHPHtmlParser/DTO/TagDTO.php deleted file mode 100644 index 71f0ec1..0000000 --- a/plugins/automagic-images/vendor/paquettg/php-html-parser/src/PHPHtmlParser/DTO/TagDTO.php +++ /dev/null @@ -1,74 +0,0 @@ -status = $values['status'] ?? false; - $this->closing = $values['closing'] ?? false; - $this->node = $values['node'] ?? null; - $this->tag = $values['tag'] ?? null; - } - - public static function makeFromPrimitives(bool $status = false, bool $closing = false, ?HtmlNode $node = null, ?string $tag = null): TagDTO - { - return new TagDTO([ - 'status' => $status, - 'closing' => $closing, - 'node' => $node, - 'tag' => $tag, - ]); - } - - public function isStatus(): bool - { - return $this->status; - } - - public function isClosing(): bool - { - return $this->closing; - } - - /** - * @return mixed - */ - public function getNode(): ?HtmlNode - { - return $this->node; - } - - /** - * @return mixed - */ - public function getTag(): ?string - { - return $this->tag; - } -} diff --git a/plugins/automagic-images/vendor/paquettg/php-html-parser/src/PHPHtmlParser/Discovery/CleanerDiscovery.php b/plugins/automagic-images/vendor/paquettg/php-html-parser/src/PHPHtmlParser/Discovery/CleanerDiscovery.php deleted file mode 100644 index 96ef678..0000000 --- a/plugins/automagic-images/vendor/paquettg/php-html-parser/src/PHPHtmlParser/Discovery/CleanerDiscovery.php +++ /dev/null @@ -1,25 +0,0 @@ -domParser = $domParser; - $this->domCleaner = $domCleaner; - } - - /** - * Returns the inner html of the root node. - * - * @throws ChildNotFoundException - * @throws UnknownChildTypeException - * @throws NotLoadedException - */ - public function __toString(): string - { - $this->isLoaded(); - - return $this->root->innerHtml(); - } - - /** - * Loads the dom from a document file/url. - * - * @throws ChildNotFoundException - * @throws CircularException - * @throws Exceptions\ContentLengthException - * @throws LogicalException - * @throws StrictException - */ - public function loadFromFile(string $file, ?Options $options = null): Dom - { - $content = @\file_get_contents($file); - if ($content === false) { - throw new LogicalException('file_get_contents failed and returned false when trying to read "' . $file . '".'); - } - - return $this->loadStr($content, $options); - } - - /** - * Use a curl interface implementation to attempt to load - * the content from a url. - * - * @throws ChildNotFoundException - * @throws CircularException - * @throws Exceptions\ContentLengthException - * @throws LogicalException - * @throws StrictException - * @throws ClientExceptionInterface - */ - public function loadFromUrl(string $url, ?Options $options = null, ?ClientInterface $client = null, ?RequestInterface $request = null): Dom - { - if ($client === null) { - $client = new Client(); - } - if ($request === null) { - $request = new Request('GET', $url); - } - - $response = $client->sendRequest($request); - $content = $response->getBody()->getContents(); - - return $this->loadStr($content, $options); - } - - /** - * Parsers the html of the given string. Used for load(), loadFromFile(), - * and loadFromUrl(). - * - * @throws ChildNotFoundException - * @throws CircularException - * @throws Exceptions\ContentLengthException - * @throws LogicalException - * @throws StrictException - */ - public function loadStr(string $str, ?Options $options = null): Dom - { - $localOptions = new Options(); - if ($this->globalOptions !== null) { - $localOptions = $localOptions->setFromOptions($this->globalOptions); - } - if ($options !== null) { - $localOptions = $localOptions->setFromOptions($options); - } - - $html = $this->domCleaner->clean($str, $localOptions, $this->defaultCharset); - - $this->content = new Content($html); - - $this->root = $this->domParser->parse($localOptions, $this->content, \strlen($str)); - $this->domParser->detectCharset($localOptions, $this->defaultCharset, $this->root); - - return $this; - } - - /** - * Sets a global options array to be used by all load calls. - */ - public function setOptions(Options $options): Dom - { - $this->globalOptions = $options; - - return $this; - } - - /** - * Find elements by css selector on the root node. - * - * @throws NotLoadedException - * @throws ChildNotFoundException - * - * @return mixed|Collection|null - */ - public function find(string $selector, int $nth = null) - { - $this->isLoaded(); - - return $this->root->find($selector, $nth); - } - - /** - * Simple wrapper function that returns an element by the - * id. - * - * @param $id - * - * @throws NotLoadedException - * @throws ChildNotFoundException - * - * @return mixed|Collection|null - */ - public function getElementById($id) - { - $this->isLoaded(); - - return $this->find('#' . $id, 0); - } - - /** - * Simple wrapper function that returns all elements by - * tag name. - * - * @throws NotLoadedException - * @throws ChildNotFoundException - * - * @return mixed|Collection|null - */ - public function getElementsByTag(string $name) - { - $this->isLoaded(); - - return $this->find($name); - } - - /** - * Simple wrapper function that returns all elements by - * class name. - * - * @throws NotLoadedException - * @throws ChildNotFoundException - * - * @return mixed|Collection|null - */ - public function getElementsByClass(string $class) - { - $this->isLoaded(); - - return $this->find('.' . $class); - } - - /** - * Checks if the load methods have been called. - * - * @throws NotLoadedException - */ - private function isLoaded(): void - { - if (\is_null($this->content)) { - throw new NotLoadedException('Content is not loaded!'); - } - } -} diff --git a/plugins/automagic-images/vendor/paquettg/php-html-parser/src/PHPHtmlParser/Dom/Cleaner.php b/plugins/automagic-images/vendor/paquettg/php-html-parser/src/PHPHtmlParser/Dom/Cleaner.php deleted file mode 100644 index 52e5728..0000000 --- a/plugins/automagic-images/vendor/paquettg/php-html-parser/src/PHPHtmlParser/Dom/Cleaner.php +++ /dev/null @@ -1,130 +0,0 @@ -isCleanupInput()) { - // skip entire cleanup step - return $str; - } - - // check if the string is gziped - $is_gzip = 0 === \mb_strpos($str, "\x1f" . "\x8b" . "\x08", 0, 'US-ASCII'); - if ($is_gzip) { - $str = \gzdecode($str); - if ($str === false) { - throw new LogicalException('gzdecode returned false. Error when trying to decode the string.'); - } - } - - // we must handle character encoding - $str = $this->setUpRegexEncoding($str, $options, $defaultCharset); - - // remove white space before closing tags - $str = \mb_eregi_replace("'\s+>", "'>", $str); - if ($str === false) { - throw new LogicalException('mb_eregi_replace returned false instead of a string. Error when attempting to clean single quotes.'); - } - $str = \mb_eregi_replace('"\s+>', '">', $str); - if ($str === false) { - throw new LogicalException('mb_eregi_replace returned false instead of a string. Error when attempting to clean double quotes.'); - } - - // clean out the \n\r - $replace = ' '; - if ($options->isPreserveLineBreaks()) { - $replace = ' '; - } - $str = \str_replace(["\r\n", "\r", "\n"], $replace, $str); - if ($str === false) { - throw new LogicalException('str_replace returned false instead of a string. Error when attempting to clean input string.'); - } - - // strip the doctype - $str = \mb_eregi_replace('', '', $str); - if ($str === false) { - throw new LogicalException('mb_eregi_replace returned false instead of a string. Error when attempting to strip the doctype.'); - } - - // strip out comments - $str = \mb_eregi_replace('', '', $str); - if ($str === false) { - throw new LogicalException('mb_eregi_replace returned false instead of a string. Error when attempting to strip comments.'); - } - - // strip out cdata - $str = \mb_eregi_replace("", '', $str); - if ($str === false) { - throw new LogicalException('mb_eregi_replace returned false instead of a string. Error when attempting to strip out cdata.'); - } - - // strip out ` tag at the bottom with this code: - - ```html - - ``` - -# File Upload - -To upload files you can use the `file` form field. [The standard features apply](https://learn.getgrav.org/forms/blueprints/how-to-add-file-upload), and you can simply edit your custom blueprint with a field definition similar to: - -``` - item_image: - type: file - label: Item Image - random_name: true - destination: 'user/data/flex-objects/files' - multiple: true -``` - -> In order to fully take advantage of image uploads, you should always be using `FolderStorage`, meaning that the objects get saved to individual folders together with the images. Other storage layers may or may not support media. - -# Advanced - -You can radically alter the structure of the `contacts.json` data file by making major edits to the `contacts.yaml` blueprint file. However, it's best to start with an empty `contacts.json` if you are making wholesale changes or you will have data conflicts. Best to create your blueprint first. Reloading a **New Entry** until the form looks correct, then try saving, and check to make sure the stored `user/data/flex-objects/contacts.json` file looks correct. - -Then you will need to make more widespread changes to the site Twig templates. You might need to adjust the number of columns and the field names. You will also need to pay attention to the JavaScript initialization in each template. - -# Features - -Here are the main benefits of using Flex objects: - -* CRUD is automatically handled for you by Flex Objects plugin -* Objects can be stored using many different strategies, including single file, file per object or folder per object; using yaml, json etc. -* Flex types can be easily extended by custom PHP collection and object classes -* Both Flex objects and collections know how to render themselves: `echo $object->render($layout, $context)` or `{% render object layout: layout with context %}` -* You can easily create custom layouts for your objects and collections to be used in different pages -* Both Flex objects and collections support serialization and `json_encode()` -* Flex objects support Grav `Medium` objects with few lines of code -* Flex objects can have relations to other Flex objects with few lines of code defining the relation -* Flex directories support indexes which allow searching objects without loading all of them -* Efficient caching for indexes, searches, objects and rendered output - -# Limitations and future improvements - -Right now there are a few limitations: - -* Frontend only has a basic routing for the individual pages (you need to do the advanced routing manually by yourself) -* Administration needs more features like filtering, bulk updates etc -* It would be nice to have an easy way to display Flex admin in other admin plugins (it is already possible, but not easy) -* Optional database storage layer would be nice to have -* We need general collection functions to do simple filtering, like: "display all published items" without custom PHP code - -### Notes: - -1. You can actually use pretty much any folder under the `user/` folder of Grav. Simply edit the **Extra Admin Twig Path** option in the `flex-objects.yaml` file. It defaults to `theme://admin/templates` which means it uses the default theme's `admin/templates/` folder if it exists. -2. You can use any path for front end Twig templates also, if you don't want to put them in your theme, you can add an entry in the **Extra Site Twig Path** option of the `flex-objects.yaml` configuration and point to another location. - -# Tricks and tips - -* You can enable and disable directories from **Plugins** > **Flex Objects** - * New Flex Directories can be registered by simply creating a new blueprint file in `user/blueprints/flex-objects` folder - * You can also add types from your plugins by hooking into `onFlexInit` event (see `AccountsServiceProvider` in Grav) -* To properly create your own custom types, you need at least the object blueprint and the template files for collections and objects -* Use `flex-objects.md` page to create entry point for your own directory - * In page header you can use nested `flex.directory` variable to define the directory (or do it in admin) - * In Admin you can just select the directory under the page title - - -# Parameters supported by Flex page type: - -``` ---- -title: 'Flex Directories' -flex: - directories: - layout: default - list: - - accounts - - contacts ---- -``` - -`directories.layout`: uses template file `templates/flex-objects/directories/[LAYOUT].html.twig` -`directories.list`: list of flex directories displayed in this page diff --git a/plugins/flex-objects/admin/pages/flex-objects.md b/plugins/flex-objects/admin/pages/flex-objects.md deleted file mode 100644 index c9359a2..0000000 --- a/plugins/flex-objects/admin/pages/flex-objects.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Flex Objects - -access: - admin.flex-objects: true - admin.super: true ---- \ No newline at end of file diff --git a/plugins/flex-objects/admin/templates/flex-objects.html.twig b/plugins/flex-objects/admin/templates/flex-objects.html.twig deleted file mode 100644 index 74ee1ca..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects.html.twig +++ /dev/null @@ -1,30 +0,0 @@ -{%- set user = admin.user -%} -{%- set route = controller.route -%} -{%- set type = directory.config('admin.template') ?? target -%} - -{# Set action from ?preview=1 #} -{%- if key and uri.currentUri().queryParam('preview') %} - {% set action = 'preview' %} -{% endif -%} - -{%- set template -%} - {%- if action == 'add' -%} - edit - {%- elseif action == 'delete' -%} - list - {%- else -%} - {{- action ?: task ?: 'types' -}} - {%- endif -%} -{%- endset -%} - -{%- set separator = config.system.param_sep -%} -{%- set view_config = directory.config('admin.views.' ~ template) ?? directory.config('admin.' ~ template) ?? [] -%} - -{%- include target ? [ - 'flex-objects/types/' ~ type ~ '/' ~ template ~ '.html.twig', - 'flex-objects/types/default/' ~ template ~ '.html.twig', - 'flex-objects/layouts/404.html.twig' - ] : [ - 'flex-objects/types/default/' ~ template ~ '.html.twig', - 'flex-objects/layouts/404.html.twig' - ] -%} diff --git a/plugins/flex-objects/admin/templates/flex-objects.json.twig b/plugins/flex-objects/admin/templates/flex-objects.json.twig deleted file mode 100644 index c5b85dc..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects.json.twig +++ /dev/null @@ -1 +0,0 @@ -{{- admin.json_response|json_encode|raw -}} \ No newline at end of file diff --git a/plugins/flex-objects/admin/templates/flex-objects/layouts/404.html.twig b/plugins/flex-objects/admin/templates/flex-objects/layouts/404.html.twig deleted file mode 100644 index 6101c81..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/layouts/404.html.twig +++ /dev/null @@ -1 +0,0 @@ -{{ 'PLUGIN_FLEX_OBJECTS.ERROR.LAYOUT_NOT_FOUND'|tu(template, null) }} diff --git a/plugins/flex-objects/admin/templates/flex-objects/layouts/accounts/partials/top.html.twig b/plugins/flex-objects/admin/templates/flex-objects/layouts/accounts/partials/top.html.twig deleted file mode 100644 index 46b1ef6..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/layouts/accounts/partials/top.html.twig +++ /dev/null @@ -1,25 +0,0 @@ -{% set active_html = 'class="active"' %} -{% set is_configure = route.gravParam('') is same as('configure') %} -{% set authorize = directory.config('admin.views.configure.authorize') ?? directory.config('admin.configure.authorize') ?? 'admin.super' %} - -{% if allowed %} -
-
- {% for name,title in {'user-accounts': 'PLUGIN_ADMIN.USERS', 'user-groups': 'PLUGIN_ADMIN.GROUPS'} %} - {% set current = flex.directory(name) %} - {% if current and current.isAuthorized('list', 'admin', user) %} - {% set active = not is_configure and nav_route|starts_with(flex.adminRoute(current)|trim('/') ~ '/') %} - - {{ title|tu }} - - {% endif %} - {% endfor %} - - {% if user.authorize(authorize) or user.authorize('admin.super') %} - - {{ 'PLUGIN_ADMIN.CONFIGURATION'|tu }} - - {% endif %} -
-
-{% endif %} diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/default/buttons/add.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/default/buttons/add.html.twig deleted file mode 100644 index cb91524..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/default/buttons/add.html.twig +++ /dev/null @@ -1,3 +0,0 @@ - - {{ 'PLUGIN_ADMIN.ADD'|tu }} - diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/default/buttons/back.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/default/buttons/back.html.twig deleted file mode 100644 index dbb57c6..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/default/buttons/back.html.twig +++ /dev/null @@ -1,3 +0,0 @@ - - {{ "PLUGIN_ADMIN.BACK"|tu }} - diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/default/buttons/configuration.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/default/buttons/configuration.html.twig deleted file mode 100644 index 2a463b2..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/default/buttons/configuration.html.twig +++ /dev/null @@ -1,7 +0,0 @@ -{%- set authorize = directory.config('admin.views.configure.authorize') ?? directory.config('admin.configure.authorize') ?? 'admin.super' %} - -{%- if configure_url and user.authorize(authorize) %} - - {{ 'PLUGIN_ADMIN.CONFIGURATION'|tu }} - -{% endif %} diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/default/buttons/delete.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/default/buttons/delete.html.twig deleted file mode 100644 index 779760e..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/default/buttons/delete.html.twig +++ /dev/null @@ -1,3 +0,0 @@ - - {{ 'PLUGIN_ADMIN.DELETE'|tu }} - diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/default/buttons/export-csv.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/default/buttons/export-csv.html.twig deleted file mode 100644 index 6a8fadc..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/default/buttons/export-csv.html.twig +++ /dev/null @@ -1,3 +0,0 @@ - - {{ 'PLUGIN_FLEX_OBJECTS.CSV'|tu }} - diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/default/buttons/export.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/default/buttons/export.html.twig deleted file mode 100644 index 99a36e1..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/default/buttons/export.html.twig +++ /dev/null @@ -1,21 +0,0 @@ -{% if export.options %} -
- - -
- -{% else %} - - {{ export.title ?? (export.formatter.class ? 'PLUGIN_ADMIN.EXPORT'|tu : 'PLUGIN_FLEX_OBJECTS.CSV'|tu) }} - -{% endif %} \ No newline at end of file diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/default/buttons/languages.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/default/buttons/languages.html.twig deleted file mode 100644 index 58c2551..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/default/buttons/languages.html.twig +++ /dev/null @@ -1,18 +0,0 @@ -
- - {% if admin_languages|length > (language in admin_languages)|int %} - - - {% endif %} -
diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/default/buttons/preview-open.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/default/buttons/preview-open.html.twig deleted file mode 100644 index df8893d..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/default/buttons/preview-open.html.twig +++ /dev/null @@ -1,5 +0,0 @@ -{% if preview_url %} - - {{ "PLUGIN_ADMIN.OPEN_NEW_TAB"|tu }} - -{% endif %} diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/default/buttons/preview.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/default/buttons/preview.html.twig deleted file mode 100644 index 00390a6..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/default/buttons/preview.html.twig +++ /dev/null @@ -1,3 +0,0 @@ - - {{ "PLUGIN_ADMIN.PREVIEW"|tu }} - diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/default/buttons/save.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/default/buttons/save.html.twig deleted file mode 100644 index 379d97d..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/default/buttons/save.html.twig +++ /dev/null @@ -1,4 +0,0 @@ -{% set task = task ?? 'save' %} - diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/default/configure.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/default/configure.html.twig deleted file mode 100644 index 2d72493..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/default/configure.html.twig +++ /dev/null @@ -1,103 +0,0 @@ -{% extends 'partials/base.html.twig' %} -{% use 'flex-objects/types/default/titlebar/configure.html.twig' %} - -{% set name = view_config['form'] %} -{% set form = form ?? directory.directoryForm(name) %} - -{# Allowed actions #} -{% set can_save = can_save ?? user.authorize(view_config['authorize'] ?? 'admin.super') %} - -{# These variables can be overridden from the main template file #} -{% set allowed = allowed ?? (directory and form and can_save) %} -{% set back_route = back_route ?? ('/' ~ route.getRoute(1)) %} -{% set title_icon = title_icon ?? view_config['icon'] ?? 'fa-cog' %} -{% set title -%} - {%- set title_config = view_config['title'] ?? null -%} - {%- if title_config.template -%} - {{- include(template_from_string(title_config.template, 'configure title template')) -}} - {%- else -%} - {{- directory.title|tu }} - {{ 'PLUGIN_ADMIN.CONFIGURATION'|tu -}} - {% endif %} -{%- endset %} - -{% macro spanToggle(input, length) %} - {{ (repeat('  ', (length - input|length) / 2) ~ input ~ repeat('  ', (length - input|length) / 2))|raw }} -{% endmacro %} -{% import _self as macro %} - -{% block body %} - {% set back_url = back_url ?? admin_route(back_route) %} - - {{ parent() }} -{% endblock body %} - -{% block content_top %} - {% if allowed and user.authorize('admin.super') %} - {% set save_location = directory.getDirectoryConfigUri(name) %} -
{{ "PLUGIN_ADMIN.SAVE_LOCATION"|tu }}: {{ url(save_location, false, true)|trim('/') }}
- {% endif %} -{% endblock %} - -{% block topbar %} - {% if user.authorize('admin.super') %} -
- {% set normalText = 'PLUGIN_ADMIN.NORMAL'|tu %} - {% set expertText = 'PLUGIN_ADMIN.EXPERT'|tu %} - {% set maxLen = max([normalText|length, expertText|length]) %} - {% set normalText = macro.spanToggle(normalText, maxLen) %} - {% set expertText = macro.spanToggle(expertText, maxLen) %} - -
- - - - - -
-
- {% endif %} -{% endblock topbar %} - -{% block content %} - {{ parent() }} - - {% if allowed %} -
-
- {# TODO: RAW MODE -
- {{ block('topbar') }} -
- #} - {% block edit %} - {% include 'partials/blueprints.html.twig' with { form: form, data: form.data } %} - {% endblock %} -
-
- - {% include 'partials/modal-changes-detected.html.twig' %} - - {% else %} - - {% do page.modifyHeader('http_response_code', 404) %} -
-

{{ 'PLUGIN_ADMIN.ERROR'|tu }} 404

-
-

- {{ 'PLUGIN_FLEX_OBJECTS.ERROR.PAGE_NOT_EXIST'|tu }} -

-
-
- - {% endif %} -{% endblock %} - -{% block bottom %} - {{ parent() }} - - {# TODO: RAW MODE - - #} -{% endblock bottom %} diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/default/edit.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/default/edit.html.twig deleted file mode 100644 index ecab064..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/default/edit.html.twig +++ /dev/null @@ -1,121 +0,0 @@ -{% extends 'partials/base.html.twig' %} -{% use 'flex-objects/types/default/titlebar/edit.html.twig' %} - -{# Avoid defining form and object twice: object should always come from the form! #} -{% if form is not defined %} - {% set form = object.form %} - {% set object = form.object %} -{% endif %} - -{# Allowed actions #} -{% set can_list = can_list ?? directory.isAuthorized('list', 'admin', user) %} -{% set can_read = can_read ?? (object.exists ? object.isAuthorized('read', 'admin', user) : directory.isAuthorized('create', 'admin', user)) %} -{% set can_create = can_create ?? object.isAuthorized('create', 'admin', user) %} -{% set can_save = can_save ?? (object.exists ? object.isAuthorized('update', 'admin', user) : directory.isAuthorized('create', 'admin', user)) %} -{% set can_delete = can_delete ?? (object.exists and object.isAuthorized('delete', 'admin', user)) %} -{% set can_translate = can_translate ?? (admin.multilang and object.hasFlexFeature('flex-translate')) %} -{% set can_preview = can_preview ?? (can_read and object.exists and (directory.config('admin.views.preview.enabled') ?? directory.config('admin.preview.enabled', false))) %} - -{# Translations #} -{% if can_translate %} - {% set translate_include_default = translate_include_default ?? grav.config.get('system.languages.include_default_lang_file_extension', true) %} - {% set all_languages = grav.admin.siteLanguages %} - {% set admin_languages = admin.languages_enabled %} - {% set default_language = grav.language.default %} - {% set object_language = object.language %} - {% set language = controller.language %} - {% set has_translation = object.hasTranslation(language, false) %} - - {# - {% if translate_include_default %} - {% set all_languages = all_languages|merge({'': 'Default'}) %} - {% set admin_languages = admin_languages|merge({'': ''}) %} - {% set object_languages = object.languages(true) %} - {% else %} - #} - {% set language = language ?: default_language %} - {% set object_language = object_language ?: default_language %} - {% set object_languages = object.languages(false) %} - {# endif #} -{% endif %} - -{# These variables can be overridden from the main template file #} -{% set allowed = allowed ?? (directory and (object.exists and (can_read or can_save)) or (action == 'add' and can_read)) %} -{% set back_route = back_route ?? ('/' ~ (action != 'edit' and not key ? route.getRoute(1, not can_list ? -1 : null) : route.getRoute(1, not can_list ? -2 : -1))) %} -{% set title_icon = title_icon ?? view_config['icon'] ?? directory.config.admin.menu.list.icon ?? 'fa-file-text-o' %} -{% set title -%} - {%- set title_config = view_config['title'] -%} - {%- if title_config.template -%} - {{- include(template_from_string(title_config.template, 'edit title template')) -}} - {%- else -%} - {{- title ?? object.form.getValue('title') ?? object.title ?? key -}} - {% endif %} -{%- endset %} - -{% block body %} - {% set back_url = back_url ?? admin_route(back_route) %} - {% set id = key %} - {% set blueprint = blueprint ?? form.blueprint %} - - {{ parent() }} -{% endblock body %} - -{% block content_top %} - {% if allowed and user.authorize('admin.super') %} - {% if directory and object or action == 'add' %} - {% set save_location = object.getStorageFolder() ?? directory.getStorageFolder() %} -
{{ "PLUGIN_ADMIN.SAVE_LOCATION"|tu }}: {{ url(save_location, false, true)|trim('/') }} {{ not object.exists ? '[' ~ 'PLUGIN_FLEX_OBJECTS.NEW'|tu|upper ~ ']' }}
- {% endif %} - {% endif %} - {% if object.exists and form.flash.exists %} -
- {{ 'PLUGIN_FLEX_OBJECTS.STATE.EDITING_DRAFT'|tu }} -
- {% endif %} -{% endblock %} - -{% block content %} - {% if allowed %} -
-
-
- {% block topbar %}{% endblock %} -
- {% block edit %} - {% include 'partials/blueprints.html.twig' with { form: form, context: object, data: object } %} - {% endblock %} -
-
- - {% include 'partials/modal-changes-detected.html.twig' %} - - {% if can_delete %} - {% include ['flex-objects/types/' ~ target ~ '/modals/remove.html.twig', 'flex-objects/types/default/modals/remove.html.twig'] with { name: target } %} - {% endif %} - - {% elseif (object.exists) %} - - {% do page.modifyHeader('http_response_code', 403) %} -
-

{{ 'PLUGIN_ADMIN.ERROR'|tu }} 403

-
-

- {{ 'PLUGIN_FLEX_OBJECTS.ERROR.PAGE_FORBIDDEN'|tu }} -

-
-
- - {% else %} - - {% do page.modifyHeader('http_response_code', 404) %} -
-

{{ 'PLUGIN_ADMIN.ERROR'|tu }} 404

-
-

- {{ 'PLUGIN_FLEX_OBJECTS.ERROR.PAGE_NOT_EXIST'|tu }} -

-
-
- - {% endif %} -{% endblock %} diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/default/list.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/default/list.html.twig deleted file mode 100644 index abd40a9..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/default/list.html.twig +++ /dev/null @@ -1,98 +0,0 @@ -{% extends 'partials/base.html.twig' %} -{% use 'flex-objects/types/default/titlebar/list.html.twig' %} - -{# Allowed actions #} -{% set export = directory.config('admin.views.export') ?? directory.config('admin.export') ?? [] %} -{% set can_export = can_export ?? (export['enabled'] ?? export|array|count)|bool %} -{% set can_create = can_create ?? directory.isAuthorized('create', 'admin', user) %} -{% set can_translate = can_translate ?? (admin.multilang and directory.object.hasFlexFeature('flex-translate')) %} - -{% set per_page = per_page ?? grav.uri.currentUri.queryParam('per_page') %} - -{# Translations #} -{% if can_translate %} - {% set translate_include_default = translate_include_default ?? grav.config.get('system.languages.include_default_lang_file_extension', true) %} - {% set all_languages = grav.admin.siteLanguages %} - {% set admin_languages = admin.languages_enabled %} - {% set default_language = grav.language.default %} - {% set language = controller.language %} - {# - {% if translate_include_default %} - {% set all_languages = all_languages|merge({'': 'Default'}) %} - {% set admin_languages = admin_languages|merge({'': ''}) %} - {% else %} - #} - {% set language = language ?: default_language %} - {# endif #} -{% endif %} - -{# These variables can be overridden from the main template file #} -{% set allowed = allowed ?? (directory and directory.isAuthorized('list', 'admin', user)) %} -{% set back_route = back_route ?? route.getRoute(1, -1) %} - -{% set configure_path = directory.config('admin.router.actions.configure.path') %} -{% set configure_route = configure_route ?? (configure_path ? route.withRoute(admin_route(configure_path).toString(true)|trim('/')) : null) %} -{% set configure_route = configure_route ?? route.withGravParam('', 'configure').toString(true) %} - -{% set title_icon = title_icon ?? view_config['icon'] ?? directory.config.admin.menu.list.icon ?? 'fa-file-text-o' %} -{% set title -%} - {%- set title_config = view_config['title'] ?? null -%} - {%- if title_config.template -%} - {{- include(template_from_string(title_config.template, 'configure title template')) -}} - {%- else -%} - {{- directory.title|tu -}} - {% endif %} -{%- endset %} - -{% set schema = directory.blueprint.schema %} - -{% do assets.addJs('plugin://flex-objects/js/flex-objects.js', { 'group': 'bottom', 'loading': 'defer' }) %} - -{% block body %} - {% set collection = directory ? collection.isAuthorized('list', 'admin', user) %} - {% set directory_config = view_config['options'] ?? config.get('plugins.flex-objects.admin_list', { per_page: 15, order: { by: 'updated_timestamp', dir: 'desc' }}) %} - {% set per_page = max(1, per_page ?? directory_config.per_page) %} - {% set table = directory ? flex.dataTable(collection.flexDirectory(), { collection: collection, limit: per_page, sort: directory_config.order.by ~ '|' ~ directory_config.order.dir }) %} - {% set back_url = admin_route(back_route) %} - {% set configure_url = (directory.config('admin.views.configure.hidden') ?? directory.config('admin.configure.hidden', false)) is not same as(true) ? configure_route.toString(true) %} - - {% set fields = table.getColumns() %} - {% set fields_count = fields ? count(fields) : 0 %} - {% set fields_width = 8 %} - {% set fields_set = 0 %} - {% set title_field = view_config['title'] %} - {% for key,options in fields %} - {% set fields_width = fields_width + options.width ?: 0 %} - {% set fields_set = fields_set + (options.width ? 1 : 0) %} - {% if not title_field and options.link == 'edit' %} - {% set title_field = key %} - {% endif %} - {% endfor %} - - {{ parent() }} -{% endblock body %} - -{% block content_top %} -{% if allowed and user.authorize('admin.super') %} - {% set save_location = directory.getStorageFolder() %} -
{{ "PLUGIN_ADMIN.SAVE_LOCATION"|tu }}: {{ url(save_location, false, true)|trim('/') }}
-{% endif %} -{% endblock %} - -{% block content %} -{% if allowed %} - {% block content_list %} - {% include ['flex-objects/types/' ~ target ~ '/list/list.html.twig', 'flex-objects/types/default/list/list.html.twig'] %} - {% endblock %} -{% else %} - {% do page.modifyHeader('http_response_code', 404) %} -
-

{{ 'PLUGIN_ADMIN.ERROR'|tu }} 404

-
-

- {{ 'PLUGIN_FLEX_OBJECTS.ERROR.PAGE_NOT_EXIST'|tu }} -

-
-
-{% endif %} -{% endblock %} diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/default/list/list.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/default/list/list.html.twig deleted file mode 100644 index 2200e53..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/default/list/list.html.twig +++ /dev/null @@ -1,112 +0,0 @@ -{% block directory %} -
- {% if not fields %} - {% block no_list %} -
-

{{ 'PLUGIN_FLEX_OBJECTS.ERROR.BLUEPRINT_NO_LIST'|tu( target, null )|raw }}

-
    -
  • - {{ 'PLUGIN_FLEX_OBJECTS.ERROR.BLUEPRINT_NO_LIST_ADVISE'|tu }} -
  • -
  • - {{ 'PLUGIN_FLEX_OBJECTS.ERROR.BLUEPRINT_NO_LIST_TEMPLATE'|tu( target, null )|raw }} -
  • -
-
- {% endblock %} - {% elseif not collection.count %} - {% block no_entries %} -
- {% if directory.isAuthorized('create', 'admin', user) %} - {% set createLink = admin_route(flex.adminRoute(collection, {action: 'add'})) %} - {{ 'PLUGIN_FLEX_OBJECTS.ERROR.LIST_EMPTY_ADD'|tu(createLink, null)|raw }} - {% else %} - {{ 'PLUGIN_FLEX_OBJECTS.ERROR.LIST_EMPTY'|tu }} - {% endif %} -
- {% endblock %} - {% else %} - {% block entries %} - {% set per_page = per_page ?? directory_config.per_page %} - - {% set tableFields = [] %} - {% set searchFields = [] %} - {% for key, options in fields %} - {% set name = key %} - {% set sortField = options.sort.field ?? key %} - {% set title = (options.field.label ?? schema.get(options.alias ?? key).label)|tu %} - {% set width = options.width ?: ((100-fields_width) / ((fields_count-fields_set) ?: 1))|round(3) %} - {% set title_class = options.title_class ?: '' %} - {% set data_class = options.data_class ?: '' %} - - {# Vuetable doesn't like field names with `.` in them, so we convert name and sortField to `_` #} - {% set tableFields = tableFields|merge([ - { - name: name|replace({'.': '_'}), - sortField: sortField, - title: title ?? 'N/A', - width: width ~ '%', - titleClass: title_class, - dataClass: data_class - } - ]) %} - - {# FIXME: Search fields should be passed and individually customizable, right now defaulting to all fields selected #} - {% set searchFields = searchFields|merge([key|replace({'.': '_'})]) %} - {% endfor %} - {% set tableFields = tableFields|merge([{ name: '_actions_', title: "PLUGIN_FLEX_OBJECTS.ACTION.ACTIONS"|tu, titleClass: 'right' }]) %} - - - {% set list = table.jsonSerialize %} - -
- - {% for i in 0..((min(per_page, list.data|count) + 3) - 1) %} - - - - - - - - - - - - - - - - - - - - - - - - {% endfor %} - -
- {% endblock %} - {% endif %} - - {% block modals %} - {% include 'flex-objects/types/default/modals/remove.html.twig' with { name: target } %} - {% endblock %} -
-{% endblock %} diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/default/list/list_actions.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/default/list/list_actions.html.twig deleted file mode 100644 index e4d9da5..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/default/list/list_actions.html.twig +++ /dev/null @@ -1,39 +0,0 @@ -{% set object_title = title_field ? "'" ~ object[title_field]|join(' ') ~ "'" : 'Item' %} -{% set can_read = object.isAuthorized('read', 'admin', user) %} -{% set can_update = object.isAuthorized('update', 'admin', user) %} -{% set can_delete = object.isAuthorized('delete', 'admin', user) %} - -{% if can_read and object.getRoute() %} - {% block action_preview %} - - - - {% endblock %} -{% endif %} - -{% if can_update %} - {% block action_edit %} - - - - {% endblock %} -{% elseif can_read %} - {% block action_read %} - - - - {% endblock %} -{% endif %} - -{% if can_delete %} - {% block action_delete %} - - - - {% endblock %} -{% endif %} diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/default/modals/remove.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/default/modals/remove.html.twig deleted file mode 100644 index f37500a..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/default/modals/remove.html.twig +++ /dev/null @@ -1,13 +0,0 @@ -
-
- {# FIXME -name|singularize- is not translatable #} -

{{ 'PLUGIN_FLEX_OBJECTS.ACTION.DELETE_N'|tu }} {{ name|singularize|capitalize }}

-

- {{ 'PLUGIN_FLEX_OBJECTS.ACTION.REALLY_DELETE'|tu( name|singularize, null ) }} -

-
- - {{ "PLUGIN_ADMIN.CONTINUE"|tu }} -
-
-
diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/default/preview.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/default/preview.html.twig deleted file mode 100644 index 3e24744..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/default/preview.html.twig +++ /dev/null @@ -1,62 +0,0 @@ -{% extends 'partials/base.html.twig' %} -{% use 'flex-objects/types/default/titlebar/preview.html.twig' %} - -{# Allowed actions #} -{% set can_preview = can_preview ?? (object.exists and (view_config['enabled'] ?? false)) %} -{% set can_translate = can_translate ?? (admin.multilang and object.hasFlexFeature('flex-translate')) %} - -{# These variables can be overridden from the main template file #} -{% set allowed = allowed ?? (directory and (object.exists or action == 'add')) %} -{% set back_route = back_route ?? ('/' ~ route.getRoute(1)) %} -{% set title_icon = title_icon ?? view_config['icon'] ?? directory.config.admin.menu.list.icon ?? 'fa-file-text-o' %} -{% set title -%} - {%- set title_config = view_config['title'] -%} - {%- if title_config.template -%} - {{- include(template_from_string(title_config.template, 'edit title template')) -}} - {%- else -%} - {{- title ?? object.form.getValue('title') ?? object.title ?? key -}} - {% endif %} -{%- endset %} -{% set preview_url -%} - {%- set route_config = view_config['route'] -%} - {%- if route_config.template -%} - {{- include(template_from_string(route_config.template, 'preview route template')) -}} - {%- else -%} - {{- preview_url ?? object.getRoute().uri ?: '' -}} - {%- endif -%} -{% endset -%} - -{% block body %} - {% if not can_preview or not preview_url %} - {% set allowed = false %} - {% endif %} - {% set id = key %} - {% set blueprint = object.blueprint ?? directory.blueprint %} - {% set back_url = back_url ?? admin_route(back_route) %} - - {{ parent() }} -{% endblock body %} - -{% block content_wrapper %} -{% if can_preview and allowed and preview_url %} -
-
- -
-
-{% else %} - {{ parent() }} -{% endif %} -{% endblock content_wrapper %} - -{% block content %} - {% do page.modifyHeader('http_response_code', 404) %} -
-

{{ 'PLUGIN_ADMIN.ERROR'|tu }} 404

-
-

- {{ 'PLUGIN_FLEX_OBJECTS.ERROR.PAGE_NOT_EXIST'|tu }} -

-
-
-{% endblock content %} \ No newline at end of file diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/default/titlebar/configure.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/default/titlebar/configure.html.twig deleted file mode 100644 index 08d6f86..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/default/titlebar/configure.html.twig +++ /dev/null @@ -1,32 +0,0 @@ -{% block titlebar %} - {% block titlebar_button_bar %} -
- {# BACK #} - {% block back_button %} - {% include ['flex-objects/types/' ~ target ~ '/buttons/back.html.twig', 'flex-objects/types/default/buttons/back.html.twig'] %} - {% endblock back_button %} - - {% block extra_buttons %}{% endblock extra_buttons %} - - {# SAVE #} - {% if can_save %} - {% block save_button %} - {% include ['flex-objects/types/' ~ target ~ '/buttons/save.html.twig', 'flex-objects/types/default/buttons/save.html.twig'] with {task: 'configure'} %} - {% endblock save_button %} - {% endif %} -
- {% endblock titlebar_button_bar %} - - {% block titlebar_title %} -

- {% if allowed %} - - {{ title }} - {% else %} - - {{ 'PLUGIN_ADMIN.ERROR'|tu }} -   {% endif %} -

- {% endblock titlebar_title %} - -{% endblock %} diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/default/titlebar/edit.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/default/titlebar/edit.html.twig deleted file mode 100644 index b209e44..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/default/titlebar/edit.html.twig +++ /dev/null @@ -1,46 +0,0 @@ -{% block titlebar %} - {% block titlebar_button_bar %} -
- {# BACK #} - {% block back_button %} - {% include ['flex-objects/types/' ~ target ~ '/buttons/back.html.twig', 'flex-objects/types/default/buttons/back.html.twig'] %} - {% endblock back_button %} - - {# PREVIEW #} - {% if can_preview %} - {% block preview_button %} - {% include ['flex-objects/types/' ~ target ~ '/buttons/preview.html.twig', 'flex-objects/types/default/buttons/preview.html.twig'] %} - {% endblock preview_button %} - {% endif %} - - {# DELETE #} - {% if can_delete %} - {% block delete_button %} - {% include ['flex-objects/types/' ~ target ~ '/buttons/delete.html.twig', 'flex-objects/types/default/buttons/delete.html.twig'] %} - {% endblock delete_button %} - {% endif %} - - {% block extra_buttons %}{% endblock extra_buttons %} - - {# SAVE #} - {% if allowed and can_save %} - {% block save_button %} - {% include ['flex-objects/types/' ~ target ~ '/buttons/save.html.twig', 'flex-objects/types/default/buttons/save.html.twig'] with {task: 'save'} %} - {% endblock save_button %} - {% endif %} -
- {% endblock titlebar_button_bar %} - - {% block titlebar_title %} -

- {% if allowed %} - - {{ not object.exists ? '[' ~ 'PLUGIN_FLEX_OBJECTS.NEW'|tu|upper ~ ']' }} {{ title|tu }} - {% else %} - - {{ 'PLUGIN_ADMIN.ERROR'|tu }} - {% endif %} -

- {% endblock titlebar_title %} - -{% endblock %} diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/default/titlebar/list.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/default/titlebar/list.html.twig deleted file mode 100644 index 4397606..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/default/titlebar/list.html.twig +++ /dev/null @@ -1,48 +0,0 @@ -{% block titlebar %} - {% block titlebar_button_bar %} -
- {# BACK #} - {% block back_button %} - {% include ['flex-objects/types/' ~ target ~ '/buttons/back.html.twig', 'flex-objects/types/default/buttons/back.html.twig'] %} - {% endblock back_button %} - - {# EXPORT #} - {% if can_export %} - {% block export_button %} - {% include ['flex-objects/types/' ~ target ~ '/buttons/export.html.twig', 'flex-objects/types/default/buttons/export.html.twig'] with {export: directory.config('admin.views.export') ?? directory.config('admin.export') ?? []} %} - {% endblock export_button %} - {% endif %} - - {# CREATE #} - {% if can_create %} - {% block create_button %} - {% include ['flex-objects/types/' ~ target ~ '/buttons/add.html.twig', 'flex-objects/types/default/buttons/add.html.twig'] %} - {% endblock create_button %} - {% endif %} - - {# LANGUAGES #} - {% if can_translate %} - {% block languages_button %} - {% include ['flex-objects/types/' ~ target ~ '/buttons/languages.html.twig', 'flex-objects/types/default/buttons/languages.html.twig'] %} - {% endblock languages_button %} - {% endif %} - - {# CONFIGURE #} - {% block configure %} - {% include 'flex-objects/types/default/buttons/configuration.html.twig' %} - {% endblock configure %} -
- {% endblock titlebar_button_bar %} - - {% block titlebar_title %} -

- {% if allowed %} - - {{ directory ? title|tu : 'Error' }} - {% else %} - - {{ 'PLUGIN_ADMIN.ERROR'|tu }} - {% endif %} -

- {% endblock titlebar_title %} -{% endblock %} diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/default/titlebar/preview.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/default/titlebar/preview.html.twig deleted file mode 100644 index 6b7bad7..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/default/titlebar/preview.html.twig +++ /dev/null @@ -1,30 +0,0 @@ -{% block titlebar %} - {% block titlebar_button_bar %} -
- {# BACK #} - {% block back_button %} - {% include ['flex-objects/types/' ~ target ~ '/buttons/back.html.twig', 'flex-objects/types/default/buttons/back.html.twig'] %} - {% endblock back_button %} - - {# PREVIEW #} - {% if can_preview %} - {% block preview_button %} - {% include ['flex-objects/types/' ~ target ~ '/buttons/preview-open.html.twig', 'flex-objects/types/default/buttons/preview-open.html.twig'] %} - {% endblock preview_button %} - {% endif %} -
- {% endblock titlebar_button_bar %} - - {% block titlebar_title %} -

- {% if allowed %} - - {{ "PLUGIN_ADMIN.PREVIEW"|tu }}: {{ not object.exists ? '[' ~ 'PLUGIN_FLEX_OBJECTS.NEW'|tu|upper ~ ']' }} {{ title }} - {% else %} - - {{ 'PLUGIN_ADMIN.ERROR'|tu }} - {% endif %} -

- {% endblock titlebar_title %} - -{% endblock %} diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/default/titlebar/types.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/default/titlebar/types.html.twig deleted file mode 100644 index 97789de..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/default/titlebar/types.html.twig +++ /dev/null @@ -1,22 +0,0 @@ -{% block titlebar %} - {% block titlebar_button_bar %} -
- {# BACK #} - {% block back_button %} - {% include 'flex-objects/types/default/buttons/back.html.twig' %} - {% endblock back_button %} - - {# CONFIGURE #} - {% block configure %} - {% include 'flex-objects/types/default/buttons/configuration.html.twig' %} - {% endblock configure %} -
- {% endblock titlebar_button_bar %} - - {% block titlebar_title %} -

- - {{ "PLUGIN_FLEX_OBJECTS.TITLE"|tu }} -

- {% endblock titlebar_title %} -{% endblock %} diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/default/types.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/default/types.html.twig deleted file mode 100644 index 88b1ab2..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/default/types.html.twig +++ /dev/null @@ -1,46 +0,0 @@ -{% extends 'partials/base.html.twig' %} -{% use 'flex-objects/types/default/titlebar/types.html.twig' %} - -{% set flex = grav['flex_objects'] %} - -{# These variables can be overridden from the main template file #} -{% set back_route = back_route ?? ('/' ~ route.getRoute(1, -1)) %} -{% set configure_route = '/plugins/flex-objects' %} - -{% block body %} - {% set back_url = admin_route(back_route) %} - {% set configure_url = configure_route ? admin_route(configure_route) : null %} - - {{ parent() }} -{% endblock body %} - -{% block content %} - -

{{ 'PLUGIN_FLEX_OBJECTS.TYPES_TITLE'|tu }}

- -
- {% for name,directory in flex.directories if directory.enabled and directory.config('admin.hidden', false) is not same as(true) and not directory.config('admin.menu') %} - {% try %} - {% set collection = directory.collection %} - {% if flex.adminRoute(collection) %} -
- -

{{ directory.title|tu }} {{ collection.isAuthorized('list', 'admin', user).count }}

-

- {{ directory.description }} -

-
- {% endif %} - {% catch %} -
-

{{ 'PLUGIN_FLEX_OBJECTS.ERROR.BAD_DIRECTORY'|tu }} '{{ name }}'

-

- {{ e.message }} -

-
- {% endcatch %} - {% endfor %} - -
- -{% endblock %} \ No newline at end of file diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/add.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/add.html.twig deleted file mode 100644 index 74242aa..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/add.html.twig +++ /dev/null @@ -1,20 +0,0 @@ -
- - - -
diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/back.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/back.html.twig deleted file mode 100644 index df0761a..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/back.html.twig +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/copy.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/copy.html.twig deleted file mode 100644 index 47ec501..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/copy.html.twig +++ /dev/null @@ -1,4 +0,0 @@ -{# href="{{ uri.addNonce(route.withoutParams().withGravParam('task', 'copy').getUri(), 'admin-form', 'admin-nonce') }}" #} - - {{ "PLUGIN_ADMIN.COPY"|tu }} - diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/delete.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/delete.html.twig deleted file mode 100644 index 859b38b..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/delete.html.twig +++ /dev/null @@ -1,3 +0,0 @@ - - {{ "PLUGIN_ADMIN.DELETE"|tu }} - diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/move.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/move.html.twig deleted file mode 100644 index 17f607c..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/move.html.twig +++ /dev/null @@ -1,6 +0,0 @@ - - {{ "PLUGIN_ADMIN.MOVE"|tu }} - -
- {% include 'partials/page-move.html.twig' with { blueprints: admin.blueprints('admin/pages/move'), data: context } %} -
\ No newline at end of file diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/nav-child.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/nav-child.html.twig deleted file mode 100644 index 778ccac..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/nav-child.html.twig +++ /dev/null @@ -1,9 +0,0 @@ -{% if child_url %} - - - -{% else %} - - - -{% endif %} diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/nav-next.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/nav-next.html.twig deleted file mode 100644 index c38113a..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/nav-next.html.twig +++ /dev/null @@ -1,9 +0,0 @@ -{% if next_url %} - - - -{% else %} - - - -{% endif %} diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/nav-parent.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/nav-parent.html.twig deleted file mode 100644 index b57f851..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/nav-parent.html.twig +++ /dev/null @@ -1,9 +0,0 @@ -{% if parent_url %} - - - -{% else %} - - - -{% endif %} diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/nav-prev.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/nav-prev.html.twig deleted file mode 100644 index 141e9b2..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/nav-prev.html.twig +++ /dev/null @@ -1,9 +0,0 @@ -{% if prev_url %} - - - -{% else %} - - - -{% endif %} \ No newline at end of file diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/preview.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/preview.html.twig deleted file mode 100644 index 1d2a918..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/preview.html.twig +++ /dev/null @@ -1,5 +0,0 @@ -{% if object.routable and object.published %} - - - -{% endif %} diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/save.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/save.html.twig deleted file mode 100644 index 7d171a5..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/pages/buttons/save.html.twig +++ /dev/null @@ -1,23 +0,0 @@ -{% set task = task ?? 'save' %} -
- - {% if can_translate %} - {% set untranslated = admin_languages|array_diff(object_languages) %} - {% if count(untranslated) %} - - - {% endif %} - {% endif %} -
diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/pages/edit.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/pages/edit.html.twig deleted file mode 100644 index a370b87..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/pages/edit.html.twig +++ /dev/null @@ -1,236 +0,0 @@ -{% extends 'flex-objects/types/default/edit.html.twig' %} - -{# Avoid defining form and object twice: object should always come from the form! #} -{% set expert = user.authorize('admin.super') and admin.session.expert != '0' %} -{% if expert or form is not defined %} - {% set form = object.form(expert ? 'raw' : '') %} - {% set object = form.object %} -{% endif %} - -{% set title = title ?? form.getValue('header.title') ?? object.title ?? key %} -{% set parent = object.parent %} -{% set can_read = can_read ?? (object.exists ? object.isAuthorized('read', 'admin', user) : object.isAuthorized('create', 'admin', user))|bool %} -{% set can_copy = can_copy ?? (parent.exists and parent.isAuthorized('create', 'admin', user)) %} -{% set can_create = can_create ?? (object.exists and object.isAuthorized('create', 'admin', user)) %} -{% set can_save = can_save ?? (object.exists ? object.isAuthorized('update', 'admin', user) : object.isAuthorized('create', 'admin', user))|bool %} -{% set can_move = can_move ?? can_save and form.blueprint.schema.property('route').type is same as('parents') %} -{% set can_translate = can_translate ?? (admin.multilang and object.hasFlexFeature('page-translate') and not object.root()) %} - -{% macro spanToggle(input, length) %} - {{ (repeat('  ', (length - input|length) / 2) ~ input ~ repeat('  ', (length - input|length) / 2))|raw }} -{% endmacro %} -{% import _self as macro %} - -{% block body %} - {% set current_route = '/' ~ route.getRoute(1) %} - - {% if not object.root() %} - {% set child = object.children.first %} - {% set prev = object.prevSibling %} - {% set next = object.nextSibling %} - - {% set parent_url = parent and not parent.root ? admin_route(back_route) %} - {% set child_url = can_read and child ? admin_route(current_route ~ '/' ~ child.slug) %} - {% set prev_url = can_read and prev ? admin_route(back_route ~ '/' ~ prev.slug) %} - {% set next_url = can_read and next ? admin_route(back_route ~ '/' ~ next.slug) %} - {% endif %} - {% set back_url = back_url ?? admin_route(flex.adminRoute(directory.getFlexType())) %} - - {{ parent() }} -{% endblock body %} - -{% block back_button %} - {% include ['flex-objects/types/' ~ target ~ '/buttons/back.html.twig', 'flex-objects/types/pages/buttons/back.html.twig'] - with { back_url: back_url } %} - {% if not object.root() %} - {% include ['flex-objects/types/' ~ target ~ '/buttons/nav-prev.html.twig', 'flex-objects/types/pages/buttons/nav-prev.html.twig'] - with { prev_url: prev_url, title: prev.route } %} - {% include ['flex-objects/types/' ~ target ~ '/buttons/nav-parent.html.twig', 'flex-objects/types/pages/buttons/nav-parent.html.twig'] - with { parent_url: parent_url, title: parent.route } %} - {% include ['flex-objects/types/' ~ target ~ '/buttons/nav-child.html.twig', 'flex-objects/types/pages/buttons/nav-child.html.twig'] - with { child_url: child_url, title: child.route } %} - {% include ['flex-objects/types/' ~ target ~ '/buttons/nav-next.html.twig', 'flex-objects/types/pages/buttons/nav-next.html.twig'] - with { next_url: next_url, title: next.route } %} - {% endif %} -{% endblock back_button %} - -{% block preview_button %} - {% if object.exists and not object.root() %} - {% include ['flex-objects/types/' ~ target ~ '/buttons/preview.html.twig', 'flex-objects/types/pages/buttons/preview.html.twig'] %} - {% endif %} -{% endblock preview_button %} - -{% block delete_button %} - {# FIXME: add support for deleting root file only #} - {% if not object.root() %} - {% include ['flex-objects/types/' ~ target ~ '/buttons/delete.html.twig', 'flex-objects/types/pages/buttons/delete.html.twig'] %} - {% endif %} -{% endblock delete_button %} - -{% block extra_buttons %} - {% if object.exists and not object.root() %} - {% if can_create %} - {% include ['flex-objects/types/' ~ target ~ '/buttons/add.html.twig', 'flex-objects/types/pages/buttons/add.html.twig'] %} - {% endif %} - {% if can_copy %} - {% include ['flex-objects/types/' ~ target ~ '/buttons/copy.html.twig', 'flex-objects/types/pages/buttons/copy.html.twig'] %} - {% endif %} - {% if can_move %} - {% include ['flex-objects/types/' ~ target ~ '/buttons/move.html.twig', 'flex-objects/types/pages/buttons/move.html.twig'] %} - {% endif %} - {% endif %} -{% endblock extra_buttons %} - -{% block save_button %} - {% include ['flex-objects/types/' ~ target ~ '/buttons/save.html.twig', 'flex-objects/types/pages/buttons/save.html.twig'] %} -{% endblock save_button %} - -{% block content_top %} - {% if allowed and user.authorize('admin.super') %} -
- {% set save_location = object.getStorageFolder() ?: directory.getStorageFolder() %} - {{ "PLUGIN_ADMIN.SAVE_LOCATION"|tu }}: {{ url(save_location, false, true)|trim('/') }} {{ not object.exists ? '[' ~ 'PLUGIN_FLEX_OBJECTS.NEW'|tu|upper ~ ']' }} (type: {{ (form.getValue('name') ?: 'default') }}) -
- {% endif %} - {% if object.exists and form.flash.exists %} -
- {{ 'PLUGIN_FLEX_OBJECTS.STATE.EDITING_DRAFT'|tu }} -
- {% endif %} - {% if not object.exists %} -
- {{ 'PLUGIN_FLEX_OBJECTS.STATE.NOT_CREATED_YET'|tu }} -
- {% elseif can_translate %} - {% set is_default = language is same as(default_language) %} - {% if is_default and default_language in object_languages %} - {% if not translate_include_default and object.property('lang') %} - {# Handle default language extension #} -
- {% set overrideLanguage = all_languages[object_language] ?? object_language %} - {{ 'PLUGIN_FLEX_OBJECTS.LANGUAGE.USING_OVERRIDE'|tu(overrideLanguage, null)|raw }} - {{ object.hasTranslation('', false) ? 'PLUGIN_FLEX_OBJECTS.LANGUAGE.UNUSED_DEFAULT'|tu|raw }} -
- {% elseif translate_include_default %} - {% if not object.property('lang') %} -
- {{ 'PLUGIN_FLEX_OBJECTS.LANGUAGE.USING_DEFAULT'|tu|raw }} -
- {% elseif object.hasTranslation('', false) %} -
- {{ 'PLUGIN_FLEX_OBJECTS.LANGUAGE.UNUSED_DEFAULT'|tu|raw }} -
- {% endif %} - {% endif %} - {% elseif not has_translation %} -
- {% set overrideLanguage = all_languages[language] ?? object_language %} - {{ 'PLUGIN_FLEX_OBJECTS.LANGUAGE.NOT_TRANSLATED_YET'|tu(overrideLanguage, null)|raw }} - {% if language == object_language %} - {{ 'PLUGIN_FLEX_OBJECTS.LANGUAGE.NO_FALLBACK_FOUND'|tu|raw }} - {% else %} - {% set overrideLanguage = all_languages[object_language] ?? object_language %} - {{ 'PLUGIN_FLEX_OBJECTS.LANGUAGE.FALLING_BACK'|tu(overrideLanguage, null)|raw }} - {% endif %} -
- {% endif %} - {% endif %} -{% endblock content_top %} - -{% block topbar %} - {% if can_translate %} -
- - {% if count(object_languages) > (object_language in object_languages)|int %} - - - {% endif %} -
- {% endif %} - - {% if user.authorize('admin.super') %} -
- {% set normalText = 'PLUGIN_ADMIN.NORMAL'|tu %} - {% set expertText = 'PLUGIN_ADMIN.EXPERT'|tu %} - {% set maxLen = max([normalText|length, expertText|length]) %} - {% set normalText = macro.spanToggle(normalText, maxLen) %} - {% set expertText = macro.spanToggle(expertText, maxLen) %} - -
- - - - - -
-
- {% endif %} -{% endblock topbar %} - -{% block edit %} - {% include 'partials/blueprints.html.twig' with { context: object, data: object, blueprints: form.blueprint } %} -{% endblock edit %} - -{% block content %} - {{ parent() }} - - {% include 'partials/modal-changes-detected.html.twig' %} - - {% if object.exists %} - {% set modal_data = data({ - route: '/' ~ object.key, - name: object.header.child_type ?? object.blueprint.child_type ?? 'default' - }) %} - -
- {% include 'partials/blueprints-new.html.twig' with { form: null, blueprints: admin.blueprints('admin/pages/new'), data: modal_data, form_id: 'new-page' } %} -
- -
- {% include 'partials/blueprints-new-folder.html.twig' with { form: null, blueprints: admin.blueprints('admin/pages/new_folder'), data: modal_data, form_id: 'new-folder' } %} -
- -
- {% include 'partials/blueprints-new.html.twig' with { form: null, blueprints: admin.blueprints('admin/pages/modular_new'), data: modal_data, form_id: 'new-module' } %} -
- -
- {% include 'partials/blueprints-copy.html.twig' with { blueprints: admin.blueprints('admin/pages/copy'), data: data({ title: object.title ~ ' (Copy)', folder: object.slug ~ '-copy' }), form_id: 'copy' } %} -
- {% endif %} - - {# TODO: regular pages support extra modals from admin config #} - -
-
-

{{ 'PLUGIN_FLEX_OBJECTS.PARENTS'|tu }}

-
{{ 'PLUGIN_FLEX_OBJECTS.STATE.LOADING'|tu }}
-
- -
-
- -{% endblock content %} - -{% block bottom %} - {{ parent() }} - -{% endblock bottom %} diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/pages/list.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/pages/list.html.twig deleted file mode 100644 index e4ab2f5..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/pages/list.html.twig +++ /dev/null @@ -1,29 +0,0 @@ -{% extends 'flex-objects/types/default/list.html.twig' %} - -{% set can_create = true %} - -{% block back_button %} - {% include ['flex-objects/types/' ~ target ~ '/buttons/back.html.twig', 'flex-objects/types/pages/buttons/back.html.twig'] %} -{% endblock back_button %} - -{% block create_button %} - {% for key, add_modal in config.plugins.admin.add_modals %} - {% if add_modal.show_in|default('bar') == 'bar' %} - {{ add_modal.label|tu }} - {% endif %} - {% endfor %} - - {% include ['flex-objects/types/' ~ target ~ '/buttons/add.html.twig', 'flex-objects/types/pages/buttons/add.html.twig'] %} -{% endblock %} - -{% block content_top %}{% endblock %} - -{% block content_list %} - {% set list_layout = grav.uri.param('layout', 'columns') %} - {% include [ - 'flex-objects/types/' ~ target ~ '/list/' ~ list_layout ~ '.html.twig', - 'flex-objects/types/pages/list/' ~ list_layout ~ '.html.twig', - 'flex-objects/types/' ~ target ~ '/list/list.html.twig', - 'flex-objects/types/pages/list/list.html.twig' - ] %} -{% endblock %} diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/pages/list/columns.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/pages/list/columns.html.twig deleted file mode 100644 index 082bb61..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/pages/list/columns.html.twig +++ /dev/null @@ -1,155 +0,0 @@ -{% macro toggle(id, title, filters, name = null) %} - {% set name = id|fieldName %} - {% set filter = filters[name] ?? null %} - {% set value = filter is null ? 0 : (not filter)|int+1 %} - {% set classes = ['status-unchecked', 'status-checked', 'status-indeterminate'] %} - - - - - -{% endmacro %} - -{% import _self as macros %} - -{% block directory %} - {% set filters = grav.request.getCookieParams()['grav-admin-flexpages']|base64_decode|json_decode(true)['filters'] %} - {% set hidePanel = filters|length == 0 or (filters|length == 1 and filters['filters[search]']) %} -
-
-
- - -
-
- - {{ 'PLUGIN_FLEX_OBJECTS.FILTER.PAGE_ATTRIBUTES'|tu }} - - {{ macros.toggle('filters.routable', 'Routable', filters) }} - {{ macros.toggle('filters.module', 'Module', filters) }} - {{ macros.toggle('filters.visible', 'Visible', filters) }} - {{ macros.toggle('filters.published', 'Published', filters) }} - {{ macros.toggle('filters.translated', 'Translated', filters) }} - {{ macros.toggle('filters.folder', 'Empty Folder', filters) }} -
- - {% set selected = filters['filters[page_type]']|split(',') %} - {% set page_types = admin.types(null) %} {# directory.config('filters.ignore_page_types') #} -
- - {{ 'PLUGIN_FLEX_OBJECTS.FILTER.PAGE_TYPES'|tu }} - - {% for name,title in page_types %} - - - - - {% endfor %} -
- - {% set module_types = admin.modularTypes(null) %} {# directory.config('filters.ignore_module_types') #} - {% if module_types %} -
- - {{ 'PLUGIN_FLEX_OBJECTS.FILTER.MODULAR_TYPES'|tu }} - - {% for name,title in module_types %} - - - - - {% endfor %} -
- {% endif %} - - - {{ 'PLUGIN_FLEX_OBJECTS.ACTION.APPLY_FILTERS'|tu }} - - - {{ 'PLUGIN_FLEX_OBJECTS.ACTION.RESET_FILTERS'|tu }} - -
-
-
- -
-
{{ 'PLUGIN_FLEX_OBJECTS.STATE.LOADING'|tu }}
-
-
- -
- - {# Modals #} -
- {% include 'partials/blueprints-new.html.twig' with { blueprints: admin.blueprints('admin/pages/new'), data: obj_data, form_id: 'new-page' } %} -
- -
- {% include 'partials/blueprints-new-folder.html.twig' with { blueprints: admin.blueprints('admin/pages/new_folder'), data: obj_data, form_id: 'new-folder' } %} -
- -
- {% include 'partials/blueprints-new.html.twig' with { blueprints: admin.blueprints('admin/pages/modular_new'), data: obj_data, form_id: 'new-module' } %} -
- - {% for key, add_modal in config.plugins.admin.add_modals %} -
- {% include add_modal.template|defined('partials/blueprints-new.html.twig') with { - blueprints: admin.blueprints(add_modal.blueprint), - data: obj_data, - form_id: 'add-modal' - }|merge(add_modal.with|defined({})) %} -
- {% endfor %} - -
- {% include 'partials/blueprints-copy.html.twig' with { blueprints: admin.blueprints('admin/pages/copy'), data: obj_data, form_id: 'copy' } %} -
- -
-
-

Parents

-
-
{{ 'PLUGIN_FLEX_OBJECTS.STATE.LOADING'|tu }}
-
-
- -
-
- -
-
-

{{ "PLUGIN_ADMIN.MODAL_DELETE_PAGE_CONFIRMATION_REQUIRED_TITLE"|tu }}

-

- {% if context %} - {{ "PLUGIN_ADMIN.PAGE"|tu }}: {{ context.title }} - {% endif %} -

-

- {{ "PLUGIN_ADMIN.MODAL_DELETE_PAGE_CONFIRMATION_REQUIRED_DESC"|tu }} -

-
-
- - {{ "PLUGIN_ADMIN.CONTINUE"|tu }} -
-
-
-{% endblock %} diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/pages/list/list.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/pages/list/list.html.twig deleted file mode 100644 index 12ac6ad..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/pages/list/list.html.twig +++ /dev/null @@ -1,41 +0,0 @@ -{% extends 'flex-objects/types/default/list/list.html.twig' %} - -{% block modals %} -
- {% include 'partials/blueprints-new.html.twig' with { blueprints: admin.blueprints('admin/pages/new'), data: obj_data, form_id: 'new-page' } %} -
- -
- {% include 'partials/blueprints-new-folder.html.twig' with { blueprints: admin.blueprints('admin/pages/new_folder'), data: obj_data, form_id: 'new-folder' } %} -
- -
- {% include 'partials/blueprints-new.html.twig' with { blueprints: admin.blueprints('admin/pages/modular_new'), data: obj_data, form_id: 'new-module' } %} -
- - {% for key, add_modal in config.plugins.admin.add_modals %} -
- {% include add_modal.template|defined('partials/blueprints-new.html.twig') with { - blueprints: admin.blueprints(add_modal.blueprint), - data: obj_data, - form_id: 'add-modal' - }|merge(add_modal.with|defined({})) %} -
- {% endfor %} - -
- {% include 'partials/blueprints-copy.html.twig' with { blueprints: admin.blueprints('admin/pages/copy'), data: obj_data, form_id: 'copy' } %} -
- -
-
-

Parents

-
{{ 'PLUGIN_FLEX_OBJECTS.STATE.LOADING'|tu }}
-
- -
-
-{% endblock %} diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/pages/preview.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/pages/preview.html.twig deleted file mode 100644 index 61499ee..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/pages/preview.html.twig +++ /dev/null @@ -1,16 +0,0 @@ -{% extends 'flex-objects/types/default/preview.html.twig' %} - -{% set can_translate = can_translate ?? (admin.multilang and object.hasFlexFeature('page-translate')) %} - -{% block back_button %} - {% include ['flex-objects/types/' ~ target ~ '/buttons/back.html.twig', 'flex-objects/types/pages/buttons/back.html.twig'] - with { back_url: back_url } %} -{% endblock back_button %} - -{% block body %} - {% set parent = object.parent %} - - {% set preview_url = preview_url ?: (object.home ? '/' : '') %} - - {{ parent() }} -{% endblock body %} diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/user-accounts/configure.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/user-accounts/configure.html.twig deleted file mode 100644 index 2348417..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/user-accounts/configure.html.twig +++ /dev/null @@ -1,9 +0,0 @@ -{% extends 'flex-objects/types/default/configure.html.twig' %} - -{% set back_route = back_route ?? ('/' ~ route.getRoute(1, -1)) %} - -{% block content_top %} - {% include 'flex-objects/layouts/accounts/partials/top.html.twig' %} - - {{ parent() }} -{% endblock %} diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/user-accounts/edit.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/user-accounts/edit.html.twig deleted file mode 100644 index 85fe5fd..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/user-accounts/edit.html.twig +++ /dev/null @@ -1,9 +0,0 @@ -{% extends 'flex-objects/types/default/edit.html.twig' %} - -{% if not directory.isAuthorized('list', 'admin', user) %} - {% set back_route = '/' %} -{% endif %} - -{% if not object.exists %} - {% do object.onPrepareRegistration() %} -{% endif %} \ No newline at end of file diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/user-accounts/list.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/user-accounts/list.html.twig deleted file mode 100644 index 0cefbb8..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/user-accounts/list.html.twig +++ /dev/null @@ -1,7 +0,0 @@ -{% extends 'flex-objects/types/default/list.html.twig' %} - -{% block content_top %} - {% include 'flex-objects/layouts/accounts/partials/top.html.twig' %} - - {{ parent() }} -{% endblock %} diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/user-groups/configure.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/user-groups/configure.html.twig deleted file mode 100644 index 2348417..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/user-groups/configure.html.twig +++ /dev/null @@ -1,9 +0,0 @@ -{% extends 'flex-objects/types/default/configure.html.twig' %} - -{% set back_route = back_route ?? ('/' ~ route.getRoute(1, -1)) %} - -{% block content_top %} - {% include 'flex-objects/layouts/accounts/partials/top.html.twig' %} - - {{ parent() }} -{% endblock %} diff --git a/plugins/flex-objects/admin/templates/flex-objects/types/user-groups/list.html.twig b/plugins/flex-objects/admin/templates/flex-objects/types/user-groups/list.html.twig deleted file mode 100644 index 0cefbb8..0000000 --- a/plugins/flex-objects/admin/templates/flex-objects/types/user-groups/list.html.twig +++ /dev/null @@ -1,7 +0,0 @@ -{% extends 'flex-objects/types/default/list.html.twig' %} - -{% block content_top %} - {% include 'flex-objects/layouts/accounts/partials/top.html.twig' %} - - {{ parent() }} -{% endblock %} diff --git a/plugins/flex-objects/admin/templates/forms/fields/flex-objects/flex-objects.html.twig b/plugins/flex-objects/admin/templates/forms/fields/flex-objects/flex-objects.html.twig deleted file mode 100644 index ea0ad6a..0000000 --- a/plugins/flex-objects/admin/templates/forms/fields/flex-objects/flex-objects.html.twig +++ /dev/null @@ -1,69 +0,0 @@ -{% extends "forms/field.html.twig" %} - -{% macro spanToggle(input, length) %} - {% set space = repeat('  ', (length - input|length) / 2) %} - {{ (space ~ input ~ space)|raw }} -{% endmacro %} - -{% import _self as macro %} - -{% set value = (value is null ? field.default : value) %} - -{% block global_attributes %} - {{ parent() }} - data-grav-field-name="{{ (scope ~ field.name)|fieldName }}" -{% endblock %} - -{% block input %} - {% set flex = grav['flex_objects'] %} - {% set all = flex.blueprints %} - {% if all|count %} - {% set legacy = flex.getLegacyBlueprintMap() %} - {% for label, directory in all %} - {% set url = directory.blueprintFile %} - {% set found = url in value %} - {% if not found and legacy[url] is defined %} - {% set found = legacy[url] in value %} - {% endif %} - -
-
- {% set maxLen = 0 %} - {% for text in ['PLUGIN_ADMIN.ENABLED', 'PLUGIN_ADMIN.DISABLED'] %} - {% set translation = grav.twig.twig.filters['tu'] is defined ? text|tu : text|t %} - {% set maxLen = max(translation|length, maxLen) %} - {% endfor %} - - {% set id = "toggle_" ~ field.name ~ '_' ~ label %} - - - {% set text = 'PLUGIN_ADMIN.ENABLED' %} - {% set translation = (grav.twig.twig.filters['tu'] is defined ? text|tu : text|t)|trim %} - - - {% set text = 'PLUGIN_ADMIN.DISABLED' %} - {% set translation = (grav.twig.twig.filters['tu'] is defined ? text|tu : text|t)|trim %} - -
- {{ directory.title|tu }} -
- {% endfor %} - {% else %} -
{{ 'PLUGIN_FLEX_OBJECTS.ERROR.NO_FLEX_DIRECTORIES'|tu }}
- {% endif %} -{% endblock %} \ No newline at end of file diff --git a/plugins/flex-objects/admin/templates/forms/fields/save-redirect/save-redirect.html.twig b/plugins/flex-objects/admin/templates/forms/fields/save-redirect/save-redirect.html.twig deleted file mode 100644 index 92b90c1..0000000 --- a/plugins/flex-objects/admin/templates/forms/fields/save-redirect/save-redirect.html.twig +++ /dev/null @@ -1,36 +0,0 @@ -{% extends "forms/field.html.twig" %} - -{% set originalValue = value %} -{% set value = (value is null ? field.default : value) %} -{% set isNew = key ? false : true %} -{% set savedOption = grav.session.post_entries_save|default('edit') %} - -{% if isNew %} - {% set options = {'create-new':'PLUGIN_FLEX_OBJECTS.ACTION.CREATE_NEW', 'edit':'PLUGIN_FLEX_OBJECTS.ACTION.EDIT_ITEM', 'list':'PLUGIN_FLEX_OBJECTS.ACTION.LIST_ITEMS'} %} -{% else %} - {% set options = {'edit':'PLUGIN_FLEX_OBJECTS.ACTION.EDIT_ITEM', 'list':'PLUGIN_FLEX_OBJECTS.ACTION.LIST_ITEMS'} %} -{% endif %} - -{% block input %} - {% for key, text in options %} - {% set id = field.id|default(field.name) ~ '-' ~ key %} - - {% if savedOption == key %} - {% set value = savedOption %} - {% endif %} - - - - - - - - {% endfor %} -{% endblock %} \ No newline at end of file diff --git a/plugins/flex-objects/app/columns/finder.js b/plugins/flex-objects/app/columns/finder.js deleted file mode 100644 index ac623b2..0000000 --- a/plugins/flex-objects/app/columns/finder.js +++ /dev/null @@ -1,425 +0,0 @@ -import $ from 'jquery'; -import Finder from '../utils/finder'; -import { getInitialRoute, getStore, setInitialRoute } from './index'; -// import getFilters from '../utils/get-filters'; - -let XHRUUID = 0; -const GRAV_CONFIG = typeof global.GravConfig !== 'undefined' ? global.GravConfig : global.GravAdmin.config; - -export const Instances = {}; - -const isInViewport = (elem) => { - const bounding = elem.getBoundingClientRect(); - const titlebar = document.querySelector('#titlebar'); - const offset = titlebar ? titlebar.getBoundingClientRect().height : 0; - return ( - bounding.top >= offset && - bounding.left >= 0 && - bounding.bottom <= (window.innerHeight || document.documentElement.clientHeight) && - bounding.right <= (window.innerWidth || document.documentElement.clientWidth) - ); -}; - -export class FlexPages { - constructor(container, data) { - this.container = $(container); - this.data = data; - const dataLoad = this.dataLoad; - - this.finder = new Finder( - this.container, - (parent, callback) => { - return dataLoad.call(this, parent, callback); - }, - { - labelKey: 'title', - defaultPath: getInitialRoute(), - itemTrigger: '[data-flexpages-expand]', - createItem: function(item) { - return FlexPages.createItem(this.config, item, this); - }, - createItemContent: function(item) { - return FlexPages.createItemContent(this.config, item, this); - } - } - ); - - this.finder.$emitter.on('leaf-selected', (item) => { - setInitialRoute({ - route: item.route.raw - }); - }); - - this.finder.$emitter.on('interior-selected', (item) => { - setInitialRoute({ - route: item.route.raw - }); - }); - - /* - this.finder.$emitter.on('leaf-selected', (item) => { - console.log('selected', item); - this.finder.emit('create-column', () => this.createSimpleColumn(item)); - }); - - this.finder.$emitter.on('item-selected', (selected) => { - console.log('selected', selected); - // for future use only - create column-card creation for file with details like in macOS finder - // this.finder.$emitter('create-column', () => this.createSimpleColumn(selected)); - }); */ - - this.finder.$emitter.on('column-created', () => { - this.container[0].scrollLeft = this.container[0].scrollWidth - this.container[0].clientWidth; - }); - } - - static createItem(config, item, finder) { - const listItem = $('
  • '); - const listItemClasses = [config.className.item]; - // const href = `${GRAV_CONFIG.current_url}/${item.route.raw}`.replace('//', '/'); - const link = $('
    '); - const createItemContent = config.createItemContent || finder.createItemContent; - const fragment = createItemContent.call(this, item); - link.append(fragment) - // .attr('href', href) - .attr('tabindex', -1); - - if (item.url) { - link.attr('href', item.url); - listItemClasses.push(item.className); - } - - if (item[config.childKey]) { - listItemClasses.push(config.className[config.childKey]); - } - - if (item.filters_hit) { - listItemClasses.push('filters-hit'); - } - - listItem.addClass(listItemClasses.join(' ')); - listItem.append(link) - .attr('data-fjs-item', item[config.itemKey]); - - listItem[0]._item = item; - - return listItem; - } - - static createItemContent(config, item) { - const frag = document.createDocumentFragment(); - const route = `${GRAV_CONFIG.current_url}/${item.route.raw}`.replace('//', '/'); - const title = $('
    '); - const link = $(``); - const icon = $(``); - - if (item.extras && item.extras.lang) { - let status = ''; - if (item.extras.translated) { - status = 'translated'; - } - - if (item.extras.lang === 'n/a') { - status = 'not-available'; - } - - const lang = $(`${item.extras.lang}`); - lang.appendTo(icon); - } - - if (item.extras && item.extras && (item.extras.published_date || item.extras.unpublished_date)) { - const clock = $(''); - clock.appendTo(icon); - } - - const info = $(`${item.title} ${item.route.display}`); - const actions = $(''); - - let dotdotdot = null; - if (item.extras) { - const LANG_URL = $('[data-lang-url]').data('langUrl'); - dotdotdot = $('
    '); - dotdotdot.on('click', (event) => { - if (!dotdotdot.find('.dropdown-menu').length) { - let tags = ''; - let langs = ''; - - item.extras.tags.forEach((tag) => { - tags += `${tag}`; - }); - - const translations = item.extras.langs || {}; - Object.keys(translations).forEach((lang) => { - const translated = translations[lang]; - langs += `
    ${lang ? lang : 'default'}`; - }); - - const canPreview = item.extras.actions.includes('preview') && (!(item.extras.tags.includes('non-routable') || item.extras.tags.includes('unpublished'))); - const canEdit = item.extras.actions.includes('edit'); - const canCopy = item.extras.actions.includes('copy'); - const canMove = false; // item.extras.actions.includes('move'); - const canDelete = item.extras.actions.includes('delete'); - const ul = $(``); - ul.appendTo(dotdotdot); - } - - return true; - }); - } - - if (item.child_count) { - const button = $('